diff --git a/TorrentToMedia.py b/TorrentToMedia.py index b6decbad..c5d03c2a 100755 --- a/TorrentToMedia.py +++ b/TorrentToMedia.py @@ -28,11 +28,11 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, extracted_folder = [] copy_list = [] - logger.debug("Received Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory) + logger.debug("Received Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory)) inputDirectory, inputName, inputCategory, root, single = category_search(inputDirectory, inputName, inputCategory, root, nzbtomedia.CATEGORIES) # Confirm the category by parsing directory structure - logger.debug("Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory) + logger.debug("Determined Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory)) TorrentClass = None if clientAgent != 'manual': @@ -44,7 +44,7 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if inputCategory == "": inputCategory = "UNCAT" outputDestination = os.path.normpath(os.path.join(nzbtomedia.OUTPUTDIRECTORY, inputCategory, safeName(inputName))) - logger.postprocess("Output directory set to: %s", outputDestination) + logger.postprocess("Output directory set to: %s" % (outputDestination)) if nzbtomedia.CFG["SickBeard"][inputCategory]: Torrent_NoLink = int(nzbtomedia.CFG["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0 @@ -67,10 +67,10 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, processOnly.extend(nzbtomedia.USER_SCRIPT_CATEGORIES) # Adds all categories to be processed by userscript. if not inputCategory in processOnly: - logger.postprocess("No processing to be done for category: %s. Exiting", inputCategory) + logger.postprocess("No processing to be done for category: %s. Exiting" % (inputCategory)) return - logger.debug("Scanning files in directory: %s", inputDirectory) + logger.debug("Scanning files in directory: %s" % (inputDirectory)) if nzbtomedia.CFG["HeadPhones"][inputCategory]: nzbtomedia.NOFLATTEN.extend(nzbtomedia.CFG["HeadPhones"].sections) # Make sure we preserve folder structure for HeadPhones. @@ -82,7 +82,7 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if single: dirnames[:] = [] filenames[:] = [filenames] # we just want to work with this one file if single = True - logger.debug("Found %s files in %s", str(len(filenames)), dirpath) + logger.debug("Found %s files in %s" % (str(len(filenames)), dirpath)) for file in filenames: filePath = os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) @@ -92,17 +92,17 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if len(newDir) > 0 and newDir[0] == "/": newDir = newDir[1:] # remove leading "/" to enable join to work. outputDestination = os.path.join(outputDestinationMaster, newDir) # join this extra directory to output. - logger.debug("Setting outputDestination to %s to preserve folder structure", outputDestination) + logger.debug("Setting outputDestination to %s to preserve folder structure" % (outputDestination)) targetDirectory = os.path.join(outputDestination, file) if root == 1: if foundFile == int(0): - logger.debug("Looking for %s in: %s", inputName, file) + logger.debug("Looking for %s in: %s" % (inputName, file)) if (safeName(inputName) in safeName(file)) or (safeName(fileName) in safeName(inputName)): #pass # This file does match the Torrent name foundFile = 1 - logger.debug("Found file %s that matches Torrent Name %s", file, inputName) + logger.debug("Found file %s that matches Torrent Name %s" % (file, inputName)) else: continue # This file does not match the Torrent name, skip it @@ -114,13 +114,13 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): #pass # This file does match the date time criteria foundFile = 1 - logger.debug("Found file %s with date modifed/created less than 5 minutes ago.", file) + logger.debug("Found file %s with date modifed/created less than 5 minutes ago." % (file)) else: continue # This file has not been recently moved or created, skip it if fileExtension in nzbtomedia.MEDIACONTAINER and is_sample(filePath, inputName, nzbtomedia.MINSAMPLESIZE, nzbtomedia.SAMPLEIDS) and not nzbtomedia.CFG["HeadPhones"][inputCategory]: # Ignore samples - logger.postprocess("Ignoring sample file: %s ", filePath) + logger.postprocess("Ignoring sample file: %s " % (filePath)) continue if fileExtension in nzbtomedia.COMPRESSEDCONTAINER: @@ -129,24 +129,24 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if re.search(r'\d+', os.path.splitext(fileName)[1]) and os.path.dirname(filePath) in extracted_folder and not any(item in os.path.splitext(fileName)[1] for item in ['.720p','.1080p','.x264']): part = int(re.search(r'\d+', os.path.splitext(fileName)[1]).group()) if part == 1: # we only want to extract the primary part. - logger.debug("Found primary part of a multi-part archive %s. Extracting", file) + logger.debug("Found primary part of a multi-part archive %s. Extracting" % (file)) else: - logger.debug("Found part %s of a multi-part archive %s. Ignoring", part, file) + logger.debug("Found part %s of a multi-part archive %s. Ignoring" % (part, file)) continue - logger.postprocess("Found compressed archive %s for file %s", fileExtension, filePath) + logger.postprocess("Found compressed archive %s for file %s" % (fileExtension, filePath)) try: extractor.extract(filePath, outputDestination) extractionSuccess = True # we use this variable to determine if we need to pause a torrent or not in uTorrent (don't need to pause archived content) extracted_folder.append(os.path.dirname(filePath)) except: - logger.error("Extraction failed for: %s", file) + logger.error("Extraction failed for: %s" % (file)) continue try: copy_link(filePath, targetDirectory, nzbtomedia.USELINK, outputDestination) copy_list.append([filePath, os.path.join(outputDestination, file)]) except: - logger.error("Failed to link file: %s", file) + logger.error("Failed to link file: %s" % (file)) outputDestination = outputDestinationMaster # Reset here. if not inputCategory in nzbtomedia.NOFLATTEN: #don't flatten hp in case multi cd albums, and we need to copy this back later. @@ -162,21 +162,21 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, filePath = os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file - logger.debug("Found media file: %s", filePath) + logger.debug("Found media file: %s" % (filePath)) video += 1 if fileExtension in nzbtomedia.COMPRESSEDCONTAINER: # If the file is an archive file archive += 1 if video > int(0): # Check that media files exist - logger.debug("Found %s media files", str(video)) + logger.debug("Found %s media files" % (str(video))) status = int(0) elif not (nzbtomedia.CFG["SickBeard"][inputCategory] and nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination") and archive > int(0): - logger.debug("Found %s archive files to be extracted by SickBeard", str(archive)) + logger.debug("Found %s archive files to be extracted by SickBeard" % (str(archive))) status = int(0) else: logger.warning("Found no media files in output.") if (inputCategory in nzbtomedia.USER_SCRIPT_CATEGORIES and not "NONE" in nzbtomedia.USER_SCRIPT_CATEGORIES) or ("ALL" in nzbtomedia.USER_SCRIPT_CATEGORIES and not inputCategory in processCategories): - logger.postprocess("Processing user script %s.", nzbtomedia.USER_SCRIPT) + logger.postprocess("Processing user script %s." % (nzbtomedia.USER_SCRIPT)) result = external_script(outputDestination,inputName,inputCategory) elif status == int(0) or (nzbtomedia.CFG['HeadPhones','Mylar','Gamez'][inputCategory]): # if movies linked/extracted or for other categories. logger.debug("Calling autoProcess script for successful download.") @@ -187,23 +187,23 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, result = 0 if nzbtomedia.CFG['CouchPotato'][inputCategory]: - logger.postprocess("Calling CouchPotato:" + inputCategory + " to post-process: %s", inputName) + logger.postprocess("Calling CouchPotato:" + inputCategory + " to post-process: %s" % (inputName)) download_id = inputHash result = autoProcessMovie().process(outputDestination, inputName, status, clientAgent, download_id, inputCategory) elif nzbtomedia.CFG['SickBeard'][inputCategory]: - logger.postprocess("Calling Sick-Beard:" + inputCategory + " to post-process: %s", inputName) + logger.postprocess("Calling Sick-Beard:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['NzbDrone'][inputCategory]: - logger.postprocess("Calling NzbDrone:" + inputCategory + " to post-process: %s", inputName) + logger.postprocess("Calling NzbDrone:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['HeadPhones'][inputCategory]: - logger.postprocess("Calling HeadPhones:" + inputCategory + " to post-process: %s", inputName) + logger.postprocess("Calling HeadPhones:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessMusic().process(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['Mylar'][inputCategory]: - logger.postprocess("Calling Mylar:" + inputCategory + " to post-process: %s", inputName) + logger.postprocess("Calling Mylar:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessComics().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['Gamez'][inputCategory]: - logger.postprocess("Calling Gamez:" + inputCategory + " to post-process: %s", inputName) + logger.postprocess("Calling Gamez:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessGames().process(outputDestination, inputName, status, clientAgent, inputCategory) if result == 1 and clientAgent != 'manual': @@ -255,19 +255,19 @@ def external_script(outputDestination, torrentName, torrentLabel): cmd = "" for item in command: cmd = cmd + " " + item - logger.postprocess("Running script %s on file %s.", cmd, filePath) + logger.postprocess("Running script %s on file %s." % (cmd, filePath)) try: p = Popen(command) res = p.wait() if str(res) in nzbtomedia.USER_SCRIPT_SUCCESSCODES: # Linux returns 0 for successful. - logger.postprocess("UserScript %s was successfull", command[0]) + logger.postprocess("UserScript %s was successfull" % (command[0])) result = int(0) else: - logger.error("UserScript %s has failed with return code: %s", command[0], res) - logger.postprocess("If the UserScript completed successfully you should add %s to the user_script_successCodes", res) + logger.error("UserScript %s has failed with return code: %s" % (command[0], res)) + logger.postprocess("If the UserScript completed successfully you should add %s to the user_script_successCodes" % (res)) result = int(1) except: - logger.error("UserScript %s has failed", command[0]) + logger.error("UserScript %s has failed" % (command[0])) result = int(1) final_result = final_result + result @@ -282,10 +282,10 @@ def external_script(outputDestination, torrentName, torrentLabel): num_files_new = num_files_new + 1 if nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new == int(0) and final_result == int(0): - logger.postprocess("All files have been processed. Cleaning outputDirectory %s", outputDestination) + logger.postprocess("All files have been processed. Cleaning outputDirectory %s" % (outputDestination)) shutil.rmtree(outputDestination) elif nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new != int(0): - logger.postprocess("%s files were processed, but %s still remain. outputDirectory will not be cleaned.", num_files, num_files_new) + logger.postprocess("%s files were processed, but %s still remain. outputDirectory will not be cleaned." % (num_files, num_files_new)) return final_result def main(args): @@ -296,11 +296,11 @@ def main(args): clientAgent = nzbtomedia.TORRENT_CLIENTAGENT logger.postprocess("#########################################################") - logger.postprocess("## ..::[%s]::.. CLIENT:%s ## STARTING", args[0], clientAgent) + logger.postprocess("## ..::[%s]::.. CLIENT:%s ## STARTING" % (args[0], clientAgent)) logger.postprocess("#########################################################") # debug command line options - logger.debug("Options passed into TorrentToMedia: %s", args) + logger.debug("Options passed into TorrentToMedia: %s" % (args)) # Post-Processing Result result = 0 @@ -325,18 +325,18 @@ def main(args): if nzbtomedia.CFG[section][category].isenabled(): dirNames = get_dirnames(section, category) for dirName in dirNames: - logger.postprocess("Running %s:%s as a manual run for folder %s ...", section, category, dirName) + logger.postprocess("Running %s:%s as a manual run for folder %s ..." % (section, category, dirName)) results = processTorrent(dirName, os.path.basename(dirName), category, inputHash, inputID, clientAgent) if results != 0: result = results - logger.error("A problem was reported when trying to manually run %s:%s.", section, category) + logger.error("A problem was reported when trying to manually run %s:%s." % (section, category)) else: - logger.warning("%s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) + logger.warning("%s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ..." % (section, category)) if result == 0: - logger.postprocess("The %s script completed successfully.", args[0]) + logger.postprocess("The %s script completed successfully." % (args[0])) else: - logger.error("A problem was reported in the %s script.", args[0]) + logger.error("A problem was reported in the %s script." % (args[0])) sys.exit(result) diff --git a/autoProcessMedia.cfg.spec b/autoProcessMedia.cfg.spec index eb15427e..32f22051 100644 --- a/autoProcessMedia.cfg.spec +++ b/autoProcessMedia.cfg.spec @@ -8,7 +8,8 @@ git_user = git_branch = force_clean = 0 - + log_debug = 0 + [CouchPotato] #### autoProcessing for Movies #### movie - category that gets called for post-processing with CPS diff --git a/nzbToMedia.py b/nzbToMedia.py index dbe34c2c..68b19981 100755 --- a/nzbToMedia.py +++ b/nzbToMedia.py @@ -286,27 +286,25 @@ from nzbtomedia import logger # post-processing def process(nzbDir, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None): + result = 0 + # auto-detect section section = nzbtomedia.CFG.findsection(inputCategory) + if section: + logger.info("Sending %s to %s for post-processing ..." % (inputName, str(section).upper())) + else: + logger.error("We could not find a section with containing a download category labeled %s in your autoProcessMedia.cfg, Exiting!" % inputCategory) if nzbtomedia.CFG["CouchPotato"][inputCategory]: - logger.postprocess("Calling CouchPotatoServer to post-process: %s", inputName) result = autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory) elif nzbtomedia.CFG["SickBeard", "NzbDrone"][inputCategory]: - logger.postprocess("Calling Sick-Beard to post-process: %s", inputName) result = autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["HeadPhones"][inputCategory]: - logger.postprocess("Calling HeadPhones to post-process: %s", inputName) result = autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["Mylar"][inputCategory]: - logger.postprocess("Calling Mylar to post-process: %s", inputName) result = autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["Gamez"][inputCategory]: - logger.postprocess("Calling Gamez to post-process: %s", inputName) result = autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory) - else: - logger.postprocess("We could not find a section with the download category of %s in your autoProcessMedia.cfg. Exiting.", inputCategory) - result = -1 if result == 0: # Clean up any leftover files @@ -321,22 +319,21 @@ def main(args, section=None): # clientAgent for NZBs clientAgent = nzbtomedia.NZB_CLIENTAGENT - logger.postprocess("#########################################################") - logger.postprocess("## ..::[%s]::.. CLIENT:%s ## STARTING", args[0], clientAgent) - logger.postprocess("#########################################################") + logger.info("#########################################################") + logger.info("## ..::[%s]::.. ##" % os.path.basename(__file__)) + logger.info("#########################################################") # debug command line options - logger.debug("Options passed into nzbToMedia: %s", args) + logger.debug("Options passed into nzbToMedia: %s" % args) # Post-Processing Result result = 0 status = 0 - # NZBGet V11+ # Check if the script is called from nzbget 11.0 or later if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5] < '11.0': - logger.postprocess("Script triggered from NZBGet (11.0 or later).") + logger.info("Script triggered from NZBGet (11.0 or later).") if os.environ['NZBOP_UNPACK'] != 'yes': logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting") @@ -345,7 +342,7 @@ def main(args, section=None): # Check par status if os.environ['NZBPP_PARSTATUS'] == '3': logger.warning("Par-check successful, but Par-repair disabled, exiting") - logger.postprocess("Please check your Par-repair settings for future downloads.") + logger.info("Please check your Par-repair settings for future downloads.") sys.exit(nzbtomedia.NZBGET_POSTPROCESS_NONE) if os.environ['NZBPP_PARSTATUS'] == '1' or os.environ['NZBPP_PARSTATUS'] == '4': @@ -362,16 +359,16 @@ def main(args, section=None): if os.environ['NZBPP_HEALTH'] < 1000: logger.warning("Download health is compromised and Par-check/repair disabled or no .par2 files found. Setting status \"failed\"") - logger.postprocess("Please check your Par-check/repair settings for future downloads.") + logger.info("Please check your Par-check/repair settings for future downloads.") status = 1 else: - logger.postprocess("Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") - logger.postprocess("Please check your Par-check/repair settings for future downloads.") + logger.info("Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") + logger.info("Please check your Par-check/repair settings for future downloads.") # Check if destination directory exists (important for reprocessing of history items) if not os.path.isdir(os.environ['NZBPP_DIRECTORY']): - logger.error("Nothing to post-process: destination directory %s doesn't exist. Setting status \"failed\"", os.environ['NZBPP_DIRECTORY']) + logger.error("Nothing to post-process: destination directory %s doesn't exist. Setting status failed" % (os.environ['NZBPP_DIRECTORY'])) status = 1 # Check for download_id to pass to CouchPotato @@ -393,7 +390,7 @@ def main(args, section=None): # 6 Group that the NZB was posted in e.g. alt.binaries.x # 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2 clientAgent = 'sabnzbd' - logger.postprocess("Script triggered from SABnzbd") + logger.info("Script triggered from SABnzbd") result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent, download_id='') # SABnzbd 0.7.17+ elif len(args) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS: @@ -407,7 +404,7 @@ def main(args, section=None): # 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2 # 8 Failure URL clientAgent = 'sabnzbd' - logger.postprocess("Script triggered from SABnzbd 0.7.17+") + logger.info("Script triggered from SABnzbd 0.7.17+") result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent, download_id='') else: # Perform Manual Run @@ -420,21 +417,20 @@ def main(args, section=None): if nzbtomedia.CFG[section][category].isenabled(): dirNames = get_dirnames(section, category) for dirName in dirNames: - logger.postprocess("nzbToMedia running %s:%s as a manual run on folder %s ...", section, category, dirName) + logger.info("Starting manual run for %s:%s - Folder:%s" % (section, category, dirName)) results = process(dirName, os.path.basename(dirName), 0, clientAgent=clientAgent, inputCategory=category) if results != 0: - logger.error("A problem was reported when trying to manually run %s:%s.", section, category) + logger.error("A problem was reported when trying to perform a manual run for %s:%s." % (section, category)) result = results - else: - logger.postprocess("nzbToMedia %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) + logger.debug("nzbToMedia %s:%s is DISABLED" % (section, category)) if result == 0: - logger.postprocess("The %s script completed successfully.", args[0]) + logger.info("The %s script completed successfully." % args[0]) if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11 sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS) else: - logger.error("A problem was reported in the %s script.", args[0]) + logger.error("A problem was reported in the %s script." % args[0]) if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11 sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR) diff --git a/nzbtomedia/Transcoder.py b/nzbtomedia/Transcoder.py index b8fe8949..aa43cb82 100644 --- a/nzbtomedia/Transcoder.py +++ b/nzbtomedia/Transcoder.py @@ -11,15 +11,15 @@ class Transcoder: ffmpeg = os.path.join(os.path.dirname(sys.argv[0]), 'ffmpeg\\bin\\ffmpeg.exe') # note, will need to package in this dir. useNiceness = False if not os.path.isfile(ffmpeg): # problem - logger.error("ffmpeg not found. ffmpeg needs to be located at: %s", ffmpeg) - logger.info("Cannot transcode files in folder %s", dirName) + logger.error("ffmpeg not found. ffmpeg needs to be located at: %s" % (ffmpeg)) + logger.info("Cannot transcode files in folder %s" % (dirName)) return 1 # failure else: if call(['which', 'ffmpeg']) != 0: res = call([os.path.join(os.path.dirname(sys.argv[0]),'getffmpeg.sh')]) if res or call(['which', 'ffmpeg']) != 0: # did not install or ffmpeg still not found. logger.error("Failed to install ffmpeg. Please install manually") - logger.info("Cannot transcode files in folder %s", dirName) + logger.info("Cannot transcode files in folder %s" % (dirName)) return 1 # failure else: ffmpeg = 'ffmpeg' @@ -41,7 +41,7 @@ class Transcoder: name, ext = os.path.splitext(filePath) if ext in nzbtomedia.MEDIACONTAINER: # If the file is a video file if ext in nzbtomedia.IGNOREEXTENSIONS: - logger.info("No need to transcode video type %s", ext) + logger.info("No need to transcode video type %s" % (ext)) continue if ext == outputVideoExtension: # we need to change the name to prevent overwriting itself. outputVideoExtension = '-transcoded' + outputVideoExtension # adds '-transcoded.ext' @@ -96,26 +96,26 @@ class Transcoder: os.remove(newfilePath) except OSError, e: if e.errno != errno.ENOENT: # Ignore the error if it's just telling us that the file doesn't exist - logger.debug("Error when removing transcoding target: %s", e) + logger.debug("Error when removing transcoding target: %s" % (e)) except Exception, e: - logger.debug("Error when removing transcoding target: %s", e) + logger.debug("Error when removing transcoding target: %s" % (e)) - logger.info("Transcoding video: %s", file) + logger.info("Transcoding video: %s" % (file)) cmd = "" for item in command: cmd = cmd + " " + item - logger.debug("calling command:%s", cmd) + logger.debug("calling command:%s" % (cmd)) result = 1 # set result to failed in case call fails. try: result = call(command) except: - logger.error("Transcoding of video %s has failed", filePath) + logger.error("Transcoding of video %s has failed" % (filePath)) if result == 0: - logger.info("Transcoding of video %s to %s succeeded", filePath, newfilePath) + logger.info("Transcoding of video %s to %s succeeded" % (filePath, newfilePath)) if nzbtomedia.DUPLICATE == 0: # we get rid of the original file os.unlink(filePath) else: - logger.error("Transcoding of video %s to %s failed", filePath, newfilePath) + logger.error("Transcoding of video %s to %s failed" % (filePath, newfilePath)) # this will be 0 (successful) it all are successful, else will return a positive integer for failure. final_result = final_result + result return final_result diff --git a/nzbtomedia/__init__.py b/nzbtomedia/__init__.py index 2768d34d..3f7a2924 100644 --- a/nzbtomedia/__init__.py +++ b/nzbtomedia/__init__.py @@ -31,15 +31,16 @@ NZBGET_POSTPROCESS_NONE = 95 # config constants CFG = None CFG_LOGGING = None -APP_FILENAME = '' -APP_NAME = '' -PROGRAM_DIR = '' -LOG_DIR = '' -LOG_FILE = '' -CONFIG_FILE = '' -CONFIG_SPEC_FILE = '' -CONFIG_MOVIE_FILE = '' -CONFIG_TV_FILE = '' +APP_FILENAME = None +APP_NAME = None +PROGRAM_DIR = None +LOG_DIR = None +LOG_FILE = None +LOG_DEBUG = None +CONFIG_FILE = None +CONFIG_SPEC_FILE = None +CONFIG_MOVIE_FILE = None +CONFIG_TV_FILE = None SYS_ENCODING = None SYS_ARGV = None @@ -129,14 +130,11 @@ def initialize(section=None): TRANSCODE, GIT_PATH, GIT_USER, GIT_BRANCH, GIT_REPO, SYS_ENCODING, NZB_CLIENTAGENT, SABNZBDHOST, SABNZBDPORT, SABNZBDAPIKEY, \ DUPLICATE, IGNOREEXTENSIONS, OUTPUTVIDEOEXTENSION, OUTPUTVIDEOCODEC, OUTPUTVIDEOPRESET, OUTPUTVIDEOFRAMERATE, \ OUTPUTVIDEOBITRATE, OUTPUTAUDIOCODEC, OUTPUTAUDIOBITRATE, OUTPUTSUBTITLECODEC, OUTPUTFASTSTART, OUTPUTQUALITYPERCENT, \ - NICENESS, MEDIAEXTENSIONS + NICENESS, MEDIAEXTENSIONS, LOG_DEBUG if __INITIALIZED__: return False - # add our custom libs to the system path - sys.path.insert(0, os.path.abspath(os.path.join(PROGRAM_DIR, 'lib'))) - # init preliminaries SYS_ARGV = sys.argv[1:] APP_FILENAME = sys.argv[0] @@ -144,10 +142,13 @@ def initialize(section=None): PROGRAM_DIR = os.path.dirname(os.path.normpath(os.path.abspath(os.path.join(__file__, os.pardir)))) LOG_DIR = os.path.join(PROGRAM_DIR, 'logs') LOG_FILE = os.path.join(LOG_DIR, 'postprocess.log') - CONFIG_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg") - CONFIG_SPEC_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg.spec") - CONFIG_MOVIE_FILE = os.path.join(PROGRAM_DIR, "autoProcessMovie.cfg") - CONFIG_TV_FILE = os.path.join(PROGRAM_DIR, "autoProcessTv.cfg") + CONFIG_FILE = os.path.join(PROGRAM_DIR, 'autoProcessMedia.cfg') + CONFIG_SPEC_FILE = os.path.join(PROGRAM_DIR, 'autoProcessMedia.cfg.spec') + CONFIG_MOVIE_FILE = os.path.join(PROGRAM_DIR, 'autoProcessMovie.cfg') + CONFIG_TV_FILE = os.path.join(PROGRAM_DIR, 'autoProcessTv.cfg') + + # add our custom libs to the system path + sys.path.insert(0, os.path.abspath(os.path.join(PROGRAM_DIR, 'lib'))) try: locale.setlocale(locale.LC_ALL, "") @@ -179,19 +180,22 @@ def initialize(section=None): # run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. if not config.migrate(): - logger.error("Unable to migrate config file %s, exiting ...", CONFIG_FILE) + logger.error("Unable to migrate config file %s, exiting ..." % (CONFIG_FILE)) sys.exit(-1) # run migrate to convert NzbGet data from old cfg style to new cfg style if os.environ.has_key('NZBOP_SCRIPTDIR'): if not config.addnzbget(): - logger.error("Unable to migrate NzbGet config file %s, exiting ...", CONFIG_FILE) + logger.error("Unable to migrate NzbGet config file %s, exiting ..." % (CONFIG_FILE)) sys.exit(-1) # load newly migrated config - logger.info("Loading config from %s", CONFIG_FILE) + logger.info("Loading config from %s" % CONFIG_FILE) CFG = config() + # Enable/Disable DEBUG Logging + LOG_DEBUG = int(CFG['General']['log_debug']) + # Set Version and GIT variables NZBTOMEDIA_VERSION = '9.3' VERSION_NOTIFY = int(CFG['General']['version_notify']) diff --git a/nzbtomedia/autoProcess/autoProcessComics.py b/nzbtomedia/autoProcess/autoProcessComics.py index 1a7cbe04..52685afa 100644 --- a/nzbtomedia/autoProcess/autoProcessComics.py +++ b/nzbtomedia/autoProcess/autoProcessComics.py @@ -7,21 +7,13 @@ from nzbtomedia import logger class autoProcessComics: def processEpisode(self, dirName, nzbName=None, status=0, clientAgent='manual', inputCategory=None): - if dirName is None: - logger.error("No directory was given!") - return 1 # failure - # auto-detect correct section section = nzbtomedia.CFG.findsection(inputCategory) if not section: logger.error( - "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) + "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory) return 1 - logger.postprocess("#########################################################") - logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory) - logger.postprocess("#########################################################") - host = nzbtomedia.CFG[section][inputCategory]["host"] port = nzbtomedia.CFG[section][inputCategory]["port"] username = nzbtomedia.CFG[section][inputCategory]["username"] @@ -59,16 +51,16 @@ class autoProcessComics: protocol = "http://" url = "%s%s:%s%s/post_process" % (protocol, host, port, web_root) - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % (url), section) try: r = requests.get(url, params=params, auth=(username, password), stream=True) except requests.ConnectionError: - logger.error("Unable to open URL") + logger.error("Unable to open URL", section) return 1 # failure for line in r.iter_lines(): - if line: logger.postprocess("%s", line) + if line: logger.postprocess("%s" % (line), section) time.sleep(60) #wait 1 minute for now... need to see just what gets logged and how long it takes to process return 0 # Success diff --git a/nzbtomedia/autoProcess/autoProcessGames.py b/nzbtomedia/autoProcess/autoProcessGames.py index 4edbd7cd..bcc21f31 100644 --- a/nzbtomedia/autoProcess/autoProcessGames.py +++ b/nzbtomedia/autoProcess/autoProcessGames.py @@ -13,13 +13,9 @@ class autoProcessGames: section = nzbtomedia.CFG.findsection(inputCategory) if not section: logger.error( - "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) + "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory) return 1 - logger.postprocess("#########################################################") - logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory) - logger.postprocess("#########################################################") - status = int(status) host = nzbtomedia.CFG[section][inputCategory]["host"] @@ -59,7 +55,7 @@ class autoProcessGames: params['db_id'] = gamezID params['status'] = downloadStatus - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % (url),section) try: r = requests.get(url, params=params) @@ -68,11 +64,11 @@ class autoProcessGames: return 1 # failure result = r.json() - logger.postprocess("%s", result) + logger.postprocess("%s" % (result),section) if result['success']: - logger.postprocess("Status for %s has been set to %s in Gamez", gamezID, downloadStatus) + logger.postprocess("SUCCESS: Status for %s has been set to %s in Gamez" % (gamezID, downloadStatus),section) return 0 # Success else: - logger.error("Status for %s has NOT been updated in Gamez", gamezID) + logger.error("FAILED: Status for %s has NOT been updated in Gamez" % (gamezID),section) return 1 # failure diff --git a/nzbtomedia/autoProcess/autoProcessMovie.py b/nzbtomedia/autoProcess/autoProcessMovie.py index 51811d45..c77f593b 100644 --- a/nzbtomedia/autoProcess/autoProcessMovie.py +++ b/nzbtomedia/autoProcess/autoProcessMovie.py @@ -1,102 +1,62 @@ import os -import re import time import nzbtomedia from lib import requests from nzbtomedia.Transcoder import Transcoder from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions -from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, create_torrent_class, clean_nzbname +from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, find_imdbid, find_download from nzbtomedia import logger class autoProcessMovie: - def find_imdbid(self, dirName, nzbName): - imdbid = None - - nzbName = clean_nzbname(nzbName) - - # find imdbid in dirName - m = re.search('(tt\d{7})', dirName) - if m: - imdbid = m.group(1) - logger.postprocess("Found movie id %s in directory", imdbid) - return imdbid - - # find imdbid in nzbName - m = re.search('(tt\d{7})', nzbName) - if m: - imdbid = m.group(1) - logger.postprocess("Found imdbid %s in name", imdbid) - return imdbid - - m = re.search("^(.+)\W(\d{4})", os.path.basename(dirName)) - if m: - title = m.group(1) - year = m.group(2) - - url = "http://www.omdbapi.com" - - logger.debug("Opening URL: %s", url) - - try: - r = requests.get(url, params={'y':year, 't':title}) - except requests.ConnectionError: - logger.error("Unable to open URL") - return - - results = r.json() - - try: - imdbid = results['imdbID'] - except:pass - - if imdbid: - return imdbid - - def get_releases(self, baseURL, download_id, dirName, nzbName): - releases = {} + def get_releases(self, baseURL, imdbid=None, download_id=None): + results = {} params = {} - imdbid = self.find_imdbid(dirName, nzbName) - # determin cmd and params to send to CouchPotato to get our results section = 'movies' cmd = "/media.list" - params['status'] = 'active,done' if imdbid: section = 'media' cmd = "/media.get" params['id'] = imdbid - if download_id: - params['release_status'] = 'snatched,downloaded' url = baseURL + cmd - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % url) try: r = requests.get(url, params=params) except requests.ConnectionError: - logger.error("Unable to open URL") + logger.error("Unable to open URL %s" % url) return - results = r.json() - movies = results[section] + result = r.json() + movies = result[section] if not isinstance(movies, list): movies = [movies] for movie in movies: + if movie['status'] not in ['active','done']: + continue releases = movie['releases'] - if not isinstance(releases, list): - releases = [releases] for release in releases: + if release['status'] not in ['snatched','downloaded']: + continue try: if download_id: if download_id != release['download_info']['id']: continue id = release['_id'] - releases[id] = release + results[id] = release except:continue - return releases + # Search downloads on clients for a match to try and narrow our results down to 1 + for id, x in results.items(): + try: + if not find_download(str(x['download_info']['downloader']).lower(),x['download_info']['id']): + results.pop(id) + except:continue + + return results def releases_diff(self, dict_a, dict_b): return dict([ @@ -109,21 +69,13 @@ class autoProcessMovie: ]) def process(self, dirName, nzbName=None, status=0, clientAgent = "manual", download_id = "", inputCategory=None): - if dirName is None: - logger.error("No directory was given!") - return 1 # failure - # auto-detect correct section section = nzbtomedia.CFG.findsection(inputCategory) if not section: logger.error( - "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) + "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory) return 1 - logger.postprocess("#########################################################") - logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory) - logger.postprocess("#########################################################") - status = int(status) host = nzbtomedia.CFG[section][inputCategory]["host"] @@ -141,17 +93,11 @@ class autoProcessMovie: web_root = nzbtomedia.CFG[section][inputCategory]["web_root"] except: web_root = "" - try: - transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"]) - except: - transcode = 0 try: remote_path = nzbtomedia.CFG[section][inputCategory]["remote_path"] except: remote_path = None - nzbName = str(nzbName) # make sure it is a string - if ssl: protocol = "https://" else: @@ -159,10 +105,11 @@ class autoProcessMovie: baseURL = "%s%s:%s%s/api/%s" % (protocol, host, port, web_root, apikey) - releases = self.get_releases(baseURL, download_id, dirName, nzbName) + imdbid = find_imdbid(dirName,nzbName) + releases = self.get_releases(baseURL, imdbid, download_id) if not releases: - logger.error("Could not find any releases marked as WANTED on CouchPotato to compare changes against %s, skipping ...", nzbName) + logger.error("Could not find any releases marked as WANTED matching %s, skipping ..." % nzbName, section) return 1 # try to get release_id, media_id, and download_id if one was not passed in @@ -172,19 +119,19 @@ class autoProcessMovie: try: release_id = releases.keys()[0] media_id = releases[release_id]['media_id'] - download_id = releases['download_info']['id'] + download_id = releases[release_id]['download_info']['id'] except:pass process_all_exceptions(nzbName.lower(), dirName) nzbName, dirName = convert_to_ascii(nzbName, dirName) if status == 0: - if transcode == 1: + if nzbtomedia.TRANSCODE == 1: result = Transcoder().Transcode_directory(dirName) if result == 0: - logger.debug("Transcoding succeeded for files in %s", dirName) + logger.debug("Transcoding succeeded for files in %s" % (dirName),section) else: - logger.warning("Transcoding failed for files in %s", dirName) + logger.warning("Transcoding failed for files in %s" % (dirName),section) if method == "manage": command = "/manage.update" @@ -201,86 +148,88 @@ class autoProcessMovie: dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/") params['media_folder'] = dirName_new - url = baseURL + command + url = "%s%s" % (baseURL, command) - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % (url), section) - logger.postprocess("Attempting to perform a %s scan on CouchPotato for %s", method, nzbName) + logger.postprocess("Attempting to perform a %s scan for %s" % (method, nzbName), section) try: r = requests.get(url, params=params) except requests.ConnectionError: - logger.error("Unable to open URL") + logger.error("Unable to open URL", section) return 1 # failure result = r.json() if result['success']: - logger.postprocess("SUCCESS: %s scan started on CouchPotatoServer for %s", method, nzbName) + logger.postprocess("SUCCESS: Started %s scan on folder %s, please wait ..." % (method, dirName), section) else: - logger.error("FAILED: %s scan has NOT started on CouchPotato for %s. Exiting ...", method, nzbName) + logger.error("FAILED: %s scan was unable to start for folder %s. exiting!" % (method, dirName), section) return 1 # failure else: - logger.postprocess("Download of %s has failed.", nzbName) + logger.postprocess("FAILED DOWNLOAD DETECTED FOR %s" % (nzbName), section) if delete_failed and os.path.isdir(dirName) and not os.path.dirname(dirName) == dirName: - logger.postprocess("Deleting failed files and folder %s", dirName) + logger.postprocess("Deleting failed files and folder %s" % dirName, section) delete(dirName) if not download_id: - logger.warning("Could not find a movie in the database for release %s", nzbName) - logger.warning("Please manually ignore this release and refresh the wanted movie from CouchPotato, Exiting ...") + logger.error("Could not find a downloaded movie in the database matching %s, exiting!" % nzbName, section) return 1 # failure - logger.postprocess("Ignoring current failed release %s ...", nzbName) + logger.postprocess("Setting failed release %s to ignored ..." % (nzbName), section) url = baseURL + "/release.ignore" - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % (url), section) try: r = requests.get(url, params={'id': release_id}) except requests.ConnectionError: - logger.error("Unable to open URL") + logger.error("Unable to open URL %s" % (url), section) return 1 # failure result = r.json() if result['success']: - logger.postprocess("%s has been set to ignored on CouchPotato", nzbName) + logger.postprocess("SUCCESS: %s has been set to ignored ..." % (nzbName), section) else: - logger.warning("Failed to ignore %s on CouchPotato ...", nzbName) + logger.warning("FAILED: Unable to set %s to ignored!" % (nzbName), section) - logger.postprocess("Snatching next highest ranked release on CouchPotato ...") + logger.postprocess("Trying to snatch the next highest ranked release.", section) - url = baseURL + "/movie.searcher.try_next" - logger.debug("Opening URL: %s", url) + url = "%s/movie.searcher.try_next" % (baseURL) + logger.debug("Opening URL: %s" % (url), section) try: r = requests.get(url, params={'media_id': media_id}) except requests.ConnectionError: - logger.error("Unable to open URL") + logger.error("Unable to open URL %s" % (url), section) return 1 # failure result = r.json() if result['success']: - logger.postprocess("CouchPotato successfully snatched the next highest release above %s ...", nzbName) + logger.postprocess("SUCCESS: Snatched the next highest release ...", section) return 0 else: - logger.postprocess("CouchPotato was unable to find a higher release then %s to snatch ...", nzbName) + logger.postprocess("FAILED: Unable to find a higher ranked release then %s to snatch!" % (nzbName), section) return 1 # we will now check to see if CPS has finished renaming before returning to TorrentToMedia and unpausing. timeout = time.time() + 60 * wait_for while (time.time() < timeout): # only wait 2 (default) minutes, then return. - releases_current = self.get_releases(baseURL, download_id, dirName, nzbName) + releases_current = self.get_releases(baseURL, imdbid, download_id) releasesDiff = self.releases_diff(releases, releases_current) + logger.postprocess("Checking for status change, please stand by ...", section) if releasesDiff: # Something has changed. CPS must have processed this movie. - release_status = releasesDiff[releasesDiff.keys()[0]]['status'] - logger.postprocess("SUCCESS: Release %s marked as [%s] on CouchPotato", nzbName, release_status) - return 0 # success + try: + release_status = releasesDiff[releasesDiff.keys()[0]]['status'] + logger.postprocess("SUCCESS: Release %s has now been marked with a status of [%s]" % (nzbName, str(release_status).upper()), section) + return 0 # success + except:pass # pause and let CouchPotatoServer catch its breath time.sleep(10 * wait_for) # The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now. - logger.warning("The movie does not appear to have changed status after %s minutes. Please check CouchPotato Logs", wait_for) + logger.warning("%s does not appear to have changed status after %s minutes, Please check your logs." % (nzbName, wait_for), section) return 1 # failure \ No newline at end of file diff --git a/nzbtomedia/autoProcess/autoProcessMusic.py b/nzbtomedia/autoProcess/autoProcessMusic.py index c7fc09cd..a7dd21d8 100644 --- a/nzbtomedia/autoProcess/autoProcessMusic.py +++ b/nzbtomedia/autoProcess/autoProcessMusic.py @@ -7,7 +7,7 @@ from nzbtomedia import logger class autoProcessMusic: def get_status(self, baseURL, apikey, dirName): - logger.debug("Attempting to get current status for release:%s", os.path.basename(dirName)) + logger.debug("Attempting to get current status for release:%s" % (os.path.basename(dirName))) url = baseURL @@ -15,7 +15,7 @@ class autoProcessMusic: params['apikey'] = apikey params['cmd'] = "getHistory" - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % (url)) try: r = requests.get(url, params=params) @@ -31,21 +31,13 @@ class autoProcessMusic: except:pass def process(self, dirName, nzbName=None, status=0, clientAgent="manual", inputCategory=None): - if dirName is None: - logger.error("No directory was given!") - return 1 # failure - # auto-detect correct section section = nzbtomedia.CFG.findsection(inputCategory) if len(section) == 0: logger.error( - "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) + "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % (inputCategory)) return 1 - logger.postprocess("#########################################################") - logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory) - logger.postprocess("#########################################################") - status = int(status) host = nzbtomedia.CFG[section][inputCategory]["host"] @@ -92,29 +84,29 @@ class autoProcessMusic: if release_status: if release_status not in ["unprocessed", "snatched"]: - logger.warning("%s is marked with a status of %s on HeadPhones, skipping ...", nzbName, release_status) + logger.warning("%s is marked with a status of %s, skipping ..." % (nzbName, release_status),section) return 0 else: - logger.error("Could not find a status for %s on HeadPhones", nzbName) + logger.error("Could not find a status for %s" % (nzbName),section) return 1 - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % (url),section) try: r = requests.get(url, params=params) except requests.ConnectionError: - logger.error("Unable to open URL") + logger.error("Unable to open URL %s" % (url),section) return 1 # failure - logger.postprocess("HeadPhones returned %s", r.text) + logger.debug("Result: %s" % (r.text),section) if r.text == "OK": - logger.postprocess("Post-processing started on HeadPhones for %s in folder %s", nzbName, dirName) + logger.postprocess("SUCCESS: Post-Processing started for %s in folder %s ..." % (nzbName, dirName),section) else: - logger.error("Post-proecssing has NOT started on HeadPhones for %s in folder %s. Exiting", nzbName, dirName) + logger.error("FAILED: Post-Processing has NOT started for %s in folder %s. exiting!" % (nzbName, dirName),section) return 1 # failure else: - logger.postprocess("The download failed. Nothing to process") + logger.warning("FAILED DOWNLOAD DETECTED", section) return 0 # Success (as far as this script is concerned) # we will now wait 1 minutes for this album to be processed before returning to TorrentToMedia and unpausing. @@ -122,11 +114,11 @@ class autoProcessMusic: while (time.time() < timeout): # only wait 2 (default) minutes, then return. current_status = self.get_status(url, apikey, dirName) if current_status is not None and current_status != release_status: # Something has changed. CPS must have processed this movie. - logger.postprocess("SUCCESS: This release is now marked as status [%s] in HeadPhones",current_status) + logger.postprocess("SUCCESS: This release is now marked as status [%s]" % (current_status),section) return 0 time.sleep(10 * wait_for) # The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now. - logger.warning("The music album does not appear to have changed status after %s minutes. Please check HeadPhones Logs",2) + logger.warning("The music album does not appear to have changed status after %s minutes. Please check your Logs" % (wait_for)) return 1 # failure diff --git a/nzbtomedia/autoProcess/autoProcessTV.py b/nzbtomedia/autoProcess/autoProcessTV.py index ae681f16..f391046e 100644 --- a/nzbtomedia/autoProcess/autoProcessTV.py +++ b/nzbtomedia/autoProcess/autoProcessTV.py @@ -10,21 +10,13 @@ from nzbtomedia import logger class autoProcessTV: def processEpisode(self, dirName, nzbName=None, failed=False, clientAgent = "manual", inputCategory=None): - if dirName is None: - logger.error("No directory was given!") - return 1 # failure - # auto-detect correct section section = nzbtomedia.CFG.findsection(inputCategory) if not section: logger.error( - "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) + "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory) return 1 - logger.postprocess("#########################################################") - logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory) - logger.postprocess("#########################################################") - # auto-detect correct fork fork, fork_params = autoFork(inputCategory) @@ -47,18 +39,10 @@ class autoProcessTV: web_root = nzbtomedia.CFG[section][inputCategory]["web_root"] except: web_root = "" - try: - transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"]) - except: - transcode = 0 try: delete_failed = int(nzbtomedia.CFG[section][inputCategory]["delete_failed"]) except: delete_failed = 0 - try: - SampleIDs = (nzbtomedia.CFG["Extensions"]["SampleIDs"]) - except: - SampleIDs = ['sample','-s.'] try: nzbExtractionBy = nzbtomedia.CFG[section][inputCategory]["nzbExtractionBy"] except: @@ -98,18 +82,18 @@ class autoProcessTV: filePath = os.path.join(dirpath, file) fileExtension = os.path.splitext(file)[1] if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file - if is_sample(filePath, nzbName, nzbtomedia.MINSAMPLESIZE, SampleIDs): - logger.debug("Removing sample file: %s", filePath) + if is_sample(filePath, nzbName, nzbtomedia.MINSAMPLESIZE, nzbtomedia.SAMPLEIDS): + logger.debug("Removing sample file: %s" % (filePath), section) os.unlink(filePath) # remove samples else: video = video + 1 if video > 0: # Check that a video exists. if not, assume failed. flatten(dirName) # to make sure SickBeard can find the video (not in sub-folder) elif clientAgent == "manual": - logger.warning("No media files found in directory %s to manually process.", dirName) + logger.warning("No media files found in directory %s to manually process." % (dirName), section) return 0 # Success (as far as this script is concerned) else: - logger.warning("No media files found in directory %s. Processing this as a failed download", dirName) + logger.warning("No media files found in directory %s. Processing this as a failed download" % (dirName), section) status = int(1) failed = True @@ -140,37 +124,36 @@ class autoProcessTV: [fork_params.pop(k) for k,v in fork_params.items() if v is None] if status == 0: - logger.postprocess("The download succeeded. Sending process request to %s", section) + logger.postprocess("SUCCESS: The download succeeded, sending a post-process request", section) else: if fork in nzbtomedia.SICKBEARD_FAILED: - logger.postprocess("The download failed. Sending 'failed' process request to SickBeard's %s branch", fork) + logger.postprocess("FAILED: The download failed. Sending 'failed' process request to %s branch" % (fork), section) else: - logger.postprocess("The download failed. SickBeard's %s branch does not handle failed downloads. Nothing to process", fork) + logger.postprocess("FAILED: The download failed. %s branch does not handle failed downloads. Nothing to process" % (fork), section) if delete_failed and os.path.isdir(dirName) and not os.path.dirname(dirName) == dirName: - logger.postprocess("Deleting failed files and folder %s", dirName) + logger.postprocess("Deleting failed files and folder %s" % (dirName), section) delete(dirName) return 0 # Success (as far as this script is concerned) - if status == 0 and transcode == 1: # only transcode successful downlaods + if status == 0 and nzbtomedia.TRANSCODE == 1: # only transcode successful downlaods result = Transcoder().Transcode_directory(dirName) if result == 0: - logger.debug("Transcoding succeeded for files in %s", dirName) + logger.debug("SUCCESS: Transcoding succeeded for files in %s" % (dirName), section) else: - logger.warning("Transcoding failed for files in %s", dirName) + logger.warning("FAILED: Transcoding failed for files in %s" % (dirName), section) if ssl: protocol = "https://" else: protocol = "http://" - url = None if section == "SickBeard": url = "%s%s:%s%s/home/postprocess/processEpisode" % (protocol,host,port,web_root) elif section == "NzbDrone": url = "%s%s:%s%s/api/command" % (protocol, host, port, web_root) - logger.debug("Opening URL: %s", url) + logger.debug("Opening URL: %s" % (url),section) try: r = None @@ -181,13 +164,13 @@ class autoProcessTV: headers = {"X-Api-Key": apikey} r = requests.get(url, params=params, headers=headers, stream=True) except requests.ConnectionError: - logger.error("Unable to open URL") + logger.error("Unable to open URL: %s" % (url), section) return 1 # failure for line in r.iter_lines(): - if line: logger.postprocess("%s", line) + if line: logger.postprocess("%s" % (line)) if status != 0 and delete_failed and not os.path.dirname(dirName) == dirName: - logger.postprocess("Deleting failed files and folder %s", dirName) + logger.postprocess("Deleting failed files and folder %s" % (dirName),section) delete(dirName) return 0 # Success diff --git a/nzbtomedia/extractor/extractor.py b/nzbtomedia/extractor/extractor.py index 21fb8f24..767bf786 100644 --- a/nzbtomedia/extractor/extractor.py +++ b/nzbtomedia/extractor/extractor.py @@ -11,10 +11,10 @@ def os_platform(): # Author Credit: Matthew Scouten @ http://stackoverflow.com/a/7260315 true_platform = os.environ['PROCESSOR_ARCHITECTURE'] try: - true_platform = os.environ["PROCESSOR_ARCHITEW6432"] + true_platform = os.environ["PROCESSOR_ARCHITEW6432"] except KeyError: - pass - #true_platform not assigned to if this does not exist + pass + #true_platform not assigned to if this does not exist return true_platform @@ -27,10 +27,13 @@ def extract(filePath, outputDestination): platform = 'x86' if not os.path.dirname(sys.argv[0]): chplocation = os.path.normpath(os.path.join(os.getcwd(), 'nzbtomedia/extractor/bin/chp.exe')) - sevenzipLocation = os.path.normpath(os.path.join(os.getcwd(), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) + sevenzipLocation = os.path.normpath( + os.path.join(os.getcwd(), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) else: - chplocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/chp.exe')) - sevenzipLocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) + chplocation = os.path.normpath( + os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/chp.exe')) + sevenzipLocation = os.path.normpath( + os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) if not os.path.exists(sevenzipLocation): logger.error("EXTRACTOR: Could not find 7-zip, Exiting") return False @@ -39,11 +42,11 @@ def extract(filePath, outputDestination): cmd_7zip = [sevenzipLocation, "x", "-y"] else: cmd_7zip = [chplocation, sevenzipLocation, "x", "-y"] - ext_7zip = [".rar",".zip",".tar.gz","tgz",".tar.bz2",".tbz",".tar.lzma",".tlz",".7z",".xz"] + ext_7zip = [".rar", ".zip", ".tar.gz", "tgz", ".tar.bz2", ".tbz", ".tar.lzma", ".tlz", ".7z", ".xz"] EXTRACT_COMMANDS = dict.fromkeys(ext_7zip, cmd_7zip) # Using unix else: - required_cmds=["unrar", "unzip", "tar", "unxz", "unlzma", "7zr", "bunzip2"] + required_cmds = ["unrar", "unzip", "tar", "unxz", "unlzma", "7zr", "bunzip2"] ## Possible future suport: # gunzip: gz (cmd will delete original archive) ## the following do not extract to dest dir @@ -60,14 +63,14 @@ def extract(filePath, outputDestination): ".tar.lzma": ["tar", "--lzma", "-xf"], ".tlz": ["tar", "--lzma", "-xf"], ".tar.xz": ["tar", "--xz", "-xf"], ".txz": ["tar", "--xz", "-xf"], ".7z": ["7zr", "x"], - } + } # Test command exists and if not, remove if not os.getenv('TR_TORRENT_DIR'): for cmd in required_cmds: - if call(['which', cmd]): #note, returns 0 if exists, or 1 if doesn't exist. + if call(['which', cmd]): #note, returns 0 if exists, or 1 if doesn't exist. for k, v in EXTRACT_COMMANDS.items(): if cmd in v[0]: - logger.error("EXTRACTOR: %s not found, disabling support for %s", cmd, k) + logger.error("EXTRACTOR: %s not found, disabling support for %s" % (cmd, k)) del EXTRACT_COMMANDS[k] else: logger.warning("EXTRACTOR: Cannot determine which tool to use when called from Transmission") @@ -78,16 +81,16 @@ def extract(filePath, outputDestination): ext = os.path.splitext(filePath) cmd = [] if ext[1] in (".gz", ".bz2", ".lzma"): - # Check if this is a tar + # Check if this is a tar if os.path.splitext(ext[0])[1] == ".tar": cmd = EXTRACT_COMMANDS[".tar" + ext[1]] - elif ext[1] in (".1", ".01", ".001") and os.path.splitext(ext[0])[1] in (".rar", ".zip", ".7z"): #support for *.zip.001, *.zip.002 etc. - cmd = EXTRACT_COMMANDS[os.path.splitext(ext[0])[1]] + elif ext[1] in (".1", ".01", ".001") and os.path.splitext(ext[0])[1] in (".rar", ".zip", ".7z"): + cmd = EXTRACT_COMMANDS[os.path.splitext(ext[0])[1]] else: if ext[1] in EXTRACT_COMMANDS: cmd = EXTRACT_COMMANDS[ext[1]] else: - logger.debug("EXTRACTOR: Unknown file type: %s", ext[1]) + logger.debug("EXTRACTOR: Unknown file type: %s" % ext[1]) return False # Create outputDestination folder @@ -99,39 +102,42 @@ def extract(filePath, outputDestination): else: passwords = [] - logger.info("Extracting %s to %s", filePath, outputDestination) - logger.debug("Extracting %s %s %s", cmd, filePath, outputDestination) - pwd = os.getcwd() # Get our Present Working Directory - os.chdir(outputDestination) # Not all unpack commands accept full paths, so just extract into this directory - try: # now works same for nt and *nix - cmd.append(filePath) # add filePath to final cmd arg. + logger.info("Extracting %s to %s" % (filePath, outputDestination)) + logger.debug("Extracting %s %s %s" % (cmd, filePath, outputDestination)) + pwd = os.getcwd() # Get our Present Working Directory + os.chdir(outputDestination) # Not all unpack commands accept full paths, so just extract into this directory + try: # now works same for nt and *nix + cmd.append(filePath) # add filePath to final cmd arg. cmd2 = cmd - cmd2.append("-p-") # don't prompt for password. - p = Popen(cmd2) # should extract files fine. + cmd2.append("-p-") # don't prompt for password. + p = Popen(cmd2) # should extract files fine. res = p.wait() - if (res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful. - logger.info("EXTRACTOR: Extraction was successful for %s to %s", filePath, outputDestination) + if ( + res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful. + logger.info("EXTRACTOR: Extraction was successful for %s to %s" % (filePath, outputDestination)) elif len(passwords) > 0: logger.info("EXTRACTOR: Attempting to extract with passwords") pass_success = int(0) for password in passwords: - if password == "": # if edited in windows or otherwise if blank lines. + if password == "": # if edited in windows or otherwise if blank lines. continue cmd2 = cmd #append password here. passcmd = "-p" + password cmd2.append(passcmd) - p = Popen(cmd2) # should extract files fine. + p = Popen(cmd2) # should extract files fine. res = p.wait() - if (res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful. - logger.info("EXTRACTOR: Extraction was successful for %s to %s using password: %s", filePath, outputDestination, password) + if ( + res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful. + logger.info("EXTRACTOR: Extraction was successful for %s to %s using password: %s" % ( + filePath, outputDestination, password)) pass_success = int(1) break else: continue if pass_success == int(0): - logger.error("EXTRACTOR: Extraction failed for %s. 7zip result was %s", filePath, res) + logger.error("EXTRACTOR: Extraction failed for %s. 7zip result was %s" % (filePath, res)) except: - logger.error("EXTRACTOR: Extraction failed for %s. Could not call command %s", filePath, cmd) - os.chdir(pwd) # Go back to our Original Working Directory + logger.error("EXTRACTOR: Extraction failed for %s. Could not call command %s" % (filePath, cmd)) + os.chdir(pwd) # Go back to our Original Working Directory return True diff --git a/nzbtomedia/logger.py b/nzbtomedia/logger.py index ad013304..937d287f 100644 --- a/nzbtomedia/logger.py +++ b/nzbtomedia/logger.py @@ -76,8 +76,8 @@ class NTMRotatingLogHandler(object): # set a format which is simpler for console use console.setFormatter(DispatchingFormatter( - {'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)s:: %(message)s', '%H:%M:%S'), - 'postprocess': logging.Formatter('%(asctime)s %(levelname)s:: %(message)s', '%H:%M:%S') + {'nzbtomedia': logging.Formatter('[%(asctime)s] [%(levelname)s]::%(message)s', '%H:%M:%S'), + 'postprocess': logging.Formatter('[%(asctime)s] [%(levelname)s]::%(message)s', '%H:%M:%S') }, logging.Formatter('%(message)s'), )) @@ -109,8 +109,8 @@ class NTMRotatingLogHandler(object): file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(DispatchingFormatter( - {'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)-8s:: %(message)s', '%Y-%m-%d %H:%M:%S'), - 'postprocess': logging.Formatter('%(asctime)s %(levelname)-8s:: %(message)s', '%Y-%m-%d %H:%M:%S') + {'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)-8s::%(message)s', '%Y-%m-%d %H:%M:%S'), + 'postprocess': logging.Formatter('%(asctime)s %(levelname)-8s::%(message)s', '%Y-%m-%d %H:%M:%S') }, logging.Formatter('%(message)s'), )) @@ -166,7 +166,7 @@ class NTMRotatingLogHandler(object): ntm_logger.addHandler(new_file_handler) pp_logger.addHandler(new_file_handler) - def log(self, toLog, logLevel=MESSAGE): + def log(self, toLog, logLevel=MESSAGE, section='MAIN'): with self.log_lock: @@ -178,7 +178,7 @@ class NTMRotatingLogHandler(object): else: self.writes_since_check += 1 - message = u"" + toLog + message = u"%s:: %s" % (str(section).upper(), toLog) out_line = message @@ -188,7 +188,8 @@ class NTMRotatingLogHandler(object): try: if logLevel == DEBUG: - ntm_logger.debug(out_line) + if nzbtomedia.LOG_DEBUG == 1: + ntm_logger.debug(out_line) elif logLevel == MESSAGE: ntm_logger.info(out_line) elif logLevel == WARNING: @@ -221,31 +222,26 @@ class DispatchingFormatter: ntm_log_instance = NTMRotatingLogHandler("nzbtomedia.log", NUM_LOGS, LOG_SIZE) -def log(toLog, logLevel=MESSAGE): - ntm_log_instance.log(toLog, logLevel) +def log(toLog, logLevel=MESSAGE, section='MAIN'): + ntm_log_instance.log(toLog, logLevel, section) -def info(toLog, *args): - toLog = toLog % args - ntm_log_instance.log(toLog, MESSAGE) +def info(toLog, section='MAIN'): + log(toLog, MESSAGE, section) -def error(toLog, *args): - toLog = toLog % args - ntm_log_instance.log(toLog, ERROR) +def error(toLog, section='MAIN'): + log(toLog, ERROR, section) -def warning(toLog, *args): - toLog = toLog % args - ntm_log_instance.log(toLog, WARNING) +def warning(toLog, section='MAIN'): + log(toLog, WARNING, section) -def debug(toLog, *args): - toLog = toLog % args - ntm_log_instance.log(toLog, DEBUG) +def debug(toLog, section='MAIN'): + log(toLog, DEBUG, section) + +def postprocess(toLog, section='MAIN'): + log(toLog, POSTPROCESS, section) def log_error_and_exit(error_msg): ntm_log_instance.log_error_and_exit(error_msg) -def postprocess(toLog, *args): - toLog = toLog % args - ntm_log_instance.log(toLog, POSTPROCESS) - def close(): ntm_log_instance.close_log() diff --git a/nzbtomedia/nzbToMediaAutoFork.py b/nzbtomedia/nzbToMediaAutoFork.py index 479d2595..f82c2c7c 100644 --- a/nzbtomedia/nzbToMediaAutoFork.py +++ b/nzbtomedia/nzbToMediaAutoFork.py @@ -7,7 +7,7 @@ def autoFork(inputCategory): section = nzbtomedia.CFG.findsection(inputCategory) if not section: logger.error( - "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) + "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory) return 1 # config settings @@ -47,9 +47,9 @@ def autoFork(inputCategory): detected = False if fork == "auto": - logger.info("Attempting to auto-detect " + section + " fork") + logger.info("Attempting to auto-detect %s fork" % inputCategory) for fork in sorted(nzbtomedia.FORKS.iteritems(), reverse=False): - url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(fork[1]) + url = "%s%s:%s%s/home/postprocess/processEpisode?%s" % (protocol,host,port,web_root,urllib.urlencode(fork[1])) # attempting to auto-detect fork try: @@ -58,7 +58,7 @@ def autoFork(inputCategory): else: r = requests.get(url) except requests.ConnectionError: - logger.info("Could not connect to " + section + ":" + inputCategory + " to perform auto-fork detection!") + logger.info("Could not connect to %s:%s to perform auto-fork detection!" % (section, inputCategory)) break if r.ok: @@ -66,10 +66,10 @@ def autoFork(inputCategory): break if detected: - logger.info("" + section + ":" + inputCategory + " fork auto-detection successful ...") + logger.info("%s:%s fork auto-detection successful ..." % (section, inputCategory)) else: - logger.info("" + section + ":" + inputCategory + " fork auto-detection failed") + logger.info("%s:%s fork auto-detection failed" % (section, inputCategory)) fork = nzbtomedia.FORKS.items()[nzbtomedia.FORKS.keys().index(nzbtomedia.FORK_DEFAULT)] - logger.info("" + section + ":" + inputCategory + " fork set to %s", fork[0]) + logger.info("%s:%s inputCategory fork set to %s" % (section, inputCategory, fork[0])) return fork[0], fork[1] \ No newline at end of file diff --git a/nzbtomedia/nzbToMediaUtil.py b/nzbtomedia/nzbToMediaUtil.py index fb9d2a72..e8b1b6d0 100644 --- a/nzbtomedia/nzbToMediaUtil.py +++ b/nzbtomedia/nzbToMediaUtil.py @@ -4,7 +4,6 @@ import socket import stat import struct import shutil -import sys import time from lib import requests import nzbtomedia @@ -15,9 +14,10 @@ from nzbtomedia.synchronousdeluge.client import DelugeClient from nzbtomedia.utorrent.client import UTorrentClient from nzbtomedia.transmissionrpc.client import Client as TransmissionClient + def safeName(name): - safename = re.sub(r"[\/\\\:\*\?\"\<\>\|]", "", name) #make this name safe for use in directories for windows etc. - return safename + return re.sub(r"[\/\\\:\*\?\"\<\>\|]", "", name) #make this name safe for use in directories for windows etc. + def makeDir(path): if not os.path.isdir(path): @@ -27,6 +27,7 @@ def makeDir(path): return False return True + def category_search(inputDirectory, inputName, inputCategory, root, categories): single = False tordir = False @@ -49,16 +50,18 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): return inputDirectory, inputName, inputCategory, root, single if inputCategory and os.path.isdir(os.path.join(inputDirectory, inputCategory)): - logger.info("SEARCH: Found category directory %s in input directory directory %s", inputCategory, inputDirectory) + logger.info( + "SEARCH: Found category directory %s in input directory directory %s" % (inputCategory, inputDirectory)) inputDirectory = os.path.join(inputDirectory, inputCategory) logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory) if inputName and os.path.isdir(os.path.join(inputDirectory, inputName)): - logger.info("SEARCH: Found torrent directory %s in input directory directory %s", inputName, inputDirectory) + logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % (inputName, inputDirectory)) inputDirectory = os.path.join(inputDirectory, inputName) logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory) tordir = True if inputName and os.path.isdir(os.path.join(inputDirectory, safeName(inputName))): - logger.info("SEARCH: Found torrent directory %s in input directory directory %s", safeName(inputName), inputDirectory) + logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % ( + safeName(inputName), inputDirectory)) inputDirectory = os.path.join(inputDirectory, safeName(inputName)) logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory) tordir = True @@ -73,8 +76,8 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): index = pathlist.index(inputCategory) if index + 1 < len(pathlist): tordir = True - logger.info("SEARCH: Found a unique directory %s in the category directory", pathlist[index+1]) - if not inputName: inputName = pathlist[index+1] + logger.info("SEARCH: Found a unique directory %s in the category directory", pathlist[index + 1]) + if not inputName: inputName = pathlist[index + 1] except ValueError: pass @@ -93,6 +96,7 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): return inputDirectory, inputName, inputCategory, root, single + def is_sample(filePath, inputName, minSampleSize, SampleIDs): # 200 MB in bytes SIZE_CUTOFF = minSampleSize * 1024 * 1024 @@ -101,7 +105,7 @@ def is_sample(filePath, inputName, minSampleSize, SampleIDs): return True # Ignore 'sample' in files unless 'sample' in Torrent Name for ident in SampleIDs: - if ident.lower() in filePath.lower() and not ident.lower() in inputName.lower(): + if ident.lower() in filePath.lower() and not ident.lower() in inputName.lower(): return True # Return False if none of these were met. return False @@ -115,41 +119,45 @@ def copy_link(filePath, targetDirectory, useLink, outputDestination): makeDir(outputDestination) if useLink == "hard": try: - logger.info("COPYLINK: Hard linking %s to %s", filePath, targetDirectory) + logger.info("COPYLINK: Hard linking %s to %s" % (filePath, targetDirectory)) linktastic.link(filePath, targetDirectory) except: logger.error("COPYLINK") if os.path.isfile(targetDirectory): - logger.warning("COPYLINK: Something went wrong in linktastic.link, but the destination file was created") + logger.warning( + "COPYLINK: Something went wrong in linktastic.link, but the destination file was created") else: logger.warning("COPYLINK: Something went wrong in linktastic.link, copying instead") - logger.debug("COPYLINK: Copying %s to %s", filePath, targetDirectory) + logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory)) shutil.copy(filePath, targetDirectory) elif useLink == "sym": try: - logger.info("COPYLINK: Moving %s to %s before sym linking", filePath, targetDirectory) + logger.info("COPYLINK: Moving %s to %s before sym linking" % (filePath, targetDirectory)) shutil.move(filePath, targetDirectory) - logger.info("COPYLINK: Sym linking %s to %s", targetDirectory, filePath) + logger.info("COPYLINK: Sym linking %s to %s" % (targetDirectory, filePath)) linktastic.symlink(targetDirectory, filePath) except: logger.error("COPYLINK") if os.path.isfile(targetDirectory): - logger.warning("COPYLINK: Something went wrong in linktastic.link, but the destination file was created") + logger.warning( + "COPYLINK: Something went wrong in linktastic.link, but the destination file was created") else: logger.info("COPYLINK: Something went wrong in linktastic.link, copying instead") - logger.debug("COPYLINK: Copying %s to %s", filePath, targetDirectory) + logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory)) shutil.copy(filePath, targetDirectory) elif useLink == "move": - logger.debug("Moving %s to %s", filePath, targetDirectory) + logger.debug("Moving %s to %s" % (filePath, targetDirectory)) shutil.move(filePath, targetDirectory) else: - logger.debug("Copying %s to %s", filePath, targetDirectory) + logger.debug("Copying %s to %s" % (filePath, targetDirectory)) shutil.copy(filePath, targetDirectory) return True + def flatten(outputDestination): logger.info("FLATTEN: Flattening directory: %s", outputDestination) - for dirpath, dirnames, filenames in os.walk(outputDestination): # Flatten out the directory to make postprocessing easier + for dirpath, dirnames, filenames in os.walk( + outputDestination): # Flatten out the directory to make postprocessing easier if dirpath == outputDestination: continue # No need to try and move files in the root destination directory for filename in filenames: @@ -161,6 +169,7 @@ def flatten(outputDestination): logger.error("FLATTEN: Could not flatten %s", source) removeEmptyFolders(outputDestination) # Cleanup empty directories + def removeEmptyFolders(path): logger.info("REMOVER: Removing empty folders in: %s", path) if not os.path.isdir(path): @@ -180,6 +189,7 @@ def removeEmptyFolders(path): logger.debug("REMOVER: Removing empty folder: %s", path) os.rmdir(path) + def remove_read_only(path): if not os.path.isdir(path): return @@ -188,16 +198,16 @@ def remove_read_only(path): logger.debug("Removing Read Only Flag for: %s", filename) os.chmod(os.path.join(dirpath, filename), stat.S_IWRITE) + #Wake function def WakeOnLan(ethernet_address): - addr_byte = ethernet_address.split(':') hw_addr = struct.pack('BBBBBB', int(addr_byte[0], 16), - int(addr_byte[1], 16), - int(addr_byte[2], 16), - int(addr_byte[3], 16), - int(addr_byte[4], 16), - int(addr_byte[5], 16)) + int(addr_byte[1], 16), + int(addr_byte[2], 16), + int(addr_byte[3], 16), + int(addr_byte[4], 16), + int(addr_byte[5], 16)) # Build the Wake-On-LAN "Magic Packet"... @@ -210,6 +220,7 @@ def WakeOnLan(ethernet_address): ss.sendto(msg, ('', 9)) ss.close() + #Test Connection function def TestCon(host, port): try: @@ -218,50 +229,55 @@ def TestCon(host, port): except: return "Down" + def WakeUp(): wake = int(nzbtomedia.CFG["WakeOnLan"]["wake"]) - if wake == 0: # just return if we don't need to wake anything. + if wake == 0: # just return if we don't need to wake anything. return logger.info(("Loading WakeOnLan config from %s", nzbtomedia.CONFIG_FILE)) host = nzbtomedia.CFG["WakeOnLan"]["host"] port = int(nzbtomedia.CFG["WakeOnLan"]["port"]) mac = nzbtomedia.CFG["WakeOnLan"]["mac"] - i=1 + i = 1 while TestCon(host, port) == "Down" and i < 4: logger.info(("Sending WakeOnLan Magic Packet for mac: %s", mac)) WakeOnLan(mac) time.sleep(20) - i=i+1 + i = i + 1 - if TestCon(host,port) == "Down": # final check. - logger.warning("System with mac: %s has not woken after 3 attempts. Continuing with the rest of the script.", mac) + if TestCon(host, port) == "Down": # final check. + logger.warning("System with mac: %s has not woken after 3 attempts. Continuing with the rest of the script.", + mac) else: logger.info("System with mac: %s has been woken. Continuing with the rest of the script.", mac) + def convert_to_ascii(nzbName, dirName): ascii_convert = int(nzbtomedia.CFG["ASCII"]["convert"]) - if ascii_convert == 0 or os.name == 'nt': # just return if we don't want to convert or on windows os and "\" is replaced!. + if ascii_convert == 0 or os.name == 'nt': # just return if we don't want to convert or on windows os and "\" is replaced!. return nzbName, dirName - + nzbName2 = str(nzbName.decode('ascii', 'replace').replace(u'\ufffd', '_')) dirName2 = str(dirName.decode('ascii', 'replace').replace(u'\ufffd', '_')) if dirName != dirName2: - logger.info("Renaming directory:%s to: %s.", dirName, dirName2) + logger.info("Renaming directory:%s to: %s." % (dirName, dirName2)) shutil.move(dirName, dirName2) for dirpath, dirnames, filesnames in os.walk(dirName2): for filename in filesnames: filename2 = str(filename.decode('ascii', 'replace').replace(u'\ufffd', '_')) if filename != filename2: - logger.info("Renaming file:%s to: %s.", filename, filename2) + logger.info("Renaming file:%s to: %s." % (filename, filename2)) shutil.move(filename, filename2) nzbName = nzbName2 dirName = dirName2 return nzbName, dirName + def parse_other(args): return os.path.normpath(args[1]), '', '', '', '' + def parse_rtorrent(args): # rtorrent usage: system.method.set_key = event.download.finished,TorrentToMedia, # "execute={/path/to/nzbToMedia/TorrentToMedia.py,\"$d.get_base_path=\",\"$d.get_name=\",\"$d.get_custom1=\",\"$d.get_hash=\"}" @@ -285,6 +301,7 @@ def parse_rtorrent(args): return inputDirectory, inputName, inputCategory, inputHash, inputID + def parse_utorrent(args): # uTorrent usage: call TorrentToMedia.py "%D" "%N" "%L" "%I" inputDirectory = os.path.normpath(args[1]) @@ -324,21 +341,23 @@ def parse_transmission(args): inputID = os.getenv('TR_TORRENT_ID') return inputDirectory, inputName, inputCategory, inputHash, inputID + def parse_args(clientAgent, args): clients = { - 'other': parse_other, - 'rtorrent': parse_rtorrent, - 'utorrent': parse_utorrent, - 'deluge': parse_deluge, - 'transmission': parse_transmission, + 'other': parse_other, + 'rtorrent': parse_rtorrent, + 'utorrent': parse_utorrent, + 'deluge': parse_deluge, + 'transmission': parse_transmission, } try: return clients[clientAgent](args) - except:return None, None, None, None, None + except: + return None, None, None, None, None + def get_dirnames(section, subsections=None): - dirNames = [] if subsections is None: @@ -386,13 +405,14 @@ def get_dirnames(section, subsections=None): shutil.move(mediafile, p) dirNames.extend([os.path.join(outputDirectory, o) for o in os.listdir(outputDirectory) if - os.path.isdir(os.path.join(outputDirectory, o))]) + os.path.isdir(os.path.join(outputDirectory, o))]) if not dirNames: - logger.warning("%s:%s has no directories identified for post-processing", section, subsection) + logger.warning("%s:%s has no directories identified for post-processing" % (section, subsection)) return list(set(dirNames)) + def delete(dirName): logger.info("Deleting %s", dirName) try: @@ -400,6 +420,7 @@ def delete(dirName): except: logger.error("Unable to delete folder %s", dirName) + def cleanup_directories(inputCategory, processCategories, result, directory): if inputCategory in processCategories and result == 0 and os.path.isdir(directory): num_files_new = int(0) @@ -415,90 +436,97 @@ def cleanup_directories(inputCategory, processCategories, result, directory): logger.info("All files have been processed. Cleaning directory %s", directory) shutil.rmtree(directory) else: - logger.info("Directory %s still contains %s media and/or meta files. This directory will not be removed.", directory, num_files_new) + logger.info( + "Directory %s still contains %s media and/or meta files. This directory will not be removed." % ( + directory, num_files_new)) for item in file_list: logger.debug("media/meta file found: %s", item) + def create_torrent_class(clientAgent): # Hardlink solution for Torrents TorrentClass = None if clientAgent == 'utorrent': try: - logger.debug("Connecting to %s: %s", clientAgent, nzbtomedia.UTORRENTWEBUI) + logger.debug("Connecting to %s: %s" % (clientAgent, nzbtomedia.UTORRENTWEBUI)) TorrentClass = UTorrentClient(nzbtomedia.UTORRENTWEBUI, nzbtomedia.UTORRENTUSR, nzbtomedia.UTORRENTPWD) except: logger.error("Failed to connect to uTorrent") if clientAgent == 'transmission': try: - logger.debug("Connecting to %s: http://%s:%s", clientAgent, nzbtomedia.TRANSMISSIONHOST, - nzbtomedia.TRANSMISSIONPORT) - TorrentClass = TransmissionClient(nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT, nzbtomedia.TRANSMISSIONUSR, + logger.debug("Connecting to %s: http://%s:%s" % ( + clientAgent, nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT)) + TorrentClass = TransmissionClient(nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT, + nzbtomedia.TRANSMISSIONUSR, nzbtomedia.TRANSMISSIONPWD) except: logger.error("Failed to connect to Transmission") if clientAgent == 'deluge': try: - logger.debug("Connecting to %s: http://%s:%s", clientAgent, nzbtomedia.DELUGEHOST, - nzbtomedia.DELUGEPORT) + logger.debug("Connecting to %s: http://%s:%s" % (clientAgent, nzbtomedia.DELUGEHOST, nzbtomedia.DELUGEPORT)) TorrentClass = DelugeClient() - TorrentClass.connect(host =nzbtomedia.DELUGEHOST, port =nzbtomedia.DELUGEPORT, username =nzbtomedia.DELUGEUSR, password =nzbtomedia.DELUGEPWD) + TorrentClass.connect(host=nzbtomedia.DELUGEHOST, port=nzbtomedia.DELUGEPORT, username=nzbtomedia.DELUGEUSR, + password=nzbtomedia.DELUGEPWD) except: logger.error("Failed to connect to Deluge") return TorrentClass + def pause_torrent(clientAgent, TorrentClass, inputHash, inputID, inputName): # if we are using links with Torrents it means we need to pause it in order to access the files - logger.debug("Stoping torrent %s in %s while processing", inputName, clientAgent) + logger.debug("Stoping torrent %s in %s while processing" % (inputName, clientAgent)) if clientAgent == 'utorrent' and TorrentClass != "": TorrentClass.stop(inputHash) - if clientAgent == 'transmission' and TorrentClass !="": + if clientAgent == 'transmission' and TorrentClass != "": TorrentClass.stop_torrent(inputID) if clientAgent == 'deluge' and TorrentClass != "": TorrentClass.core.pause_torrent([inputID]) time.sleep(5) # Give Torrent client some time to catch up with the change + def resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName): # Hardlink solution for uTorrent, need to implent support for deluge, transmission - if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash: + if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash: # Delete torrent and torrentdata from Torrent client if processing was successful. - if (int(nzbtomedia.CFG["Torrent"]["deleteOriginal"]) is 1 and result != 1) or nzbtomedia.USELINK == 'move': # if we move files, nothing to resume seeding. - logger.debug("Deleting torrent %s from %s", inputName, clientAgent) + if (int(nzbtomedia.CFG["Torrent"][ + "deleteOriginal"]) is 1 and result != 1) or nzbtomedia.USELINK == 'move': # if we move files, nothing to resume seeding. + logger.debug("Deleting torrent %s from %s" % (inputName, clientAgent)) if clientAgent == 'utorrent' and TorrentClass != "": TorrentClass.removedata(inputHash) TorrentClass.remove(inputHash) - if clientAgent == 'transmission' and TorrentClass !="": + if clientAgent == 'transmission' and TorrentClass != "": TorrentClass.remove_torrent(inputID, True) if clientAgent == 'deluge' and TorrentClass != "": TorrentClass.core.remove_torrent(inputID, True) # we always want to resume seeding, for now manually find out what is wrong when extraction fails else: - logger.debug("Starting torrent %s in %s", inputName, clientAgent) + logger.debug("Starting torrent %s in %s" % (inputName, clientAgent)) if clientAgent == 'utorrent' and TorrentClass != "": TorrentClass.start(inputHash) - if clientAgent == 'transmission' and TorrentClass !="": + if clientAgent == 'transmission' and TorrentClass != "": TorrentClass.start_torrent(inputID) if clientAgent == 'deluge' and TorrentClass != "": TorrentClass.core.resume_torrent([inputID]) time.sleep(5) -def find_download(clientAgent, nzbName, download_id): + +def find_download(clientAgent, download_id): tc = create_torrent_class(clientAgent) logger.debug("Searching for Download on %s ...", clientAgent) if clientAgent == 'utorrent': torrents = tc.list()[1]['torrents'] - if torrents: - for torrent in torrents: - if nzbName in torrent and download_id in torrent: - return True + for torrent in torrents: + if download_id in torrent: + return True if clientAgent == 'transmission': - torrent = tc.get_torrent(download_id) - if torrent: - name = torrent.name - if name == nzbName: + torrents = tc.get_torrents() + for torrent in torrents: + hash = torrent.hashString + if hash == download_id: return True if clientAgent == 'deluge': pass @@ -507,9 +535,9 @@ def find_download(clientAgent, nzbName, download_id): url = baseURL params = {} params['apikey'] = nzbtomedia.SABNZBDAPIKEY - params['mode'] = "history" + params['mode'] = "get_files" params['output'] = 'json' - + params['value'] = download_id try: r = requests.get(url, params=params) except requests.ConnectionError: @@ -517,7 +545,8 @@ def find_download(clientAgent, nzbName, download_id): return 1 # failure result = r.json() - pass + if result['files']: + return True def clean_nzbname(nzbname): @@ -537,6 +566,7 @@ def clean_nzbname(nzbname): nzbname = re.sub("^\[.*\]", "", nzbname) return nzbname.strip() + def isMediaFile(filename): # ignore samples if re.search('(^|[\W_])(sample\d*)[\W_]', filename, re.I): @@ -556,6 +586,7 @@ def isMediaFile(filename): else: return False + def listMediaFiles(path): if not dir or not os.path.isdir(path): return [] @@ -571,4 +602,56 @@ def listMediaFiles(path): elif isMediaFile(curFile): files.append(fullCurFile) - return files \ No newline at end of file + return files + + +def find_imdbid(dirName, nzbName): + imdbid = None + + nzbName = clean_nzbname(nzbName) + + logger.info('Attemping imdbID lookup for %s' % (nzbName)) + + # find imdbid in dirName + logger.info('Searching folder name for imdbID ...') + m = re.search('(tt\d{7})', dirName) + if m: + imdbid = m.group(1) + logger.info("Found movie id %s in directory" % imdbid) + return imdbid + + # find imdbid in nzbName + logger.info('Searching filename for imdbID ...') + m = re.search('(tt\d{7})', nzbName) + if m: + imdbid = m.group(1) + logger.info("Found imdbid %s in name" % imdbid) + return imdbid + + logger.info('Searching IMDB for imdbID ...') + m = re.search("^(.+)(\d{4})\W", nzbName) + if m: + title = m.group(1) + year = m.group(2) + + url = "http://www.omdbapi.com" + + logger.debug("Opening URL: %s" % url) + + try: + r = requests.get(url, params={'y': year, 't': title}) + except requests.ConnectionError: + logger.error("Unable to open URL %s" % url) + return + + results = r.json() + + try: + imdbid = results['imdbID'] + except: + pass + + if imdbid: + return imdbid + else: + logger.warning('Unable to find a imdbID for %s' % (nzbName)) \ No newline at end of file diff --git a/nzbtomedia/versionCheck.py b/nzbtomedia/versionCheck.py index bed46342..7a647e23 100644 --- a/nzbtomedia/versionCheck.py +++ b/nzbtomedia/versionCheck.py @@ -225,7 +225,7 @@ class GitUpdateManager(UpdateManager): branch = branch_info.strip().replace('refs/heads/', '', 1) if branch: nzbtomedia.NZBTOMEDIA_BRANCH = branch - return nzbtomedia.NZBTOMEDIA_BRANCH + return nzbtomedia.GIT_BRANCH def _check_github_for_update(self): """ @@ -273,7 +273,7 @@ class GitUpdateManager(UpdateManager): logger.log(u"git didn't return numbers for behind and ahead, not using it", logger.DEBUG) return - logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u", newest_commit = " + str(self._newest_commit_hash) + logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u" % (newest_commit)= " + str(self._newest_commit_hash) + u", num_commits_behind = " + str(self._num_commits_behind) + u", num_commits_ahead = " + str( self._num_commits_ahead), logger.DEBUG) @@ -405,7 +405,7 @@ class SourceUpdateManager(UpdateManager): # when _cur_commit_hash doesn't match anything _num_commits_behind == 100 self._num_commits_behind += 1 - logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u", newest_commit = " + str(self._newest_commit_hash) + logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u" % (newest_commit)= " + str(self._newest_commit_hash) + u", num_commits_behind = " + str(self._num_commits_behind), logger.DEBUG) def set_newest_text(self): diff --git a/tests/general.py b/tests/general.py index 618e1c52..8f9584d0 100644 --- a/tests/general.py +++ b/tests/general.py @@ -4,29 +4,10 @@ import nzbtomedia import TorrentToMedia from nzbtomedia.nzbToMediaUtil import find_download, clean_nzbname, listMediaFiles -os.environ['TR_TORRENT_DIR']="z:/downloads/complete/movie/The.Art.of.the.Steal.2013.LIMITED.1080p.BRRip.h264.AAC-RARBG" -os.environ['TR_TORRENT_NAME']="The.Art.of.the.Steal.2013.LIMITED.1080p.BRRip.h264.AAC-RARBG" -os.environ['TR_TORRENT_ID']="154206e6390a03bbf01e61f013e1a52494a52dfa" -os.environ['TR_TORRENT_HASH']="154206e6390a03bbf01e61f013e1a52494a52dfa" -#TorrentToMedia.main(sys.argv) -test = 'The.Art.of.the.Steal.2013.LIMITED.1080p.BRRip.h264.AAC-RARBG' -cleaned = clean_nzbname(test) - -# Initialize the config nzbtomedia.initialize() -dirName = 'Z:/complete/tv/' -test = listMediaFiles('Z:/complete/tv/') -for filename in test: - parentDir = os.path.dirname(filename) - if parentDir == dirName: - pass - clientAgent = nzbtomedia.NZB_CLIENTAGENT -nzbName = 'Anger.Management.S02E57.HDTV.x264-KILLERS' -#download_id = '51C9B415382894727C5C7D8442554D3AC08B390F' - -download_id = 'SABnzbd_nzo_uBYaGb' -if find_download(clientAgent, nzbName, download_id): +download_id = 'SABnzbd_nzo_qhoQ7m' +if find_download('sabnzbd', download_id): print 'found' else: print 'no luck'