#!/usr/local/bin/python -u import os import sys import subprocess import shutil import time import hashlib # path = "/home/audiobooks/Incoming" path = str(os.environ['AAXPATH']) archivepath = str(os.environ['ARCHIVEPATH']) dpath = str(os.environ['DESTPATH']) errorinprocessing = False def getMD5(fpathaudiofile): with open(fpathaudiofile, "rb") as f: file_hash = hashlib.md5() while chunk := f.read(8192): file_hash.update(chunk) return file_hash.digest() def changebadfilename(fpathaudiofile): # This is used in the case of a zero length file os.rename(fpathaudiofile, str(fpathaudiofile) + ".bad") def waitforupload(fpathaudiofile): # Wait for the file to finish uploading fsize_a = 0 fsizecompare = 0 loopcount = 0 while fsizecompare == 0: fsize_b = os.path.getsize(fpathaudiofile) if fsize_b == 0: loopcount += 1 if loopcount == 24: changebadfilename(fpathaudiofile) return False time.sleep(5) continue if fsize_a == fsize_b: fsizecompare = 1 else: fsize_a = fsize_b time.sleep(1) return True def checkforaudiofile(): # Check the directory for files to process if os.path.isdir(path): files = os.listdir(path) for audio in files: fpath = path + "/" + audio if ((audio.endswith('aax')) and (checkforlock(fpath) is False)): if waitforupload(fpath): return audio else: return "None" def createlockfile(fpath): # create 0byte file with filename.aax.lock lockfile = fpath + ".lock" print(f"{time.asctime()} #Creating Lock file: {lockfile}") try: open(lockfile, "w") except Exception as err: sys.stderr.write("Couldn't create lock file: {}\n".format(err)) errorinprocessing = True def cpfiletoprocessing(fpath, audio): # Copy the file to the processing location print("Copying the file to processing " + audio) try: shutil.copy(fpath, "/processing/") except Exception as err: sys.stderr.write("Couldn't copy the file to processing: {}\n" .format(err) ) errorinprocessing = True def processfile(audio): # process the file. Convert from aax to mp3 back on the NAS print(f"{time.asctime()} #Processing {audio}") command = "./aaxConvert.py -v -d {} /processing/{}\n".format(dpath, audio) subprocess.run(command, shell=True) def copyToArchive(fpath, audio): # move aax to archive filesystem archive = archivepath + "/" + audio try: shutil.copy(fpath, archive) except Exception as err: sys.stderr.write( f"{time.asctime()} #Couldn't copy file to the archive: {err}\n" ) errorinprocessing = True def cleanup(fpath, audio): # cleanup after yourself # print"clean up debug: {}".format(fpath) # TODO verify md5 hash of archive and original before delete archive = archivepath + "/" + audio orginial_hash = getMD5(fpath) archive_file = getMD5(archive) if orginial_hash == archive_file: try: lockfile = fpath + ".lock" print("Removing lock file: " + lockfile) os.remove(lockfile) os.remove(fpath) os.remove('/processing/' + audio) except Exception as err: sys.stderr.write( f"{time.asctime()} Couldn't clean up after myself to the archive: {err}\n" # noqa E501 ) errorinprocessing = True else: print("Checksum's do not match for fpath. I am not cleaning up") def checkforlock(fpathaudiofile): # Need to check for .lock file in this function. lockfile = fpathaudiofile + ".lock" if os.path.exists(lockfile): return True else: return False def loopforever(): # main loop for running the app while True: # print("Looking for files in {}\n").format(path) audio = str(checkforaudiofile()) if audio != "None": fpath = path + '/' + audio print(f"Debug: {fpath}") print(f"{time.asctime()} #Processing file: {audio}\n") try: createlockfile(fpath) cpfiletoprocessing(fpath, audio) # copy file processfile(audio) # process file # Copy file from Incoming to archive copyToArchive(fpath, audio) cleanup(fpath, audio) # Clean up the processing dir if errorinprocessing is True: # noqa F823 print(f"{time.asctime()}There is a error with {audio}\n") except Exception: continue time.sleep(15) errorinprocessing = False if __name__ == "__main__": loopforever()