From 0d725a78d684a5f6c4086be9c6395429b095aad1 Mon Sep 17 00:00:00 2001 From: echel0n Date: Fri, 25 Apr 2014 12:19:07 -0700 Subject: [PATCH] Resolves userscript issues. Converted userscript categories to new subsection format. --- TorrentToMedia.py | 42 ++++++++++++++++++++------- autoProcessMedia.cfg.spec | 37 ++++++++++++------------ nzbtomedia/__init__.py | 48 ++++++++++--------------------- nzbtomedia/nzbToMediaConfig.py | 52 ++++++++++++++++++++-------------- nzbtomedia/nzbToMediaUtil.py | 16 +++++++---- tests/general.py | 2 +- 6 files changed, 106 insertions(+), 91 deletions(-) diff --git a/TorrentToMedia.py b/TorrentToMedia.py index fc5bc042..20116621 100755 --- a/TorrentToMedia.py +++ b/TorrentToMedia.py @@ -9,12 +9,23 @@ import nzbtomedia from subprocess import Popen from nzbtomedia import logger, nzbToMediaDB +USER_SCRIPT_MEDIAEXTENSIONS = None +USER_SCRIPT = None +USER_SCRIPT_PARAM = None +USER_SCRIPT_SUCCESSCODES = None +USER_SCRIPT_CLEAN = None +USER_DELAY = None +USER_SCRIPT_RUNONCE = None + def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, clientAgent): status = 1 # 1 = failed | 0 = success root = 0 foundFile = 0 + global USER_DELAY, USER_SCRIPT, USER_SCRIPT_CLEAN, USER_SCRIPT_MEDIAEXTENSIONS, \ + USER_SCRIPT_PARAM, USER_SCRIPT_RUNONCE, USER_SCRIPT_SUCCESSCODES + if clientAgent != 'manual': logger.debug('Adding TORRENT download info for directory %s to database' % (inputDirectory)) @@ -64,6 +75,15 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, except: extract = 0 + if not "NONE" in nzbtomedia.USER_SCRIPT_CATEGORIES: + USER_SCRIPT_MEDIAEXTENSIONS = (section[inputCategory]["user_script_mediaExtensions"]) + USER_SCRIPT = section[inputCategory]["user_script_path"] + USER_SCRIPT_PARAM = (section[inputCategory]["user_script_param"]) + USER_SCRIPT_SUCCESSCODES = (section[inputCategory]["user_script_successCodes"]) + USER_SCRIPT_CLEAN = int(section[inputCategory]["user_script_clean"]) + USER_DELAY = int(section[inputCategory]["delay"]) + USER_SCRIPT_RUNONCE = int(section[inputCategory]["user_script_runOnce"]) + if clientAgent != 'manual': nzbtomedia.pause_torrent(clientAgent, inputHash, inputID, inputName) @@ -163,7 +183,7 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, result = 0 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.info("Processing user script %s." % (nzbtomedia.USER_SCRIPT)) + logger.info("Processing user script %s." % (USER_SCRIPT)) result = external_script(outputDestination, inputName, inputCategory) elif status != 0: logger.error("Something failed! Please check logs. Exiting") @@ -213,12 +233,12 @@ def external_script(outputDestination, torrentName, torrentLabel): filePath = nzbtomedia.os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) - if fileExtension in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS or "ALL" in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS: + if fileExtension in USER_SCRIPT_MEDIAEXTENSIONS or "ALL" in USER_SCRIPT_MEDIAEXTENSIONS: num_files = num_files + 1 - if nzbtomedia.USER_SCRIPT_RUNONCE == 1 and num_files > 1: # we have already run once, so just continue to get number of files. + if USER_SCRIPT_RUNONCE == 1 and num_files > 1: # we have already run once, so just continue to get number of files. continue - command = [nzbtomedia.USER_SCRIPT] - for param in nzbtomedia.USER_SCRIPT_PARAM: + command = [USER_SCRIPT] + for param in USER_SCRIPT_PARAM: if param == "FN": command.append(file) continue @@ -232,7 +252,7 @@ def external_script(outputDestination, torrentName, torrentLabel): command.append(torrentLabel) continue elif param == "DN": - if nzbtomedia.USER_SCRIPT_RUNONCE == 1: + if USER_SCRIPT_RUNONCE == 1: command.append(outputDestination) else: command.append(dirpath) @@ -247,7 +267,7 @@ def external_script(outputDestination, torrentName, torrentLabel): try: p = Popen(command) res = p.wait() - if str(res) in nzbtomedia.USER_SCRIPT_SUCCESSCODES: # Linux returns 0 for successful. + if str(res) in USER_SCRIPT_SUCCESSCODES: # Linux returns 0 for successful. logger.info("UserScript %s was successfull" % (command[0])) result = 0 else: @@ -261,20 +281,20 @@ def external_script(outputDestination, torrentName, torrentLabel): result = int(1) final_result = final_result + result - time.sleep(nzbtomedia.USER_DELAY) + time.sleep(USER_DELAY) num_files_new = 0 for dirpath, dirnames, filenames in os.walk(outputDestination): for file in filenames: filePath = nzbtomedia.os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) - if fileExtension in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS or nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS == "ALL": + if fileExtension in USER_SCRIPT_MEDIAEXTENSIONS or USER_SCRIPT_MEDIAEXTENSIONS == "ALL": num_files_new = num_files_new + 1 - if nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new == 0 and final_result == 0: + if USER_SCRIPT_CLEAN == int(1) and num_files_new == 0 and final_result == 0: logger.info("All files have been processed. Cleaning outputDirectory %s" % (outputDestination)) shutil.rmtree(outputDestination) - elif nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new != 0: + elif USER_SCRIPT_CLEAN == int(1) and num_files_new != 0: logger.info("%s files were processed, but %s still remain. outputDirectory will not be cleaned." % ( num_files, num_files_new)) return final_result diff --git a/autoProcessMedia.cfg.spec b/autoProcessMedia.cfg.spec index 409a8e8c..6f72b7dd 100644 --- a/autoProcessMedia.cfg.spec +++ b/autoProcessMedia.cfg.spec @@ -240,25 +240,26 @@ mac = 00:01:2e:2D:64:e1 [UserScript] - #Use user_script for uncategorized download? - #Set the categories to use external script, comma separated. + #Use user_script for uncategorized downloads + #Set the categories to use external script. #Use "UNCAT" to process non-category downloads, and "ALL" for all. Set to "NONE" to disable external script. - user_script_categories = NONE - #What extension do you want to process? Specify all the extension, or use "ALL" to process all files. - user_script_mediaExtensions = .mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg - #Specify the path to your custom script - user_script_path = /nzbToMedia/userscripts/script.sh - #Specify the argument(s) passed to script, comma separated in order. - #for example FP,FN,DN, TN, TL for file path (absolute file name with path), file name, absolute directory name (with path), Torrent Name, Torrent Label/Category. - #So the result is /media/test/script/script.sh FP FN DN TN TL. Add other arguments as needed eg -f, -r - user_script_param = FN - #Set user_script_runOnce = 0 to run for each file, or 1 to only run once (presumably on teh entire directory). - user_script_runOnce = 0 - #Specify the successcodes returned by the user script as a comma separated list. Linux default is 0 - user_script_successCodes = 0 - #Clean after? Note that delay function is used to prevent possible mistake :) Delay is intended as seconds - user_script_clean = 1 - delay = 120 + [[UNCAT]] + enabled = 0 + #What extension do you want to process? Specify all the extension, or use "ALL" to process all files. + user_script_mediaExtensions = .mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg + #Specify the path to your custom script + user_script_path = /nzbToMedia/userscripts/script.sh + #Specify the argument(s) passed to script, comma separated in order. + #for example FP,FN,DN, TN, TL for file path (absolute file name with path), file name, absolute directory name (with path), Torrent Name, Torrent Label/Category. + #So the result is /media/test/script/script.sh FP FN DN TN TL. Add other arguments as needed eg -f, -r + user_script_param = FN + #Set user_script_runOnce = 0 to run for each file, or 1 to only run once (presumably on teh entire directory). + user_script_runOnce = 0 + #Specify the successcodes returned by the user script as a comma separated list. Linux default is 0 + user_script_successCodes = 0 + #Clean after? Note that delay function is used to prevent possible mistake :) Delay is intended as seconds + user_script_clean = 1 + delay = 120 [ASCII] #Set convert =1 if you want to convert any "foreign" characters to ASCII before passing to SB/CP etc. Default is disabled (0). diff --git a/nzbtomedia/__init__.py b/nzbtomedia/__init__.py index 86eb5afd..dc8e80df 100644 --- a/nzbtomedia/__init__.py +++ b/nzbtomedia/__init__.py @@ -85,7 +85,6 @@ TORRENT_CLIENTAGENT = None TORRENT_CLASS = None USELINK = None OUTPUTDIRECTORY = None -CATEGORIES = [] NOFLATTEN = [] DELETE_ORIGINAL = None @@ -103,15 +102,15 @@ DELUGEPORT = None DELUGEUSR = None DELUGEPWD = None -EXTCONTAINER = None -COMPRESSEDCONTAINER = None -MEDIACONTAINER = None -AUDIOCONTAINER = None -METACONTAINER = None -MINSAMPLESIZE = None -SAMPLEIDS = None +EXTCONTAINER = [] +COMPRESSEDCONTAINER = [] +MEDIACONTAINER = [] +AUDIOCONTAINER = [] +METACONTAINER = [] SECTIONS = [] +CATEGORIES = [] +USER_SCRIPT_CATEGORIES = [] TRANSCODE = None FFMPEG_PATH = None @@ -131,15 +130,6 @@ FFMPEG = None FFPROBE = None NICENESS = None -USER_SCRIPT_CATEGORIES = None -USER_SCRIPT_MEDIAEXTENSIONS = None -USER_SCRIPT = None -USER_SCRIPT_PARAM = None -USER_SCRIPT_SUCCESSCODES = None -USER_SCRIPT_CLEAN = None -USER_DELAY = None -USER_SCRIPT_RUNONCE = None - PASSWORDSFILE = None __INITIALIZED__ = False @@ -150,14 +140,13 @@ def initialize(section=None): NZBTOMEDIA_BRANCH, NZBTOMEDIA_VERSION, NEWEST_VERSION, NEWEST_VERSION_STRING, VERSION_NOTIFY, SYS_ARGV, CFG, \ SABNZB_NO_OF_ARGUMENTS, SABNZB_0717_NO_OF_ARGUMENTS, CATEGORIES, TORRENT_CLIENTAGENT, USELINK, OUTPUTDIRECTORY, NOFLATTEN, \ UTORRENTPWD, UTORRENTUSR, UTORRENTWEBUI, DELUGEHOST, DELUGEPORT, DELUGEUSR, DELUGEPWD, TRANSMISSIONHOST, TRANSMISSIONPORT, \ - TRANSMISSIONPWD, TRANSMISSIONUSR, COMPRESSEDCONTAINER, MEDIACONTAINER, METACONTAINER, MINSAMPLESIZE, SAMPLEIDS, \ - SECTIONS, USER_SCRIPT_CATEGORIES, __INITIALIZED__, AUTO_UPDATE, APP_FILENAME, USER_DELAY, USER_SCRIPT_RUNONCE, \ - APP_NAME, USER_SCRIPT_MEDIAEXTENSIONS, USER_SCRIPT, USER_SCRIPT_PARAM, USER_SCRIPT_SUCCESSCODES, USER_SCRIPT_CLEAN, \ - TRANSCODE, GIT_PATH, GIT_USER, GIT_BRANCH, GIT_REPO, SYS_ENCODING, NZB_CLIENTAGENT, SABNZBDHOST, SABNZBDPORT, SABNZBDAPIKEY, \ + TRANSMISSIONPWD, TRANSMISSIONUSR, COMPRESSEDCONTAINER, MEDIACONTAINER, METACONTAINER, SECTIONS, USER_SCRIPT_CATEGORIES, \ + __INITIALIZED__, AUTO_UPDATE, APP_FILENAME, USER_DELAY, APP_NAME, TRANSCODE, GIT_PATH, GIT_USER, \ + GIT_BRANCH, GIT_REPO, SYS_ENCODING, NZB_CLIENTAGENT, SABNZBDHOST, SABNZBDPORT, SABNZBDAPIKEY, \ DUPLICATE, IGNOREEXTENSIONS, OUTPUTVIDEOEXTENSION, OUTPUTVIDEOCODEC, OUTPUTVIDEOPRESET, OUTPUTVIDEOFRAMERATE, LOG_DB, \ OUTPUTVIDEOBITRATE, OUTPUTAUDIOCODEC, OUTPUTAUDIOBITRATE, OUTPUTSUBTITLECODEC, OUTPUTFASTSTART, OUTPUTQUALITYPERCENT, \ - NICENESS, LOG_DEBUG, FORCE_CLEAN, FFMPEG_PATH, FFMPEG, FFPROBE, AUDIOCONTAINER, EXTCONTAINER, TORRENT_CLASS, DELETE_ORIGINAL,\ - PASSWORDSFILE + NICENESS, LOG_DEBUG, FORCE_CLEAN, FFMPEG_PATH, FFMPEG, FFPROBE, AUDIOCONTAINER, EXTCONTAINER, TORRENT_CLASS, \ + DELETE_ORIGINAL, PASSWORDSFILE if __INITIALIZED__: return False @@ -323,18 +312,11 @@ def initialize(section=None): logger.warning("Failed to locate ffprobe, video corruption detection disabled!") logger.warning("Install ffmpeg with x264 support to enable this feature ...") - USER_SCRIPT_CATEGORIES = CFG["UserScript"]["user_script_categories"] - if not "NONE" in USER_SCRIPT_CATEGORIES: - USER_SCRIPT_MEDIAEXTENSIONS = (CFG["UserScript"]["user_script_mediaExtensions"]) - USER_SCRIPT = CFG["UserScript"]["user_script_path"] - USER_SCRIPT_PARAM = (CFG["UserScript"]["user_script_param"]) - USER_SCRIPT_SUCCESSCODES = (CFG["UserScript"]["user_script_successCodes"]) - USER_SCRIPT_CLEAN = int(CFG["UserScript"]["user_script_clean"]) - USER_DELAY = int(CFG["UserScript"]["delay"]) - USER_SCRIPT_RUNONCE = int(CFG["UserScript"]["user_script_runOnce"]) + # userscript + map(USER_SCRIPT_CATEGORIES.append, ([subsections[0] for subsections in CFG['UserScript'].items()])) # check for script-defied section and if None set to allow sections - SECTIONS = CFG[tuple(x for x in CFG if CFG[x].sections) if not section else (section,)] + SECTIONS = CFG[tuple(x for x in CFG if CFG[x].sections and CFG[x].isenabled()) if not section else (section,)] map(CATEGORIES.extend,([subsection.sections for section,subsection in SECTIONS.items()])) CATEGORIES = list(set(CATEGORIES)) diff --git a/nzbtomedia/nzbToMediaConfig.py b/nzbtomedia/nzbToMediaConfig.py index ce162dfb..29fa49f9 100644 --- a/nzbtomedia/nzbToMediaConfig.py +++ b/nzbtomedia/nzbToMediaConfig.py @@ -10,18 +10,21 @@ class Section(configobj.Section): def isenabled(section): # checks if subsection enabled, returns true/false if subsection specified otherwise returns true/false in {} if not section.sections: - if int(section['enabled']) == 1: + try: + value = list(ConfigObj.find_key(section, 'enabled'))[0] + except:value = 0 + if int(value) == 1: return section else: to_return = copy.deepcopy(section) for section_name, subsections in to_return.items(): - if subsections.sections: - for subsection in subsections: - if not int(subsections[subsection]['enabled']) == 1: - del subsections[subsection] - else: - if not int(subsections['enabled']) == 1: - del to_return[section_name] + for subsection in subsections: + try: + value = list(ConfigObj.find_key(subsections, 'enabled'))[0] + except:value = 0 + + if int(value) != 1: + del to_return[section_name][subsection] # cleanout empty sections and subsections for key in [k for (k, v) in to_return.items() if not v]: @@ -32,7 +35,11 @@ class Section(configobj.Section): def findsection(section, key): to_return = copy.deepcopy(section) for subsection in to_return: - if key not in to_return[subsection]: + try: + value = list(ConfigObj.find_key(to_return[subsection], key))[0] + except:value = None + + if not value: del to_return[subsection] # cleanout empty sections and subsections @@ -74,6 +81,19 @@ class ConfigObj(configobj.ConfigObj, Section): super(configobj.ConfigObj, self).__init__(*args, **kw) self.interpolation = False + @staticmethod + def find_key(node, kv): + if isinstance(node, list): + for i in node: + for x in ConfigObj.find_key(i, kv): + yield x + elif isinstance(node, dict): + if kv in node: + yield node[kv] + for j in node.values(): + for x in ConfigObj.find_key(j, kv): + yield x + @staticmethod def migrate(): global CFG_NEW, CFG_OLD @@ -152,19 +172,7 @@ class ConfigObj(configobj.ConfigObj, Section): values.pop(option) # remove any options that we no longer need so they don't migrate into our new config - def find_key(node, kv): - if isinstance(node, list): - for i in node: - for x in find_key(i, kv): - yield x - elif isinstance(node, dict): - if kv in node: - yield node[kv] - for j in node.values(): - for x in find_key(j, kv): - yield x - - if not list(find_key(CFG_NEW, option)): + if not list(ConfigObj.find_key(CFG_NEW, option)): values.pop(option) return values diff --git a/nzbtomedia/nzbToMediaUtil.py b/nzbtomedia/nzbToMediaUtil.py index daba27e9..f1fd8294 100644 --- a/nzbtomedia/nzbToMediaUtil.py +++ b/nzbtomedia/nzbToMediaUtil.py @@ -436,13 +436,17 @@ def getDirs(section, subsection): os.path.isdir(os.path.join(path, o))]) return folders - watch_dir = nzbtomedia.CFG[section][subsection]["watch_dir"] - if os.path.exists(watch_dir): - to_return.extend(processDir(watch_dir)) + try: + watch_dir = nzbtomedia.CFG[section][subsection]["watch_dir"] + if os.path.exists(watch_dir): + to_return.extend(processDir(watch_dir)) + except:pass - outputDirectory = os.path.join(nzbtomedia.OUTPUTDIRECTORY, subsection) - if os.path.exists(outputDirectory): - to_return.extend(processDir(outputDirectory)) + try: + outputDirectory = os.path.join(nzbtomedia.OUTPUTDIRECTORY, subsection) + if os.path.exists(outputDirectory): + to_return.extend(processDir(outputDirectory)) + except:pass if not to_return: logger.debug("No directories identified in %s:%s for post-processing" % (section,subsection)) diff --git a/tests/general.py b/tests/general.py index 4ff867f2..89468dc7 100644 --- a/tests/general.py +++ b/tests/general.py @@ -8,6 +8,6 @@ from nzbtomedia.nzbToMediaUtil import get_downloadInfo # Initialize the config nzbtomedia.initialize() -test = nzbtomedia.CFG['SickBeard','NzbDrone']['tv'] +test = nzbtomedia.CFG['SickBeard','NzbDrone']['tv'].isenabled() section = nzbtomedia.CFG.findsection('tv').isenabled() print section \ No newline at end of file