diff --git a/TorrentToMedia.py b/TorrentToMedia.py index 9b2c6369..33879098 100755 --- a/TorrentToMedia.py +++ b/TorrentToMedia.py @@ -30,58 +30,42 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID): status = int(1) # 1 = failed | 0 = success root = int(0) video = int(0) - video2 = int(0) foundFile = int(0) extracted_folder = [] extractionSuccess = False copy_list = [] - useLink = useLink_in file = None - delugeClient = "" - utorrentClass = "" - TransmissionClass = "" - Logger.debug("MAIN: Received Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory) - inputDirectory, inputName, inputCategory, root = category_search(inputDirectory, inputName, inputCategory, root, categories) # Confirm the category by parsing directory structure + inputDirectory, inputName, inputCategory, root, single = category_search(inputDirectory, inputName, inputCategory, root, categories) # Confirm the category by parsing directory structure Logger.debug("MAIN: Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory) - if config().issubsection(inputCategory,["SickBeard","NzbDrone"]): - Logger.info("MAIN: Calling autoProcessTV to post-process: %s",inputName) - result = autoProcessTV().processEpisode(inputDirectory, inputName, 0, clientAgent=clientAgent, inputCategory=inputCategory) - if result != 0: - Logger.info("MAIN: A problem was reported in the autoProcessTV script.") - Logger.info("MAIN: All done.") - sys.exit() + TorrentClass = create_torrent_class(clientAgent, inputHash) + pause_torrent(clientAgent, TorrentClass, inputHash, inputID, inputName) + + processCategories = list(chain.from_iterable(subsections.values())) outputDestination = "" - for category in categories: - if category == inputCategory: - if os.path.basename(inputDirectory) == inputName and os.path.isdir(inputDirectory): - Logger.info("MAIN: Download is a directory") - outputDestination = os.path.normpath(os.path.join(outputDirectory, category, safeName(inputName))) - else: - Logger.info("MAIN: Download is not a directory") - outputDestination = os.path.normpath(os.path.join(outputDirectory, category, os.path.splitext(safeName(inputName))[0])) - Logger.info("MAIN: Output directory set to: %s", outputDestination) - break - else: - continue + if inputCategory == "": + inputCategory = "UNCAT" + outputDestination = os.path.normpath(os.path.join(outputDirectory, inputCategory, safeName(inputName))) + Logger.info("MAIN: Output directory set to: %s", outputDestination) - if outputDestination == "": - if inputCategory == "": - inputCategory = "UNCAT" - if os.path.basename(inputDirectory) == inputName and os.path.isdir(inputDirectory): - Logger.info("MAIN: Download is a directory") - outputDestination = os.path.normpath(os.path.join(outputDirectory, inputCategory, safeName(inputName))) - else: - Logger.info("MAIN: Download is not a directory") - outputDestination = os.path.normpath(os.path.join(outputDirectory, inputCategory, os.path.splitext(safeName(inputName))[0])) - Logger.info("MAIN: Output directory set to: %s", outputDestination) + if config()["SickBeard"].issubsection(inputCategory): + Torrent_NoLink = int(config()["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0 + if Torrent_NoLink == 1: + Logger.info("MAIN: Calling autoProcessTV to post-process: %s",inputName) + result = autoProcessTV().processEpisode(inputDirectory, inputName, 0, clientAgent=clientAgent, inputCategory=inputCategory) + if result != 0: + Logger.info("MAIN: A problem was reported in the autoProcessTV script.") + resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName) + cleanup_output(inputCategory, processCategories, result, outputDestination) + Logger.info("MAIN: All done.") + sys.exit() - processOnly = list(chain.from_iterable(subsections.values())) + processOnly = list(set(chain.from_iterable(subsections.values()))) if not "NONE" in user_script_categories: # if None, we only process the 5 listed. if "ALL" in user_script_categories: # All defined categories processOnly = categories @@ -92,53 +76,23 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID): Logger.info("MAIN: All done.") sys.exit() - # Hardlink solution for uTorrent, need to implent support for deluge, transmission - if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash: - if clientAgent == 'utorrent': - try: - Logger.debug("MAIN: Connecting to %s: %s", clientAgent, uTorrentWEBui) - utorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD) - except: - Logger.exception("MAIN: Failed to connect to uTorrent") - - if clientAgent == 'transmission': - try: - Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, TransmissionHost, TransmissionPort) - TransmissionClass = TransmissionClient(TransmissionHost, TransmissionPort, TransmissionUSR, TransmissionPWD) - except: - Logger.exception("MAIN: Failed to connect to Transmission") - - if clientAgent == 'deluge': - try: - Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, DelugeHost, DelugePort) - delugeClient = DelugeClient() - delugeClient.connect(host = DelugeHost, port = DelugePort, username = DelugeUSR, password = DelugePWD) - except: - Logger.exception("MAIN: Failed to connect to deluge") - - # if we are using links with uTorrent it means we need to pause it in order to access the files - Logger.debug("MAIN: Stoping torrent %s in %s while processing", inputName, clientAgent) - if clientAgent == 'utorrent' and utorrentClass != "": - utorrentClass.stop(inputHash) - if clientAgent == 'transmission' and TransmissionClass !="": - TransmissionClass.stop_torrent(inputID) - if clientAgent == 'deluge' and delugeClient != "": - delugeClient.core.pause_torrent([inputID]) - time.sleep(5) # Give Torrent client some time to catch up with the change - Logger.debug("MAIN: Scanning files in directory: %s", inputDirectory) - if config().issubsection(inputCategory, "HeadPhones"): - noFlatten.extend(list(chain.from_iterable(config().get_subsections("HeadPhones")))) # Make sure we preserve folder structure for HeadPhones. + if config()["HeadPhones"].issubsection(inputCategory): + noFlatten.extend(config()["HeadPhones"].sections) # Make sure we preserve folder structure for HeadPhones. outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards. now = datetime.datetime.now() + if single: inputDirectory,filename = os.path.split(inputDirectory) for dirpath, dirnames, filenames in os.walk(inputDirectory): + if single: + dirnames[:] = [] + filenames[:] = [filenames] # we just want to work with this one file if single = True Logger.debug("MAIN: 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) - if inputCategory in noFlatten: + if inputCategory in noFlatten and not single: newDir = dirpath # find the full path newDir = newDir.replace(inputDirectory, "") #find the extra-depth directory if len(newDir) > 0 and newDir[0] == "/": @@ -159,7 +113,8 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID): continue # This file does not match the Torrent name, skip it if root == 2: - Logger.debug("MAIN: Looking for files with modified/created dates less than 5 minutes old.") + if foundFile == int(0): + Logger.debug("MAIN: Looking for files with modified/created dates less than 5 minutes old.") mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(os.path.join(dirpath, file))) ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(os.path.join(dirpath, file))) if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): @@ -169,83 +124,58 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID): else: continue # This file has not been recently moved or created, skip it - if fileExtension in mediaContainer: # If the file is a video file - if is_sample(filePath, inputName, minSampleSize, SampleIDs) and not config().issubsection(inputCategory, ["HeadPhones"]): # Ignore samples - Logger.info("MAIN: Ignoring sample file: %s ", filePath) - continue - else: - video = video + 1 - Logger.info("MAIN: Found media file %s in %s", fileExtension, filePath) + if fileExtension in mediaContainer and is_sample(filePath, inputName, minSampleSize, SampleIDs) and not config()["HeadPhones"].issubsection(inputCategory): # Ignore samples + Logger.info("MAIN: Ignoring sample file: %s ", filePath) + continue + + if fileExtension in compressedContainer: + if (config()["SickBeard"].issubsection(inputCategory) and config()["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination"): + # find part numbers in second "extension" from right, if we have more than 1 compressed file in the same directory. + 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("MAIN: Found primary part of a multi-part archive %s. Extracting", file) + else: + Logger.debug("MAIN: Found part %s of a multi-part archive %s. Ignoring", part, file) + continue + Logger.info("MAIN: Found compressed archive %s for file %s", fileExtension, filePath) try: - copy_link(filePath, targetDirectory, useLink, outputDestination) - copy_list.append([filePath, os.path.join(outputDestination, file)]) + 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.exception("MAIN: Failed to link file: %s", file) - elif fileExtension in metaContainer: - Logger.info("MAIN: Found metadata file %s for file %s", fileExtension, filePath) - try: - copy_link(filePath, targetDirectory, useLink, outputDestination) - copy_list.append([filePath, os.path.join(outputDestination, file)]) - except: - Logger.exception("MAIN: Failed to link file: %s", file) - continue - elif fileExtension in compressedContainer: - # find part numbers in second "extension" from right, if we have more than 1 compressed file in the same directory. - 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("MAIN: Found primary part of a multi-part archive %s. Extracting", file) - else: - Logger.debug("MAIN: Found part %s of a multi-part archive %s. Ignoring", part, file) - continue - Logger.info("MAIN: 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.exception("MAIN: Extraction failed for: %s", file) - continue - elif not config().issubsection(inputCategory,['CouchPotato','SickBeard','NzbDrone']): #process all for non-video categories. - Logger.info("MAIN: Found file %s for category %s", filePath, inputCategory) + Logger.exception("MAIN: Extraction failed for: %s", file) + continue + + try: copy_link(filePath, targetDirectory, useLink, outputDestination) copy_list.append([filePath, os.path.join(outputDestination, file)]) - continue - else: - Logger.debug("MAIN: Ignoring unknown filetype %s for file %s", fileExtension, filePath) - continue + except: + Logger.exception("MAIN: Failed to link file: %s", file) outputDestination = outputDestinationMaster # Reset here. if not inputCategory in noFlatten: #don't flatten hp in case multi cd albums, and we need to copy this back later. flatten(outputDestination) # Now check if video files exist in destination: - if config().issubsection(inputCategory,["CouchPotato","SickBeard","NzbDrone"]): + if config()["SickBeard","NzbDrone", "CouchPotato"].issubsection(inputCategory): for dirpath, dirnames, filenames in os.walk(outputDestination): for file in filenames: filePath = os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in mediaContainer: # If the file is a video file - if is_sample(filePath, inputName, minSampleSize, SampleIDs): - Logger.debug("MAIN: Removing sample file: %s", filePath) - os.unlink(filePath) # remove samples - else: - Logger.debug("MAIN: Found media file: %s", filePath) - video2 = video2 + 1 - else: - Logger.debug("MAIN: File %s is not a media file", filePath) - if video2 >= video and video2 > int(0): # Check that all video files were moved - Logger.debug("MAIN: Found %s media files", str(video2)) + Logger.debug("MAIN: Found media file: %s", filePath) + video += 1 + if video > int(0): # Check that media files exist + Logger.debug("MAIN: Found %s media files", str(video)) status = int(0) else: - Logger.debug("MAIN: Found %s media files in output. %s were found in input", str(video2), str(video)) - - processCategories = list(chain.from_iterable(subsections.values())) + Logger.warning("MAIN: Found no media files in output.", str(video)) if (inputCategory in user_script_categories and not "NONE" in user_script_categories) or ("ALL" in user_script_categories and not inputCategory in processCategories): Logger.info("MAIN: Processing user script %s.", user_script) result = external_script(outputDestination,inputName,inputCategory) - elif status == int(0) or (config().issubsection(inputCategory,['HeadPhones','Mylar','Gamez'])): # if movies linked/extracted or for other categories. + elif status == int(0) or (config()['HeadPhones','Mylar','Gamez'].issubsection(inputCategory)): # if movies linked/extracted or for other categories. Logger.debug("MAIN: Calling autoProcess script for successful download.") status = int(0) # hp, my, gz don't support failed. else: @@ -253,52 +183,97 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID): sys.exit(-1) result = 0 - if config().issubsection(inputCategory,['CouchPotato']): + if config()['CouchPotato'].issubsection(inputCategory): Logger.info("MAIN: Calling CouchPotato:" + inputCategory + " to post-process: %s", inputName) download_id = inputHash result = autoProcessMovie().process(outputDestination, inputName, status, clientAgent, download_id, inputCategory) - elif config().issubsection(inputCategory,['SickBeard']): + elif config()['SickBeard'].issubsection(inputCategory): Logger.info("MAIN: Calling Sick-Beard:" + inputCategory + " to post-process: %s", inputName) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) - elif config().issubsection(inputCategory,['NzbDrone']): + elif config()['NzbDrone'].issubsection(inputCategory): Logger.info("MAIN: Calling NzbDrone:" + inputCategory + " to post-process: %s", inputName) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) - elif config().issubsection(inputCategory,['HeadPhones']): + elif config()['HeadPhones'].issubsection(inputCategory): Logger.info("MAIN: Calling HeadPhones:" + inputCategory + " to post-process: %s", inputName) result = autoProcessMusic().process(inputDirectory, inputName, status, clientAgent, inputCategory) - elif config().issubsection(inputCategory,['Mylar']): + elif config()['Mylar'].issubsection(inputCategory): Logger.info("MAIN: Calling Mylar:" + inputCategory + " to post-process: %s", inputName) result = autoProcessComics().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) - elif config().issubsection(inputCategory,['Gamez']): + elif config()['Gamez'].issubsection(inputCategory): Logger.info("MAIN: Calling Gamez:" + inputCategory + " to post-process: %s", inputName) result = autoProcessGames().process(outputDestination, inputName, status, clientAgent, inputCategory) if result == 1: Logger.info("MAIN: A problem was reported in the autoProcess* script. If torrent was paused we will resume seeding") + resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName) + cleanup_output(inputCategory, processCategories, result, outputDestination) + Logger.info("MAIN: All done.") + +def create_torrent_class(clientAgent, inputHash): + # Hardlink solution for Torrents + TorrentClass = "" + if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash: + if clientAgent == 'utorrent': + try: + Logger.debug("MAIN: Connecting to %s: %s", clientAgent, uTorrentWEBui) + TorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD) + except: + Logger.exception("MAIN: Failed to connect to uTorrent") + + if clientAgent == 'transmission': + try: + Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, TransmissionHost, TransmissionPort) + TorrentClass = TransmissionClient(TransmissionHost, TransmissionPort, TransmissionUSR, TransmissionPWD) + except: + Logger.exception("MAIN: Failed to connect to Transmission") + + if clientAgent == 'deluge': + try: + Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, DelugeHost, DelugePort) + TorrentClass = DelugeClient() + TorrentClass.connect(host = DelugeHost, port = DelugePort, username = DelugeUSR, password = DelugePWD) + except: + Logger.exception("MAIN: 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("MAIN: Stoping torrent %s in %s while processing", inputName, clientAgent) + if clientAgent == 'utorrent' and TorrentClass != "": + TorrentClass.stop(inputHash) + 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: # Delete torrent and torrentdata from Torrent client if processing was successful. - if (deleteOriginal == 1 and result != 1) or useLink == 'move': # added uselink = move, if we move files, nothing to resume seeding. + if (int(config()["Torrent"]["deleteOriginal"]) is 1 and result != 1) or useLink == 'move': # if we move files, nothing to resume seeding. Logger.debug("MAIN: Deleting torrent %s from %s", inputName, clientAgent) - if clientAgent == 'utorrent' and utorrentClass != "": - utorrentClass.removedata(inputHash) - utorrentClass.remove(inputHash) - if clientAgent == 'transmission' and TransmissionClass !="": - TransmissionClass.remove_torrent(inputID, True) - if clientAgent == 'deluge' and delugeClient != "": - delugeClient.core.remove_torrent(inputID, True) + if clientAgent == 'utorrent' and TorrentClass != "": + TorrentClass.removedata(inputHash) + TorrentClass.remove(inputHash) + 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("MAIN: Starting torrent %s in %s", inputName, clientAgent) - if clientAgent == 'utorrent' and utorrentClass != "": - utorrentClass.start(inputHash) - if clientAgent == 'transmission' and TransmissionClass !="": - TransmissionClass.start_torrent(inputID) - if clientAgent == 'deluge' and delugeClient != "": - delugeClient.core.resume_torrent([inputID]) + if clientAgent == 'utorrent' and TorrentClass != "": + TorrentClass.start(inputHash) + if clientAgent == 'transmission' and TorrentClass !="": + TorrentClass.start_torrent(inputID) + if clientAgent == 'deluge' and TorrentClass != "": + TorrentClass.core.resume_torrent([inputID]) time.sleep(5) - #cleanup + +def cleanup_output(inputCategory, processCategories, result, outputDestination): if inputCategory in processCategories and result == 0 and os.path.isdir(outputDestination): num_files_new = int(0) file_list = [] @@ -307,18 +282,17 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID): filePath = os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in mediaContainer or fileExtension in metaContainer: - num_files_new = num_files_new + 1 + num_files_new += 1 file_list.append(file) - if num_files_new == int(0) or forceClean == 1: + if num_files_new is 0 or int(config()["Torrent"]["forceClean"]) is 1: Logger.info("All files have been processed. Cleaning outputDirectory %s", outputDestination) shutil.rmtree(outputDestination) else: Logger.info("outputDirectory %s still contains %s media and/or meta files. This directory will not be removed.", outputDestination, num_files_new) for item in file_list: Logger.debug("media/meta file found: %s", item) - Logger.info("MAIN: All done.") -def external_script(outputDestination,torrentName,torrentLabel): +def external_script(outputDestination, torrentName, torrentLabel): final_result = int(0) # start at 0. num_files = int(0) @@ -407,7 +381,7 @@ if __name__ == "__main__": # EXAMPLE VALUES: clientAgent = config()["Torrent"]["clientAgent"] # utorrent | deluge | transmission | rtorrent | other - useLink_in = config()["Torrent"]["useLink"] # no | hard | sym + useLink = config()["Torrent"]["useLink"] # no | hard | sym outputDirectory = config()["Torrent"]["outputDirectory"] # /abs/path/to/complete/ categories = (config()["Torrent"]["categories"]) # music,music_videos,pictures,software noFlatten = (config()["Torrent"]["noFlatten"]) @@ -426,17 +400,15 @@ if __name__ == "__main__": DelugeUSR = config()["Torrent"]["DelugeUSR"] # mysecretusr DelugePWD = config()["Torrent"]["DelugePWD"] # mysecretpwr - deleteOriginal = int(config()["Torrent"]["deleteOriginal"]) # 0 - forceClean = int(config()["Torrent"]["forceClean"]) # 0 - - compressedContainer = (config()["Extensions"]["compressedExtensions"]) # .zip,.rar,.7z - mediaContainer = (config()["Extensions"]["mediaExtensions"]) # .mkv,.avi,.divx - metaContainer = (config()["Extensions"]["metaExtensions"]) # .nfo,.sub,.srt + compressedContainer = (config()["Extensions"]["compressedExtensions"]) # .zip,.rar,.7z + mediaContainer = (config()["Extensions"]["mediaExtensions"]) # .mkv,.avi,.divx + metaContainer = (config()["Extensions"]["metaExtensions"]) # .nfo,.sub,.srt minSampleSize = int(config()["Extensions"]["minSampleSize"]) # 200 (in MB) - SampleIDs = (config()["Extensions"]["SampleIDs"]) # sample,-s. + SampleIDs = (config()["Extensions"]["SampleIDs"]) # sample,-s. - subsections = config().get_subsections(["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"]) - categories += list(chain.from_iterable(subsections.values())) + sections = ("CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez") + subsections = config()[sections].subsections + categories += config()[sections].sections user_script_categories = config()["UserScript"]["user_script_categories"] # NONE if not "NONE" in user_script_categories: @@ -463,12 +435,12 @@ if __name__ == "__main__": # check if this is a manual run if inputDirectory is None: - for section, subsection in subsections.iteritems(): + for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section, category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) - Logger.info("MAIN: TorrentToMedia running %s:%s as a manual run...", section, category) for dirName in dirNames: + Logger.info("MAIN: TorrentToMedia running %s:%s as a manual run for folder %s ...", section, category, dirName) main(dirName, os.path.basename(dirName), category, inputHash, inputID) else: Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...",section, section, category) diff --git a/nzbToCouchPotato.py b/nzbToCouchPotato.py index 63b680d0..c56b1811 100755 --- a/nzbToCouchPotato.py +++ b/nzbToCouchPotato.py @@ -230,22 +230,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: else: result = 0 - # init sub-sections - subsections = config().get_subsections(["CouchPotato"]) - + subsections = config()["CouchPotato"].subsections Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section, category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) for dirName in dirNames: - Logger.info("MAIN: nzbToCouchPotato running %s:%s as a manual run...", section, category) + Logger.info("MAIN: nzbToCouchPotato running %s:%s as a manual run on folder %s ...", section, category, dirName) results = autoProcessMovie().process(dirName, os.path.basename(dirName), 0, inputCategory=category) if results != 0: result = results - Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category) + Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) else: - Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, section, category) + Logger.info("MAIN: nzbToCouchPotato %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) if result == 0: Logger.info("MAIN: The autoProcessMovie script completed successfully.") diff --git a/nzbToGamez.py b/nzbToGamez.py index 52356478..7fcffe48 100755 --- a/nzbToGamez.py +++ b/nzbToGamez.py @@ -165,22 +165,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: else: result = 0 - # init sub-sections - subsections = config().get_subsections(["Gamez"]) - + subsections = config()["Gamez"].subsections Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section, category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) for dirName in dirNames: - Logger.info("MAIN: nzbToGamez running %s:%s as a manual run...", section, category) + Logger.info("MAIN: nzbToGamez running %s:%s as a manual run on folder %s ...", section, category, dirName) results = autoProcessGames().process(dirName, os.path.basename(dirName), 0, inputCategory=category) if results != 0: result = results - Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category) + Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) else: - Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, section, category) + Logger.info("MAIN: nzbToGamez %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) if result == 0: Logger.info("MAIN: The autoProcessGames script completed successfully.") diff --git a/nzbToHeadPhones.py b/nzbToHeadPhones.py index 03fb5f82..77c6efc2 100755 --- a/nzbToHeadPhones.py +++ b/nzbToHeadPhones.py @@ -175,22 +175,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: else: result = 0 - # init sub-sections - subsections = config().get_subsections(["HeadPhones"]) - + subsections = config()["HeadPhones"].subsections Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section, category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) for dirName in dirNames: - Logger.info("MAIN: nzbToHeadPhones running %s:%s as a manual run...", section, category) + Logger.info("MAIN: nzbToHeadPhones running %s:%s as a manual run on folder %s ...", section, category, dirName) results = autoProcessMusic().process(dirName, os.path.basename(dirName), 0, inputCategory=category) if results != 0: result = results - Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category) + Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) else: - Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, section, category) + Logger.info("MAIN: nzbToHeadPhones %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) if result == 0: Logger.info("MAIN: The autoProcessMusic script completed successfully.") diff --git a/nzbToMedia.py b/nzbToMedia.py index e468c2a3..c61a0ee0 100755 --- a/nzbToMedia.py +++ b/nzbToMedia.py @@ -317,19 +317,19 @@ from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_ # post-processing def process(nzbDir, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None): - if section in ["CouchPotato"]: + if config()["CouchPotato"].issubsection(inputCategory): Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName) return autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory) - elif section in ["SickBeard", "NzbDrone"]: + elif config()["SickBeard", "NzbDrone"].issubsection(inputCategory): Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName) return autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) - elif section in ["HeadPhones"]: + elif config()["HeadPhones"].issubsection(inputCategory): Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName) return autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory) - elif section in ["Mylar"]: + elif config()["Mylar"].issubsection(inputCategory): Logger.info("MAIN: Calling Mylar to post-process: %s", inputName) return autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) - elif section in ["Gamez"]: + elif config()["Gamez"].issubsection(inputCategory): Logger.info("MAIN: Calling Gamez to post-process: %s", inputName) return autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory) else: @@ -443,21 +443,20 @@ else: result = 0 # init sub-sections - subsections = config().get_subsections(["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"]) - + subsections = config()["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"].subsections Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section, category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) for dirName in dirNames: - Logger.info("MAIN: nzbToMedia running %s:%s as a manual run...", section, category) + Logger.info("MAIN: nzbToMedia running %s:%s as a manual run on folder %s ...", section, category, dirName) results = process(dirName, os.path.basename(dirName), 0, inputCategory=category) if results != 0: result = results - Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, subsection) + Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category) else: - Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section,section, category) + Logger.info("MAIN: nzbToMedia %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) if result == 0: Logger.info("MAIN: The nzbToMedia script completed successfully.") diff --git a/nzbToMylar.py b/nzbToMylar.py index af238031..97840432 100755 --- a/nzbToMylar.py +++ b/nzbToMylar.py @@ -167,22 +167,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: else: result = 0 - # init sub-sections - subsections = config().get_subsections(["Mylar"]) - + subsections = config()["Mylar"].subsections Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section, category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) for dirName in dirNames: - Logger.info("MAIN: nzbToMylar running %s:%s as a manual run...", section, category) + Logger.info("MAIN: nzbToMylar running %s:%s as a manual run on folder %s ...", section, category, dirName) results = autoProcessComics().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category) if results != 0: result = results - Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category) + Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) else: - Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, section, category) + Logger.info("MAIN: nzbToMylar %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) if result == 0: Logger.info("MAIN: The autoProcessComics script completed successfully.") diff --git a/nzbToNzbDrone.py b/nzbToNzbDrone.py index 09b2d366..c76c09b7 100755 --- a/nzbToNzbDrone.py +++ b/nzbToNzbDrone.py @@ -196,22 +196,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: else: result = 0 - # init sub-sections - subsections = config().get_subsections(["NzbDrone"]) - + subsections = config()["NzbDrone"].subsections Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section, category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) for dirName in dirNames: - Logger.info("MAIN: nzbToNzbDrone running %s:%s as a manual run...", section, category) + Logger.info("MAIN: nzbToNzbDrone running %s:%s as a manual run on folder %s ...", section, category, dirName) results = autoProcessTV().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category) if results != 0: result = results - Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category) + Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) else: - Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section,section, category) + Logger.info("MAIN: nzbToNzbDrone %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) if result == 0: Logger.info("MAIN: The autoProcessTV script completed successfully.") diff --git a/nzbToSickBeard.py b/nzbToSickBeard.py index 63f53c2c..11f1b372 100755 --- a/nzbToSickBeard.py +++ b/nzbToSickBeard.py @@ -229,22 +229,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: else: result = 0 - # init sub-sections - subsections = config().get_subsections(["SickBeard"]) - + subsections = config()["SickBeard"].subsections Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in subsections.items(): for category in subsection: - if config().isenabled(section,category): + if config()[section].isenabled(category): dirNames = get_dirnames(section, category) for dirName in dirNames: - Logger.info("MAIN: nzbTo%s running %s:%s as a manual run...", section, section, category) + Logger.info("MAIN: nzbToSickBeard running %s:%s as a manual run on folder %s ...", section, category, dirName) results = autoProcessTV().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category) if results != 0: result = results - Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category) + Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) else: - Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, section, category) + Logger.info("MAIN: nzbToSickBeard %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) if result == 0: Logger.info("MAIN: The autoProcessTV script completed successfully.") diff --git a/nzbtomedia/autoProcess/autoProcessComics.py b/nzbtomedia/autoProcess/autoProcessComics.py index 0d4fa818..e31dc4f5 100644 --- a/nzbtomedia/autoProcess/autoProcessComics.py +++ b/nzbtomedia/autoProcess/autoProcessComics.py @@ -15,21 +15,21 @@ class autoProcessComics: return 1 # failure # auto-detect correct section - section = ''.join(map(str, config().issubsection(inputCategory, checkenabled=True))) + section = config().findsection(inputCategory) if not section: Logger.error( - "MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory) + "MAIN: We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) return 1 socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. Logger.info("Loading config from %s", config.CONFIG_FILE) - host = config()[section][inputCategory]["host"] port = config()[section][inputCategory]["port"] username = config()[section][inputCategory]["username"] password = config()[section][inputCategory]["password"] + try: ssl = int(config()[section][inputCategory]["ssl"]) except: diff --git a/nzbtomedia/autoProcess/autoProcessGames.py b/nzbtomedia/autoProcess/autoProcessGames.py index 8e8cf3f8..35f9deaa 100644 --- a/nzbtomedia/autoProcess/autoProcessGames.py +++ b/nzbtomedia/autoProcess/autoProcessGames.py @@ -14,10 +14,10 @@ class autoProcessGames: return 1 # failure # auto-detect correct section - section = ''.join(map(str, config().issubsection(inputCategory, checkenabled=True))) + section = config().findsection(inputCategory) if not section: Logger.error( - "MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory) + "MAIN: We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) return 1 socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. diff --git a/nzbtomedia/autoProcess/autoProcessMovie.py b/nzbtomedia/autoProcess/autoProcessMovie.py index 4c3ca243..5536908f 100644 --- a/nzbtomedia/autoProcess/autoProcessMovie.py +++ b/nzbtomedia/autoProcess/autoProcessMovie.py @@ -166,10 +166,10 @@ class autoProcessMovie: return 1 # failure # auto-detect correct section - section = ''.join(map(str, config().issubsection(inputCategory, checkenabled=True))) + section = config().findsection(inputCategory) if not section: Logger.error( - "MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory) + "MAIN: We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) return 1 socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. diff --git a/nzbtomedia/autoProcess/autoProcessMusic.py b/nzbtomedia/autoProcess/autoProcessMusic.py index ab6eb18a..b223b289 100644 --- a/nzbtomedia/autoProcess/autoProcessMusic.py +++ b/nzbtomedia/autoProcess/autoProcessMusic.py @@ -16,10 +16,10 @@ class autoProcessMusic: return 1 # failure # auto-detect correct section - section = config().issubsection(inputCategory,checkenabled=True)[0] + section = config().findsection(inputCategory) if len(section) == 0: Logger.error( - "MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory) + "MAIN: We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) return 1 socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. diff --git a/nzbtomedia/autoProcess/autoProcessTV.py b/nzbtomedia/autoProcess/autoProcessTV.py index c32b4661..6bbef92c 100644 --- a/nzbtomedia/autoProcess/autoProcessTV.py +++ b/nzbtomedia/autoProcess/autoProcessTV.py @@ -21,17 +21,14 @@ class autoProcessTV: return 1 # failure # auto-detect correct section - section = ''.join(map(str, config().issubsection(inputCategory, checkenabled=True))) + section = config().findsection(inputCategory) if not section: Logger.error( - "MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory) + "MAIN: We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) return 1 - fork, fork_params = autoFork(section, inputCategory) - Torrent_NoLink = int(config()[section][inputCategory]["Torrent_NoLink"]) # 0 - if not fork in config.SICKBEARD_TORRENT and not Torrent_NoLink == 1: - if clientAgent in ['utorrent', 'transmission', 'deluge']: - return 1 + # auto-detect correct fork + fork, fork_params = autoFork(inputCategory) socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. diff --git a/nzbtomedia/extractor/extractor.py b/nzbtomedia/extractor/extractor.py index 6de9cf24..4c89e2dd 100644 --- a/nzbtomedia/extractor/extractor.py +++ b/nzbtomedia/extractor/extractor.py @@ -1,8 +1,9 @@ +import os import sys import logging from subprocess import call, Popen -from nzbtomedia.nzbToMediaConfig import * +from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import create_destination @@ -10,6 +11,7 @@ Logger = logging.getLogger() # which() and os_platform() breaks when running in Transmission (has to do with os.environ) + def os_platform(): # Author Credit: Matthew Scouten @ http://stackoverflow.com/a/7260315 true_platform = os.environ['PROCESSOR_ARCHITECTURE'] @@ -20,22 +22,6 @@ def os_platform(): #true_platform not assigned to if this does not exist return true_platform -def which(program): - # Author Credit: Jay @ http://stackoverflow.com/a/377028 - def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - - fpath, fname = os.path.split(program) - if fpath: - if is_exe(program): - return program - else: - for path in os.environ["PATH"].split(os.pathsep): - exe_file = os.path.join(path, program) - if is_exe(exe_file): - return exe_file - - return None def extract(filePath, outputDestination): # Using Windows @@ -45,11 +31,11 @@ def extract(filePath, outputDestination): else: platform = 'x86' if not os.path.dirname(sys.argv[0]): - chplocation = os.path.normpath(os.path.join(os.getcwd(), 'extractor/bin/chp.exe')) - sevenzipLocation = os.path.normpath(os.path.join(os.getcwd(), 'extractor/bin/' + platform + '/7z.exe')) + 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')) else: - chplocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'extractor/bin/chp.exe')) - sevenzipLocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), '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 diff --git a/nzbtomedia/nzbToMediaAutoFork.py b/nzbtomedia/nzbToMediaAutoFork.py index 230dce43..b2f56c09 100644 --- a/nzbtomedia/nzbToMediaAutoFork.py +++ b/nzbtomedia/nzbToMediaAutoFork.py @@ -5,10 +5,17 @@ from lib import requests from nzbToMediaConfig import config -def autoFork(section, inputCategory): +def autoFork(inputCategory): Logger = logging.getLogger() + # auto-detect correct section + section = config().findsection(inputCategory) + if not section: + Logger.error( + "MAIN: We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) + return 1 + # config settings try: host = config()[section][inputCategory]["host"] diff --git a/nzbtomedia/nzbToMediaConfig.py b/nzbtomedia/nzbToMediaConfig.py index 46529a45..a8901663 100644 --- a/nzbtomedia/nzbToMediaConfig.py +++ b/nzbtomedia/nzbToMediaConfig.py @@ -4,70 +4,67 @@ import lib.configobj from itertools import chain class Sections(dict): - def has_subsection(sections, subsection, checkenabled=False): - # checks sections for subsection, returns true/false - to_return = {} + def issubsection(sections, subsection, checkenabled=True): + # checks sections for subsection, returns true/false in {} + to_return = False for section in sections.values(): - to_return.update({section.name: True}) - if subsection in section and checkenabled: - if not section.isenabled(): - to_return.update({section.name: False}) - elif subsection not in section: - to_return.update({section.name: False}) + to_return = section.issubsection(subsection, checkenabled) return to_return - def isenabled(sections, subsection=None): - # checks if subsections are enabled, returns true/false - to_return = {} + def isenabled(sections, subsection): + # checks if subsections are enabled, returns true/false in {} + to_return = False for section in sections.values(): - result = {} - subsections = [subsection] if subsection else section - for category in subsections: - if category in section: - result[category] = True - if not int(section[category]['enabled']) == 1: - result[category] = False - to_return.update({section.name:result}) + to_return = section.isenabled(subsection) return to_return + @property + def sections(sections): + # returns [subsections] + to_return = [] + for section in sections: + to_return.append(sections[section].sections) + return list(set(chain.from_iterable(to_return))) + @property def subsections(sections): + # returns {section name:[subsections]} to_return = {} for section in sections: - result = [] - for subsection in sections[section]: - result.append(subsection) - to_return[section] = result + to_return.update(sections[section].subsections) return to_return class Section(lib.configobj.Section): - def has_subsection(section, subsection, checkenabled=False): + def issubsection(section, subsection, checkenabled=True): # checks section for subsection, returns true/false - to_return=[True] - if subsection in section and checkenabled: - if not section.isenabled(subsection): - to_return.append(False) - elif subsection not in section: - to_return.append(False) + to_return = False + if subsection in section: + if checkenabled and section.isenabled(subsection): + to_return = True + else: + to_return = True return to_return - def isenabled(section, subsection=None): - # checks if subsection enabled, returns true/false - to_return = {} - subsections = [subsection] if subsection else section - for category in subsections: - to_return[category] = True - if not int(section[category]['enabled']) == 1: - to_return[category] = False + def isenabled(section, subsection): + # checks if subsection enabled, returns true/false if subsection specified otherwise returns true/false in {} + to_return = False + if subsection in section and int(section[subsection]['enabled']) == 1: + to_return = True return to_return @property def subsections(section): - to_return = [] + # returns {section name:[subsections]} + to_return = {} for subsection in section: - to_return.append(subsection) + to_return.update({section.name: section.sections}) return to_return + def findsection(section, key): + for subsection in section: + if key in section[subsection]: + return subsection + class ConfigObj(lib.configobj.ConfigObj, Section): # constants for nzbtomedia NZBTOMEDIA_VERSION = 'V9.3' @@ -116,36 +113,11 @@ class ConfigObj(lib.configobj.ConfigObj, Section): for item in key: val = dict.__getitem__(self, item) result.update({item: val}) + return result else: val = dict.__getitem__(self, key) - result.update({key: val}) - return result - - def get_sections(self, subsections): - # finds all sections belonging to the subsection and returns them - if not isinstance(subsections, list): - subsections = [subsections] - - to_return = [] - for subsection in subsections: - for section in config().sections: - if self[section].has_key(subsection): - to_return.append(section) - return to_return - - def get_subsections(self, sections): - # finds all subsections belonging to the section and returns them - if not isinstance(sections, list): - sections = [sections] - - to_return = {} - for section in sections: - if section in self.sections: - for subsection in self[section].sections: - if not isinstance(subsection, list): - subsection = [subsection] - to_return.update({section: subsection}) - return to_return + #result.update({key: val}) + return val def migrate(self): global config_new, config_old @@ -171,13 +143,12 @@ class ConfigObj(lib.configobj.ConfigObj, Section): if not config() and not config(self.SAMPLE_CONFIG_FILE) or not config_new or not config_old: return False - subsections = {} # gather all new-style and old-style sub-sections - for newsection, newitems in config_new.iteritems(): + for newsection, newitems in config_new.items(): if config_new[newsection].sections: subsections.update({newsection: config_new[newsection].sections}) - for section, items in config_old.iteritems(): + for section, items in config_old.items(): if config_old[section].sections: subsections.update({section: config_old[section].sections}) for option, value in config_old[section].items(): @@ -289,6 +260,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section): if os.environ[envCatKey] not in config_new[section].sections: config_new[section][os.environ[envCatKey]] = {} config_new[section][os.environ[envCatKey]][option] = value + config_new[section][os.environ[envCatKey]]['enabled'] = 1 section = "SickBeard" envCatKey = 'NZBPO_SBCATEGORY' @@ -303,6 +275,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section): if os.environ[envCatKey] not in config_new[section].sections: config_new[section][os.environ[envCatKey]] = {} config_new[section][os.environ[envCatKey]][option] = value + config_new[section][os.environ[envCatKey]]['enabled'] = 1 section = "HeadPhones" envCatKey = 'NZBPO_HPCATEGORY' @@ -317,6 +290,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section): if os.environ[envCatKey] not in config_new[section].sections: config_new[section][os.environ[envCatKey]] = {} config_new[section][os.environ[envCatKey]][option] = value + config_new[section][os.environ[envCatKey]]['enabled'] = 1 section = "Mylar" envCatKey = 'NZBPO_MYCATEGORY' @@ -331,6 +305,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section): if os.environ[envCatKey] not in config_new[section].sections: config_new[section][os.environ[envCatKey]] = {} config_new[section][os.environ[envCatKey]][option] = value + config_new[section][os.environ[envCatKey]]['enabled'] = 1 section = "Gamez" envCatKey = 'NZBPO_GZCATEGORY' @@ -345,6 +320,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section): if os.environ[envCatKey] not in config_new[section].sections: config_new[section][os.environ[envCatKey]] = {} config_new[section][os.environ[envCatKey]][option] = value + config_new[section][os.environ[envCatKey]]['enabled'] = 1 section = "NzbDrone" envCatKey = 'NZBPO_NDCATEGORY' @@ -359,6 +335,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section): if os.environ[envCatKey] not in config_new[section].sections: config_new[section][os.environ[envCatKey]] = {} config_new[section][os.environ[envCatKey]][option] = value + config_new[section][os.environ[envCatKey]]['enabled'] = 1 section = "Extensions" envKeys = ['COMPRESSEDEXTENSIONS', 'MEDIAEXTENSIONS', 'METAEXTENSIONS'] @@ -403,4 +380,4 @@ class ConfigObj(lib.configobj.ConfigObj, Section): lib.configobj.Section = Section lib.configobj.ConfigObj = ConfigObj -config = ConfigObj \ No newline at end of file +config = ConfigObj diff --git a/nzbtomedia/nzbToMediaUtil.py b/nzbtomedia/nzbToMediaUtil.py index 3c9f2263..909c3e27 100644 --- a/nzbtomedia/nzbToMediaUtil.py +++ b/nzbtomedia/nzbToMediaUtil.py @@ -51,11 +51,25 @@ def create_destination(outputDestination): sys.exit(-1) def category_search(inputDirectory, inputName, inputCategory, root, categories): - if inputDirectory is None: - return inputDirectory, inputName, inputCategory, root + single = False + tordir = False - if not os.path.isdir(inputDirectory) and os.path.isfile(inputDirectory): # If the input directory is a file, assume single file downlaod and split dir/name. - inputDirectory,inputName = os.path.split(os.path.normpath(inputDirectory)) + if inputDirectory is None: # =Nothing to process here. + return inputDirectory, inputName, inputCategory, root, single + + pathlist = os.path.normpath(inputDirectory).split(os.sep) + + try: + inputCategory = list(set(pathlist) & set(categories))[-1] # assume last match is most relevant category. + Logger.debug("SEARCH: Found Category: %s in directory structure", inputCategory) + except IndexError: + inputCategory = "" + Logger.debug("SEARCH: Could not find a category in the directory structure") + + if not os.path.isdir(inputDirectory) and os.path.isfile(inputDirectory): # If the input directory is a file + single = True + if not inputName: inputName = os.path.split(os.path.normpath(inputDirectory))[1] + 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) @@ -65,137 +79,42 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): 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) inputDirectory = os.path.join(inputDirectory, safeName(inputName)) Logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory) - - categorySearch = [os.path.normpath(inputDirectory), ""] # initializie - notfound = 0 - unique = int(0) - for x in range(10): # loop up through 10 directories looking for category. + tordir = True + + imdbid = [item for item in pathlist if '.cp(tt' in item] # This looks for the .cp(tt imdb id in the path. + if imdbid and not '.cp(tt' in inputName: + inputName = imdbid[0] # This ensures the imdb id is preserved and passed to CP + tordir = True + + if inputCategory and not tordir: try: - categorySearch2 = os.path.split(os.path.normpath(categorySearch[0])) - except: # this might happen when we can't go higher. - if unique == int(0): - if inputCategory and inputName: # if these exists, we are ok to proceed, but assume we are in a root/common directory. - Logger.info("SEARCH: Could not find a category in the directory structure") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 1 - break # we are done - elif inputCategory: # if this exists, we are ok to proceed, but assume we are in a root/common directory and we have to check file dates. - Logger.info("SEARCH: Could not find a torrent name or category in the directory structure") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 2 - break # we are done - elif inputName: # we didn't find category after 10 loops. This is a problem. - Logger.info("SEARCH: Could not find a category in the directory structure") - Logger.info("SEARCH: Files will be linked and will only be processed by the userscript if enabled for UNCAT or ALL") - root = 1 - break # we are done - else: # we didn't find this after 10 loops. This is a problem. - Logger.info("SEARCH: Could not identify category or torrent name from the directory structure.") - Logger.info("SEARCH: Files will be linked and will only be processed by the userscript if enabled for UNCAT or ALL") - root = 2 - break # we are done + 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] + except ValueError: + pass - if categorySearch2[1] in categories: - Logger.debug("SEARCH: Found Category: %s in directory structure", categorySearch2[1]) - if not inputCategory: - Logger.info("SEARCH: Determined Category to be: %s", categorySearch2[1]) - inputCategory = categorySearch2[1] - if inputName and categorySearch[0] != os.path.normpath(inputDirectory): # if we are not in the root directory and we have inputName we can continue. - if ('.cp(tt' in categorySearch[1]) and (not '.cp(tt' in inputName): # if the directory was created by CouchPotato, and this tag is not in Torrent name, we want to add it. - Logger.info("SEARCH: Changing Torrent Name to %s to preserve imdb id.", categorySearch[1]) - inputName = categorySearch[1] - Logger.info("SEARCH: Identified Category: %s and Torrent Name: %s. We are in a unique directory, so we can proceed.", inputCategory, inputName) - break # we are done - elif categorySearch[1] and not inputName: # assume the the next directory deep is the torrent name. - inputName = categorySearch[1] - Logger.info("SEARCH: Found torrent name: %s", categorySearch[1]) - if os.path.isdir(os.path.join(categorySearch[0], categorySearch[1])): - Logger.info("SEARCH: Found torrent directory %s in category directory %s", os.path.join(categorySearch[0], categorySearch[1]), categorySearch[0]) - inputDirectory = os.path.normpath(os.path.join(categorySearch[0], categorySearch[1])) - elif os.path.isfile(os.path.join(categorySearch[0], categorySearch[1])): # Our inputdirectory is actually the full file path for single file download. - Logger.info("SEARCH: %s is a file, not a directory.", os.path.join(categorySearch[0], categorySearch[1])) - Logger.info("SEARCH: Setting input directory to %s", categorySearch[0]) - root = 1 - inputDirectory = os.path.normpath(categorySearch[0]) - else: # The inputdirectory given can't have been valid. Start at the category directory and search for date modified. - Logger.info("SEARCH: Input Directory %s doesn't exist as a directory or file", inputDirectory) - Logger.info("SEARCH: Setting input directory to %s and checking for files by date modified.", categorySearch[0]) - root = 2 - inputDirectory = os.path.normpath(categorySearch[0]) - break # we are done - elif ('.cp(tt' in categorySearch[1]) and (not '.cp(tt' in inputName): # if the directory was created by CouchPotato, and this tag is not in Torrent name, we want to add it. - Logger.info("SEARCH: Changing Torrent Name to %s to preserve imdb id.", categorySearch[1]) - inputName = categorySearch[1] - break # we are done - elif inputName and os.path.isdir(os.path.join(categorySearch[0], inputName)): # testing for torrent name in first sub directory - Logger.info("SEARCH: Found torrent directory %s in category directory %s", os.path.join(categorySearch[0], inputName), categorySearch[0]) - if categorySearch[0] == os.path.normpath(inputDirectory): # only true on first pass, x =0 - inputDirectory = os.path.join(categorySearch[0], inputName) # we only want to search this next dir up. - break # we are done - elif inputName and os.path.isdir(os.path.join(categorySearch[0], safeName(inputName))): # testing for torrent name in first sub directory - Logger.info("SEARCH: Found torrent directory %s in category directory %s", os.path.join(categorySearch[0], safeName(inputName)), categorySearch[0]) - if categorySearch[0] == os.path.normpath(inputDirectory): # only true on first pass, x =0 - inputDirectory = os.path.join(categorySearch[0], safeName(inputName)) # we only want to search this next dir up. - break # we are done - elif inputName and os.path.isfile(os.path.join(categorySearch[0], inputName)) or os.path.isfile(os.path.join(categorySearch[0], safeName(inputName))): # testing for torrent name name as file inside category directory - Logger.info("SEARCH: Found torrent file %s in category directory %s", os.path.join(categorySearch[0], safeName(inputName)), categorySearch[0]) - root = 1 - inputDirectory = os.path.normpath(categorySearch[0]) - break # we are done - elif inputName: # if these exists, we are ok to proceed, but we are in a root/common directory. - Logger.info("SEARCH: Could not find a unique torrent folder in the directory structure") - Logger.info("SEARCH: The directory passed is the root directory for category %s", categorySearch2[1]) - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 1 - break # we are done - else: # this is a problem! if we don't have Torrent name and are in the root category dir, we can't proceed. - Logger.warn("SEARCH: Could not identify a torrent name and the directory passed is common to all downloads for category %s.", categorySearch[1]) - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 2 - break - elif inputName and safeName(categorySearch2[1]) == safeName(inputName) and os.path.isdir(categorySearch[0]): # we have identified a unique directory. - Logger.info("SEARCH: Files appear to be in their own directory") - unique = int(1) - if inputCategory: # we are ok to proceed. - break # we are done - else: - Logger.debug("SEARCH: Continuing scan to determin category.") - categorySearch = categorySearch2 # ready for next loop - continue # keep going + if inputName and not tordir: + if inputName in pathlist or safeName(inputName) in pathlist: + Logger.info("SEARCH: Found torrent directory %s in the directory structure", inputName) + tordir = True else: - if x == 9: # This is the last pass in the loop and we didn't find anything. - notfound = 1 - break # we are done - else: - categorySearch = categorySearch2 # ready for next loop - continue # keep going - - if notfound == 1 and not unique == int(1): - if inputCategory and inputName: # if these exists, we are ok to proceed, but assume we are in a root/common directory. - Logger.info("SEARCH: Could not find a category in the directory structure") - Logger.info("SEARCH: We will try and determine which files to process, individually") root = 1 - elif inputCategory: # if this exists, we are ok to proceed, but assume we are in a root/common directory and we have to check file dates. - Logger.info("SEARCH: Could not find a torrent name or category in the directory structure") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 2 - elif inputName: # we didn't find category after 10 loops. This is a problem. - Logger.info("SEARCH: Could not find a category in the directory structure") - Logger.info("SEARCH: Files will be linked and will only be processed by the userscript if enabled for UNCAT or ALL") - root = 1 - else: # we didn't find this after 10 loops. This is a problem. - Logger.info("SEARCH: Could not identify category or torrent name from the directory structure.") - Logger.info("SEARCH: Files will be linked and will only be processed by the userscript if enabled for UNCAT or ALL") - root = 2 + if not tordir: + root = 2 - return inputDirectory, inputName, inputCategory, root + if root > 0: + Logger.info("SEARCH: Could not find a unique directory for this download. Assume a common directory.") + Logger.info("SEARCH: We will try and determine which files to process, individually") + return inputDirectory, inputName, inputCategory, root, single def is_sample(filePath, inputName, minSampleSize, SampleIDs): # 200 MB in bytes diff --git a/tests/test_autofork.py b/tests/test_autofork.py index a0d1611c..d52d96c7 100644 --- a/tests/test_autofork.py +++ b/tests/test_autofork.py @@ -1,3 +1,21 @@ -from nzbtomedia import * -fork, params = autoFork() -print fork, params \ No newline at end of file +from nzbtomedia.nzbToMediaConfig import config + +print config().findsection('tv').isenabled() +print +print config().sections +print +sections = ("CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez") +print config()[sections].subsections +print config()['SickBeard'].subsections +print +print config()[sections].sections +print config()['SickBeard'].sections +print +print config()['SickBeard','NzbDrone'] +print config()['SickBeard'] +print +print config()['SickBeard','NzbDrone','CouchPotato'].issubsection('tv', True) +print config()['SickBeard'].issubsection('tv', True) +print +print config()['SickBeard','NzbDrone'].isenabled('tv') +print config()['SickBeard'].isenabled('tv') \ No newline at end of file