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]: result = autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory) elif nzbtomedia.CFG["SickBeard", "NzbDrone"][inputCategory]: result = autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["HeadPhones"][inputCategory]: result = autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["Mylar"][inputCategory]: result = autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["Gamez"][inputCategory]: result = autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory) if result == 0: # Clean up any leftover files cleanup_directories(inputCategory, section, result, nzbDir) return result
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]: result = autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory) elif nzbtomedia.CFG["SickBeard", "NzbDrone"][inputCategory]: result = autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["HeadPhones"][inputCategory]: result = autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["Mylar"][inputCategory]: result = autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG["Gamez"][inputCategory]: result = autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory) if result == 0: # Clean up any leftover files cleanup_directories(inputCategory, section, result, nzbDir) return result
def process(inputDirectory, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None): if nzbtomedia.SAFE_MODE and inputDirectory == nzbtomedia.NZB_DEFAULTDIR: logger.error( 'The input directory:[%s] is the Default Download Directory. Please configure category directories to prevent processing of other media.' % ( inputDirectory)) return -1 if clientAgent != 'manual' and not nzbtomedia.DOWNLOADINFO: logger.debug('Adding NZB download info for directory %s to database' % (inputDirectory)) myDB = nzbToMediaDB.DBConnection() encoded, inputDirectory1 = CharReplace(inputDirectory) encoded, inputName1 = CharReplace(inputName) controlValueDict = {"input_directory": unicode(inputDirectory1)} newValueDict = {"input_name": unicode(inputName1), "input_hash": unicode(download_id), "input_id": unicode(download_id), "client_agent": unicode(clientAgent), "status": 0, "last_update": datetime.date.today().toordinal() } myDB.upsert("downloads", newValueDict, controlValueDict) # auto-detect section if inputCategory is None: inputCategory = 'UNCAT' usercat = inputCategory section = nzbtomedia.CFG.findsection(inputCategory).isenabled() if section is None: section = nzbtomedia.CFG.findsection("ALL").isenabled() if section is None: logger.error( 'Category:[%s] is not defined or is not enabled. Please rename it or ensure it is enabled for the appropriate section in your autoProcessMedia.cfg and try again.' % ( inputCategory)) return -1 else: usercat = "ALL" if len(section) > 1: logger.error( 'Category:[%s] is not unique, %s are using it. Please rename it or disable all other sections using the same category name in your autoProcessMedia.cfg and try again.' % ( inputCategory, section.keys())) return -1 if section: sectionName = section.keys()[0] logger.info('Auto-detected SECTION:%s' % (sectionName)) else: logger.error("Unable to locate a section with subsection:%s enabled in your autoProcessMedia.cfg, exiting!" % ( inputCategory)) return -1 try: extract = int(section[usercat]['extract']) except: extract = 0 try: if int(section[usercat]['remote_path']) and not nzbtomedia.REMOTEPATHS: logger.error('Remote Path is enabled for %s:%s but no Network mount points are defined. Please check your autoProcessMedia.cfg, exiting!' % ( sectionName, inputCategory)) return -1 except: logger.error('Remote Path %s is not valid for %s:%s Please set this to either 0 to disable or 1 to enable!' % ( section[usercat]['remote_path'], sectionName, inputCategory)) inputName, inputDirectory = convert_to_ascii(inputName, inputDirectory) if extract == 1: logger.debug('Checking for archives to extract in directory: %s' % (inputDirectory)) extractFiles(inputDirectory) logger.info("Calling %s:%s to post-process:%s" % (sectionName, inputCategory, inputName)) if sectionName == "CouchPotato": result = autoProcessMovie().process(sectionName, inputDirectory, inputName, status, clientAgent, download_id, inputCategory) elif sectionName in ["SickBeard", "NzbDrone"]: result = autoProcessTV().processEpisode(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) elif sectionName == "HeadPhones": result = autoProcessMusic().process(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) elif sectionName == "Mylar": result = autoProcessComics().processEpisode(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) elif sectionName == "Gamez": result = autoProcessGames().process(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) elif sectionName == 'UserScript': result = external_script(inputDirectory, inputName, inputCategory, section[usercat]) else: result = -1 if result == 0: if clientAgent != 'manual': # update download status in our DB update_downloadInfoStatus(inputName, 1) # cleanup our processing folders of any misc unwanted files and empty directories cleanDir(inputDirectory, sectionName, inputCategory) return result
def process(inputDirectory, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None): if nzbtomedia.SAFE_MODE and inputDirectory == nzbtomedia.NZB_DEFAULTDIR: logger.error( 'The input directory:[%s] is the Default Download Directory. Please configure category directories to prevent processing of other media.' % (inputDirectory)) return -1 if clientAgent != 'manual' and not nzbtomedia.DOWNLOADINFO: logger.debug('Adding NZB download info for directory %s to database' % (inputDirectory)) myDB = nzbToMediaDB.DBConnection() controlValueDict = {"input_directory": unicode(inputDirectory)} newValueDict = { "input_name": unicode(inputName), "input_hash": unicode(download_id), "input_id": unicode(download_id), "client_agent": unicode(clientAgent), "status": 0, "last_update": datetime.date.today().toordinal() } myDB.upsert("downloads", newValueDict, controlValueDict) # auto-detect section section = nzbtomedia.CFG.findsection(inputCategory).isenabled() if section is None: logger.error( 'Category:[%s] is not defined or is not enabled. Please rename it or ensure it is enabled for the appropriate section in your autoProcessMedia.cfg and try again.' % (inputCategory)) return -1 if len(section) > 1: logger.error( 'Category:[%s] is not unique, %s are using it. Please rename it or disable all other sections using the same category name in your autoProcessMedia.cfg and try again.' % (inputCategory, section.keys())) return -1 if section: sectionName = section.keys()[0] logger.info('Auto-detected SECTION:%s' % (sectionName)) else: logger.error( "Unable to locate a section with subsection:%s enabled in your autoProcessMedia.cfg, exiting!" % (inputCategory)) return -1 try: extract = int(section[inputCategory]['extract']) except: extract = 0 try: if int(section[inputCategory] ['remote_path']) and not nzbtomedia.REMOTEPATHS: logger.error( 'Remote Path is enabled for %s:%s but no Network mount points are defined. Please check your autoProcessMedia.cfg, exiting!' % (sectionName, inputCategory)) return -1 except: logger.error( 'Remote Path %s is not valid for %s:%s Please set this to either 0 to disable or 1 to enable!' % (section[inputCategory]['remote_path'], sectionName, inputCategory)) if extract == 1: logger.debug('Checking for archives to extract in directory: %s' % (inputDirectory)) extractFiles(inputDirectory) logger.info("Calling %s:%s to post-process:%s" % (sectionName, inputCategory, inputName)) if sectionName == "CouchPotato": result = autoProcessMovie().process(sectionName, inputDirectory, inputName, status, clientAgent, download_id, inputCategory) elif sectionName in ["SickBeard", "NzbDrone"]: result = autoProcessTV().processEpisode(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) elif sectionName == "HeadPhones": result = autoProcessMusic().process(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) elif sectionName == "Mylar": result = autoProcessComics().processEpisode(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) elif sectionName == "Gamez": result = autoProcessGames().process(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory) else: result = -1 if result == 0: if clientAgent != 'manual': # update download status in our DB update_downloadInfoStatus(inputName, 1) # cleanup our processing folders of any misc unwanted files and empty directories cleanDir(inputDirectory, sectionName, inputCategory) return result
def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, clientAgent): status = int(1) # 1 = failed | 0 = success root = int(0) video = int(0) archive = int(0) foundFile = int(0) extracted_folder = [] copy_list = [] 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)) TorrentClass = None if clientAgent != 'manual': TorrentClass = create_torrent_class(clientAgent) pause_torrent(clientAgent, TorrentClass, inputHash, inputID, inputName) processCategories = nzbtomedia.CFG[nzbtomedia.SECTIONS].sections if inputCategory == "": inputCategory = "UNCAT" outputDestination = os.path.normpath(os.path.join(nzbtomedia.OUTPUTDIRECTORY, inputCategory, sanitizeFileName(inputName))) logger.info("Output directory set to: %s" % (outputDestination)) if nzbtomedia.CFG["SickBeard"][inputCategory]: Torrent_NoLink = int(nzbtomedia.CFG["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0 if Torrent_NoLink == 1: logger.info("Calling autoProcessTV to post-process: %s",inputName) result = autoProcessTV().processEpisode(inputDirectory, inputName, 0, clientAgent=clientAgent, inputCategory=inputCategory) if result != 0: logger.error("A problem was reported in the autoProcessTV script.") if clientAgent != 'manual': resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName) cleanup_directories(inputCategory, processCategories, result, outputDestination) return result processOnly = nzbtomedia.CFG[nzbtomedia.SECTIONS].sections if not "NONE" in nzbtomedia.USER_SCRIPT_CATEGORIES: # if None, we only process the 5 listed. if "ALL" in nzbtomedia.USER_SCRIPT_CATEGORIES: # All defined categories processOnly = nzbtomedia.CATEGORIES processOnly.extend(nzbtomedia.USER_SCRIPT_CATEGORIES) # Adds all categories to be processed by userscript. if not inputCategory in processOnly: logger.info("No processing to be done for category: %s. Exiting" % (inputCategory)) return 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. 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("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 nzbtomedia.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] == "/": 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)) targetDirectory = os.path.join(outputDestination, file) if root == 1: if foundFile == int(0): logger.debug("Looking for %s in: %s" % (inputName, file)) if (sanitizeFileName(inputName) in sanitizeFileName(file)) or (sanitizeFileName(fileName) in sanitizeFileName(inputName)): #pass # This file does match the Torrent name foundFile = 1 logger.debug("Found file %s that matches Torrent Name %s" % (file, inputName)) else: continue # This file does not match the Torrent name, skip it if root == 2: if foundFile == int(0): logger.debug("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)): #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)) 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.info("Ignoring sample file: %s " % (filePath)) continue if fileExtension in nzbtomedia.COMPRESSEDCONTAINER: if not (nzbtomedia.CFG["SickBeard"][inputCategory] and nzbtomedia.CFG["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("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)) continue logger.info("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)) 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)) 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. flatten(outputDestination) if platform.system().lower() == 'windows': # remove Read Only flag from files in Windows. remove_read_only(outputDestination) # Now check if video files exist in destination: if nzbtomedia.CFG["SickBeard","NzbDrone", "CouchPotato"][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 nzbtomedia.MEDIACONTAINER: # If the file is a video file 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))) 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))) 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.info("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.") status = int(0) # hp, my, gz don't support failed. else: logger.error("Something failed! Please check logs. Exiting") return status result = 0 if nzbtomedia.CFG['CouchPotato'][inputCategory]: logger.info("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.info("Calling Sick-Beard:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['NzbDrone'][inputCategory]: logger.info("Calling NzbDrone:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['HeadPhones'][inputCategory]: logger.info("Calling HeadPhones:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessMusic().process(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['Mylar'][inputCategory]: logger.info("Calling Mylar:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessComics().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) elif nzbtomedia.CFG['Gamez'][inputCategory]: logger.info("Calling Gamez:" + inputCategory + " to post-process: %s" % (inputName)) result = autoProcessGames().process(outputDestination, inputName, status, clientAgent, inputCategory) if result == 1 and clientAgent != 'manual': logger.error("A problem was reported in the autoProcess* script. If torrent was paused we will resume seeding") if clientAgent != 'manual': resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName) cleanup_directories(inputCategory, processCategories, result, outputDestination) return result