Updated logger code to now include the section, formatting has been modified as well.

Logging of debug messages is now optional via log_debug option location in autoProcessMedia.cfg

Lots of code cleanup has been performed including cleanup log messages and corrections of spelling errors.

Improved release lookup code for autoProcessMovie, narrows search results down by making API calls to the download clients to compare results in CouchPotato's database.
This commit is contained in:
echel0n 2014-04-18 13:16:18 -07:00
parent dd41ff3b2f
commit eb7822b60b
16 changed files with 420 additions and 441 deletions

View file

@ -28,11 +28,11 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
extracted_folder = [] extracted_folder = []
copy_list = [] copy_list = []
logger.debug("Received Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory) logger.debug("Received Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory))
inputDirectory, inputName, inputCategory, root, single = category_search(inputDirectory, inputName, inputCategory, root, nzbtomedia.CATEGORIES) # Confirm the category by parsing directory structure inputDirectory, inputName, inputCategory, root, single = category_search(inputDirectory, inputName, inputCategory, root, nzbtomedia.CATEGORIES) # Confirm the category by parsing directory structure
logger.debug("Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory) logger.debug("Determined Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory))
TorrentClass = None TorrentClass = None
if clientAgent != 'manual': if clientAgent != 'manual':
@ -44,7 +44,7 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
if inputCategory == "": if inputCategory == "":
inputCategory = "UNCAT" inputCategory = "UNCAT"
outputDestination = os.path.normpath(os.path.join(nzbtomedia.OUTPUTDIRECTORY, inputCategory, safeName(inputName))) outputDestination = os.path.normpath(os.path.join(nzbtomedia.OUTPUTDIRECTORY, inputCategory, safeName(inputName)))
logger.postprocess("Output directory set to: %s", outputDestination) logger.postprocess("Output directory set to: %s" % (outputDestination))
if nzbtomedia.CFG["SickBeard"][inputCategory]: if nzbtomedia.CFG["SickBeard"][inputCategory]:
Torrent_NoLink = int(nzbtomedia.CFG["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0 Torrent_NoLink = int(nzbtomedia.CFG["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0
@ -67,10 +67,10 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
processOnly.extend(nzbtomedia.USER_SCRIPT_CATEGORIES) # Adds all categories to be processed by userscript. processOnly.extend(nzbtomedia.USER_SCRIPT_CATEGORIES) # Adds all categories to be processed by userscript.
if not inputCategory in processOnly: if not inputCategory in processOnly:
logger.postprocess("No processing to be done for category: %s. Exiting", inputCategory) logger.postprocess("No processing to be done for category: %s. Exiting" % (inputCategory))
return return
logger.debug("Scanning files in directory: %s", inputDirectory) logger.debug("Scanning files in directory: %s" % (inputDirectory))
if nzbtomedia.CFG["HeadPhones"][inputCategory]: if nzbtomedia.CFG["HeadPhones"][inputCategory]:
nzbtomedia.NOFLATTEN.extend(nzbtomedia.CFG["HeadPhones"].sections) # Make sure we preserve folder structure for HeadPhones. nzbtomedia.NOFLATTEN.extend(nzbtomedia.CFG["HeadPhones"].sections) # Make sure we preserve folder structure for HeadPhones.
@ -82,7 +82,7 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
if single: if single:
dirnames[:] = [] dirnames[:] = []
filenames[:] = [filenames] # we just want to work with this one file if single = True filenames[:] = [filenames] # we just want to work with this one file if single = True
logger.debug("Found %s files in %s", str(len(filenames)), dirpath) logger.debug("Found %s files in %s" % (str(len(filenames)), dirpath))
for file in filenames: for file in filenames:
filePath = os.path.join(dirpath, file) filePath = os.path.join(dirpath, file)
fileName, fileExtension = os.path.splitext(file) fileName, fileExtension = os.path.splitext(file)
@ -92,17 +92,17 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
if len(newDir) > 0 and newDir[0] == "/": if len(newDir) > 0 and newDir[0] == "/":
newDir = newDir[1:] # remove leading "/" to enable join to work. newDir = newDir[1:] # remove leading "/" to enable join to work.
outputDestination = os.path.join(outputDestinationMaster, newDir) # join this extra directory to output. outputDestination = os.path.join(outputDestinationMaster, newDir) # join this extra directory to output.
logger.debug("Setting outputDestination to %s to preserve folder structure", outputDestination) logger.debug("Setting outputDestination to %s to preserve folder structure" % (outputDestination))
targetDirectory = os.path.join(outputDestination, file) targetDirectory = os.path.join(outputDestination, file)
if root == 1: if root == 1:
if foundFile == int(0): if foundFile == int(0):
logger.debug("Looking for %s in: %s", inputName, file) logger.debug("Looking for %s in: %s" % (inputName, file))
if (safeName(inputName) in safeName(file)) or (safeName(fileName) in safeName(inputName)): if (safeName(inputName) in safeName(file)) or (safeName(fileName) in safeName(inputName)):
#pass # This file does match the Torrent name #pass # This file does match the Torrent name
foundFile = 1 foundFile = 1
logger.debug("Found file %s that matches Torrent Name %s", file, inputName) logger.debug("Found file %s that matches Torrent Name %s" % (file, inputName))
else: else:
continue # This file does not match the Torrent name, skip it continue # This file does not match the Torrent name, skip it
@ -114,13 +114,13 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)):
#pass # This file does match the date time criteria #pass # This file does match the date time criteria
foundFile = 1 foundFile = 1
logger.debug("Found file %s with date modifed/created less than 5 minutes ago.", file) logger.debug("Found file %s with date modifed/created less than 5 minutes ago." % (file))
else: else:
continue # This file has not been recently moved or created, skip it continue # This file has not been recently moved or created, skip it
if fileExtension in nzbtomedia.MEDIACONTAINER and is_sample(filePath, inputName, nzbtomedia.MINSAMPLESIZE, if fileExtension in nzbtomedia.MEDIACONTAINER and is_sample(filePath, inputName, nzbtomedia.MINSAMPLESIZE,
nzbtomedia.SAMPLEIDS) and not nzbtomedia.CFG["HeadPhones"][inputCategory]: # Ignore samples nzbtomedia.SAMPLEIDS) and not nzbtomedia.CFG["HeadPhones"][inputCategory]: # Ignore samples
logger.postprocess("Ignoring sample file: %s ", filePath) logger.postprocess("Ignoring sample file: %s " % (filePath))
continue continue
if fileExtension in nzbtomedia.COMPRESSEDCONTAINER: if fileExtension in nzbtomedia.COMPRESSEDCONTAINER:
@ -129,24 +129,24 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
if re.search(r'\d+', os.path.splitext(fileName)[1]) and os.path.dirname(filePath) in extracted_folder and not any(item in os.path.splitext(fileName)[1] for item in ['.720p','.1080p','.x264']): 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()) part = int(re.search(r'\d+', os.path.splitext(fileName)[1]).group())
if part == 1: # we only want to extract the primary part. if part == 1: # we only want to extract the primary part.
logger.debug("Found primary part of a multi-part archive %s. Extracting", file) logger.debug("Found primary part of a multi-part archive %s. Extracting" % (file))
else: else:
logger.debug("Found part %s of a multi-part archive %s. Ignoring", part, file) logger.debug("Found part %s of a multi-part archive %s. Ignoring" % (part, file))
continue continue
logger.postprocess("Found compressed archive %s for file %s", fileExtension, filePath) logger.postprocess("Found compressed archive %s for file %s" % (fileExtension, filePath))
try: try:
extractor.extract(filePath, outputDestination) 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) 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)) extracted_folder.append(os.path.dirname(filePath))
except: except:
logger.error("Extraction failed for: %s", file) logger.error("Extraction failed for: %s" % (file))
continue continue
try: try:
copy_link(filePath, targetDirectory, nzbtomedia.USELINK, outputDestination) copy_link(filePath, targetDirectory, nzbtomedia.USELINK, outputDestination)
copy_list.append([filePath, os.path.join(outputDestination, file)]) copy_list.append([filePath, os.path.join(outputDestination, file)])
except: except:
logger.error("Failed to link file: %s", file) logger.error("Failed to link file: %s" % (file))
outputDestination = outputDestinationMaster # Reset here. 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. if not inputCategory in nzbtomedia.NOFLATTEN: #don't flatten hp in case multi cd albums, and we need to copy this back later.
@ -162,21 +162,21 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
filePath = os.path.join(dirpath, file) filePath = os.path.join(dirpath, file)
fileName, fileExtension = os.path.splitext(file) fileName, fileExtension = os.path.splitext(file)
if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file
logger.debug("Found media file: %s", filePath) logger.debug("Found media file: %s" % (filePath))
video += 1 video += 1
if fileExtension in nzbtomedia.COMPRESSEDCONTAINER: # If the file is an archive file if fileExtension in nzbtomedia.COMPRESSEDCONTAINER: # If the file is an archive file
archive += 1 archive += 1
if video > int(0): # Check that media files exist if video > int(0): # Check that media files exist
logger.debug("Found %s media files", str(video)) logger.debug("Found %s media files" % (str(video)))
status = int(0) status = int(0)
elif not (nzbtomedia.CFG["SickBeard"][inputCategory] and nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination") and archive > int(0): elif not (nzbtomedia.CFG["SickBeard"][inputCategory] and nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination") and archive > int(0):
logger.debug("Found %s archive files to be extracted by SickBeard", str(archive)) logger.debug("Found %s archive files to be extracted by SickBeard" % (str(archive)))
status = int(0) status = int(0)
else: else:
logger.warning("Found no media files in output.") 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): if (inputCategory in nzbtomedia.USER_SCRIPT_CATEGORIES and not "NONE" in nzbtomedia.USER_SCRIPT_CATEGORIES) or ("ALL" in nzbtomedia.USER_SCRIPT_CATEGORIES and not inputCategory in processCategories):
logger.postprocess("Processing user script %s.", nzbtomedia.USER_SCRIPT) logger.postprocess("Processing user script %s." % (nzbtomedia.USER_SCRIPT))
result = external_script(outputDestination,inputName,inputCategory) 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. 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.") logger.debug("Calling autoProcess script for successful download.")
@ -187,23 +187,23 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID,
result = 0 result = 0
if nzbtomedia.CFG['CouchPotato'][inputCategory]: if nzbtomedia.CFG['CouchPotato'][inputCategory]:
logger.postprocess("Calling CouchPotato:" + inputCategory + " to post-process: %s", inputName) logger.postprocess("Calling CouchPotato:" + inputCategory + " to post-process: %s" % (inputName))
download_id = inputHash download_id = inputHash
result = autoProcessMovie().process(outputDestination, inputName, status, clientAgent, download_id, inputCategory) result = autoProcessMovie().process(outputDestination, inputName, status, clientAgent, download_id, inputCategory)
elif nzbtomedia.CFG['SickBeard'][inputCategory]: elif nzbtomedia.CFG['SickBeard'][inputCategory]:
logger.postprocess("Calling Sick-Beard:" + inputCategory + " to post-process: %s", inputName) logger.postprocess("Calling Sick-Beard:" + inputCategory + " to post-process: %s" % (inputName))
result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
elif nzbtomedia.CFG['NzbDrone'][inputCategory]: elif nzbtomedia.CFG['NzbDrone'][inputCategory]:
logger.postprocess("Calling NzbDrone:" + inputCategory + " to post-process: %s", inputName) logger.postprocess("Calling NzbDrone:" + inputCategory + " to post-process: %s" % (inputName))
result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
elif nzbtomedia.CFG['HeadPhones'][inputCategory]: elif nzbtomedia.CFG['HeadPhones'][inputCategory]:
logger.postprocess("Calling HeadPhones:" + inputCategory + " to post-process: %s", inputName) logger.postprocess("Calling HeadPhones:" + inputCategory + " to post-process: %s" % (inputName))
result = autoProcessMusic().process(outputDestination, inputName, status, clientAgent, inputCategory) result = autoProcessMusic().process(outputDestination, inputName, status, clientAgent, inputCategory)
elif nzbtomedia.CFG['Mylar'][inputCategory]: elif nzbtomedia.CFG['Mylar'][inputCategory]:
logger.postprocess("Calling Mylar:" + inputCategory + " to post-process: %s", inputName) logger.postprocess("Calling Mylar:" + inputCategory + " to post-process: %s" % (inputName))
result = autoProcessComics().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory) result = autoProcessComics().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
elif nzbtomedia.CFG['Gamez'][inputCategory]: elif nzbtomedia.CFG['Gamez'][inputCategory]:
logger.postprocess("Calling Gamez:" + inputCategory + " to post-process: %s", inputName) logger.postprocess("Calling Gamez:" + inputCategory + " to post-process: %s" % (inputName))
result = autoProcessGames().process(outputDestination, inputName, status, clientAgent, inputCategory) result = autoProcessGames().process(outputDestination, inputName, status, clientAgent, inputCategory)
if result == 1 and clientAgent != 'manual': if result == 1 and clientAgent != 'manual':
@ -255,19 +255,19 @@ def external_script(outputDestination, torrentName, torrentLabel):
cmd = "" cmd = ""
for item in command: for item in command:
cmd = cmd + " " + item cmd = cmd + " " + item
logger.postprocess("Running script %s on file %s.", cmd, filePath) logger.postprocess("Running script %s on file %s." % (cmd, filePath))
try: try:
p = Popen(command) p = Popen(command)
res = p.wait() res = p.wait()
if str(res) in nzbtomedia.USER_SCRIPT_SUCCESSCODES: # Linux returns 0 for successful. if str(res) in nzbtomedia.USER_SCRIPT_SUCCESSCODES: # Linux returns 0 for successful.
logger.postprocess("UserScript %s was successfull", command[0]) logger.postprocess("UserScript %s was successfull" % (command[0]))
result = int(0) result = int(0)
else: else:
logger.error("UserScript %s has failed with return code: %s", command[0], res) logger.error("UserScript %s has failed with return code: %s" % (command[0], res))
logger.postprocess("If the UserScript completed successfully you should add %s to the user_script_successCodes", res) logger.postprocess("If the UserScript completed successfully you should add %s to the user_script_successCodes" % (res))
result = int(1) result = int(1)
except: except:
logger.error("UserScript %s has failed", command[0]) logger.error("UserScript %s has failed" % (command[0]))
result = int(1) result = int(1)
final_result = final_result + result final_result = final_result + result
@ -282,10 +282,10 @@ def external_script(outputDestination, torrentName, torrentLabel):
num_files_new = num_files_new + 1 num_files_new = num_files_new + 1
if nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new == int(0) and final_result == int(0): if nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new == int(0) and final_result == int(0):
logger.postprocess("All files have been processed. Cleaning outputDirectory %s", outputDestination) logger.postprocess("All files have been processed. Cleaning outputDirectory %s" % (outputDestination))
shutil.rmtree(outputDestination) shutil.rmtree(outputDestination)
elif nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new != int(0): elif nzbtomedia.USER_SCRIPT_CLEAN == int(1) and num_files_new != int(0):
logger.postprocess("%s files were processed, but %s still remain. outputDirectory will not be cleaned.", num_files, num_files_new) logger.postprocess("%s files were processed, but %s still remain. outputDirectory will not be cleaned." % (num_files, num_files_new))
return final_result return final_result
def main(args): def main(args):
@ -296,11 +296,11 @@ def main(args):
clientAgent = nzbtomedia.TORRENT_CLIENTAGENT clientAgent = nzbtomedia.TORRENT_CLIENTAGENT
logger.postprocess("#########################################################") logger.postprocess("#########################################################")
logger.postprocess("## ..::[%s]::.. CLIENT:%s ## STARTING", args[0], clientAgent) logger.postprocess("## ..::[%s]::.. CLIENT:%s ## STARTING" % (args[0], clientAgent))
logger.postprocess("#########################################################") logger.postprocess("#########################################################")
# debug command line options # debug command line options
logger.debug("Options passed into TorrentToMedia: %s", args) logger.debug("Options passed into TorrentToMedia: %s" % (args))
# Post-Processing Result # Post-Processing Result
result = 0 result = 0
@ -325,18 +325,18 @@ def main(args):
if nzbtomedia.CFG[section][category].isenabled(): if nzbtomedia.CFG[section][category].isenabled():
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
logger.postprocess("Running %s:%s as a manual run for folder %s ...", section, category, dirName) logger.postprocess("Running %s:%s as a manual run for folder %s ..." % (section, category, dirName))
results = processTorrent(dirName, os.path.basename(dirName), category, inputHash, inputID, clientAgent) results = processTorrent(dirName, os.path.basename(dirName), category, inputHash, inputID, clientAgent)
if results != 0: if results != 0:
result = results result = results
logger.error("A problem was reported when trying to manually run %s:%s.", section, category) logger.error("A problem was reported when trying to manually run %s:%s." % (section, category))
else: else:
logger.warning("%s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) logger.warning("%s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ..." % (section, category))
if result == 0: if result == 0:
logger.postprocess("The %s script completed successfully.", args[0]) logger.postprocess("The %s script completed successfully." % (args[0]))
else: else:
logger.error("A problem was reported in the %s script.", args[0]) logger.error("A problem was reported in the %s script." % (args[0]))
sys.exit(result) sys.exit(result)

View file

@ -8,7 +8,8 @@
git_user = git_user =
git_branch = git_branch =
force_clean = 0 force_clean = 0
log_debug = 0
[CouchPotato] [CouchPotato]
#### autoProcessing for Movies #### autoProcessing for Movies
#### movie - category that gets called for post-processing with CPS #### movie - category that gets called for post-processing with CPS

View file

@ -286,27 +286,25 @@ from nzbtomedia import logger
# post-processing # post-processing
def process(nzbDir, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None): def process(nzbDir, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None):
result = 0
# auto-detect section # auto-detect section
section = nzbtomedia.CFG.findsection(inputCategory) 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]: if nzbtomedia.CFG["CouchPotato"][inputCategory]:
logger.postprocess("Calling CouchPotatoServer to post-process: %s", inputName)
result = autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory) result = autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory)
elif nzbtomedia.CFG["SickBeard", "NzbDrone"][inputCategory]: elif nzbtomedia.CFG["SickBeard", "NzbDrone"][inputCategory]:
logger.postprocess("Calling Sick-Beard to post-process: %s", inputName)
result = autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) result = autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
elif nzbtomedia.CFG["HeadPhones"][inputCategory]: elif nzbtomedia.CFG["HeadPhones"][inputCategory]:
logger.postprocess("Calling HeadPhones to post-process: %s", inputName)
result = autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory) result = autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory)
elif nzbtomedia.CFG["Mylar"][inputCategory]: elif nzbtomedia.CFG["Mylar"][inputCategory]:
logger.postprocess("Calling Mylar to post-process: %s", inputName)
result = autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) result = autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
elif nzbtomedia.CFG["Gamez"][inputCategory]: elif nzbtomedia.CFG["Gamez"][inputCategory]:
logger.postprocess("Calling Gamez to post-process: %s", inputName)
result = autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory) result = autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory)
else:
logger.postprocess("We could not find a section with the download category of %s in your autoProcessMedia.cfg. Exiting.", inputCategory)
result = -1
if result == 0: if result == 0:
# Clean up any leftover files # Clean up any leftover files
@ -321,22 +319,21 @@ def main(args, section=None):
# clientAgent for NZBs # clientAgent for NZBs
clientAgent = nzbtomedia.NZB_CLIENTAGENT clientAgent = nzbtomedia.NZB_CLIENTAGENT
logger.postprocess("#########################################################") logger.info("#########################################################")
logger.postprocess("## ..::[%s]::.. CLIENT:%s ## STARTING", args[0], clientAgent) logger.info("## ..::[%s]::.. ##" % os.path.basename(__file__))
logger.postprocess("#########################################################") logger.info("#########################################################")
# debug command line options # debug command line options
logger.debug("Options passed into nzbToMedia: %s", args) logger.debug("Options passed into nzbToMedia: %s" % args)
# Post-Processing Result # Post-Processing Result
result = 0 result = 0
status = 0 status = 0
# NZBGet V11+ # NZBGet V11+
# Check if the script is called from nzbget 11.0 or later # Check if the script is called from nzbget 11.0 or later
if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5] < '11.0': if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5] < '11.0':
logger.postprocess("Script triggered from NZBGet (11.0 or later).") logger.info("Script triggered from NZBGet (11.0 or later).")
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
@ -345,7 +342,7 @@ def main(args, section=None):
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
logger.warning("Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
logger.postprocess("Please check your Par-repair settings for future downloads.") logger.info("Please check your Par-repair settings for future downloads.")
sys.exit(nzbtomedia.NZBGET_POSTPROCESS_NONE) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_NONE)
if os.environ['NZBPP_PARSTATUS'] == '1' or os.environ['NZBPP_PARSTATUS'] == '4': if os.environ['NZBPP_PARSTATUS'] == '1' or os.environ['NZBPP_PARSTATUS'] == '4':
@ -362,16 +359,16 @@ def main(args, section=None):
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
logger.warning("Download health is compromised and Par-check/repair disabled or no .par2 files found. Setting status \"failed\"") logger.warning("Download health is compromised and Par-check/repair disabled or no .par2 files found. Setting status \"failed\"")
logger.postprocess("Please check your Par-check/repair settings for future downloads.") logger.info("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
logger.postprocess("Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") logger.info("Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful")
logger.postprocess("Please check your Par-check/repair settings for future downloads.") logger.info("Please check your Par-check/repair settings for future downloads.")
# Check if destination directory exists (important for reprocessing of history items) # Check if destination directory exists (important for reprocessing of history items)
if not os.path.isdir(os.environ['NZBPP_DIRECTORY']): if not os.path.isdir(os.environ['NZBPP_DIRECTORY']):
logger.error("Nothing to post-process: destination directory %s doesn't exist. Setting status \"failed\"", os.environ['NZBPP_DIRECTORY']) logger.error("Nothing to post-process: destination directory %s doesn't exist. Setting status failed" % (os.environ['NZBPP_DIRECTORY']))
status = 1 status = 1
# Check for download_id to pass to CouchPotato # Check for download_id to pass to CouchPotato
@ -393,7 +390,7 @@ def main(args, section=None):
# 6 Group that the NZB was posted in e.g. alt.binaries.x # 6 Group that the NZB was posted in e.g. alt.binaries.x
# 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2 # 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2
clientAgent = 'sabnzbd' clientAgent = 'sabnzbd'
logger.postprocess("Script triggered from SABnzbd") logger.info("Script triggered from SABnzbd")
result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent, download_id='') result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent, download_id='')
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(args) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS: elif len(args) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
@ -407,7 +404,7 @@ def main(args, section=None):
# 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2 # 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2
# 8 Failure URL # 8 Failure URL
clientAgent = 'sabnzbd' clientAgent = 'sabnzbd'
logger.postprocess("Script triggered from SABnzbd 0.7.17+") logger.info("Script triggered from SABnzbd 0.7.17+")
result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent, download_id='') result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent, download_id='')
else: else:
# Perform Manual Run # Perform Manual Run
@ -420,21 +417,20 @@ def main(args, section=None):
if nzbtomedia.CFG[section][category].isenabled(): if nzbtomedia.CFG[section][category].isenabled():
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
logger.postprocess("nzbToMedia running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.info("Starting manual run for %s:%s - Folder:%s" % (section, category, dirName))
results = process(dirName, os.path.basename(dirName), 0, clientAgent=clientAgent, inputCategory=category) results = process(dirName, os.path.basename(dirName), 0, clientAgent=clientAgent, inputCategory=category)
if results != 0: if results != 0:
logger.error("A problem was reported when trying to manually run %s:%s.", section, category) logger.error("A problem was reported when trying to perform a manual run for %s:%s." % (section, category))
result = results result = results
else: else:
logger.postprocess("nzbToMedia %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) logger.debug("nzbToMedia %s:%s is DISABLED" % (section, category))
if result == 0: if result == 0:
logger.postprocess("The %s script completed successfully.", args[0]) logger.info("The %s script completed successfully." % args[0])
if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11 if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11
sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
logger.error("A problem was reported in the %s script.", args[0]) logger.error("A problem was reported in the %s script." % args[0])
if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11 if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11
sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -11,15 +11,15 @@ class Transcoder:
ffmpeg = os.path.join(os.path.dirname(sys.argv[0]), 'ffmpeg\\bin\\ffmpeg.exe') # note, will need to package in this dir. ffmpeg = os.path.join(os.path.dirname(sys.argv[0]), 'ffmpeg\\bin\\ffmpeg.exe') # note, will need to package in this dir.
useNiceness = False useNiceness = False
if not os.path.isfile(ffmpeg): # problem if not os.path.isfile(ffmpeg): # problem
logger.error("ffmpeg not found. ffmpeg needs to be located at: %s", ffmpeg) logger.error("ffmpeg not found. ffmpeg needs to be located at: %s" % (ffmpeg))
logger.info("Cannot transcode files in folder %s", dirName) logger.info("Cannot transcode files in folder %s" % (dirName))
return 1 # failure return 1 # failure
else: else:
if call(['which', 'ffmpeg']) != 0: if call(['which', 'ffmpeg']) != 0:
res = call([os.path.join(os.path.dirname(sys.argv[0]),'getffmpeg.sh')]) res = call([os.path.join(os.path.dirname(sys.argv[0]),'getffmpeg.sh')])
if res or call(['which', 'ffmpeg']) != 0: # did not install or ffmpeg still not found. if res or call(['which', 'ffmpeg']) != 0: # did not install or ffmpeg still not found.
logger.error("Failed to install ffmpeg. Please install manually") logger.error("Failed to install ffmpeg. Please install manually")
logger.info("Cannot transcode files in folder %s", dirName) logger.info("Cannot transcode files in folder %s" % (dirName))
return 1 # failure return 1 # failure
else: else:
ffmpeg = 'ffmpeg' ffmpeg = 'ffmpeg'
@ -41,7 +41,7 @@ class Transcoder:
name, ext = os.path.splitext(filePath) name, ext = os.path.splitext(filePath)
if ext in nzbtomedia.MEDIACONTAINER: # If the file is a video file if ext in nzbtomedia.MEDIACONTAINER: # If the file is a video file
if ext in nzbtomedia.IGNOREEXTENSIONS: if ext in nzbtomedia.IGNOREEXTENSIONS:
logger.info("No need to transcode video type %s", ext) logger.info("No need to transcode video type %s" % (ext))
continue continue
if ext == outputVideoExtension: # we need to change the name to prevent overwriting itself. if ext == outputVideoExtension: # we need to change the name to prevent overwriting itself.
outputVideoExtension = '-transcoded' + outputVideoExtension # adds '-transcoded.ext' outputVideoExtension = '-transcoded' + outputVideoExtension # adds '-transcoded.ext'
@ -96,26 +96,26 @@ class Transcoder:
os.remove(newfilePath) os.remove(newfilePath)
except OSError, e: except OSError, e:
if e.errno != errno.ENOENT: # Ignore the error if it's just telling us that the file doesn't exist if e.errno != errno.ENOENT: # Ignore the error if it's just telling us that the file doesn't exist
logger.debug("Error when removing transcoding target: %s", e) logger.debug("Error when removing transcoding target: %s" % (e))
except Exception, e: except Exception, e:
logger.debug("Error when removing transcoding target: %s", e) logger.debug("Error when removing transcoding target: %s" % (e))
logger.info("Transcoding video: %s", file) logger.info("Transcoding video: %s" % (file))
cmd = "" cmd = ""
for item in command: for item in command:
cmd = cmd + " " + item cmd = cmd + " " + item
logger.debug("calling command:%s", cmd) logger.debug("calling command:%s" % (cmd))
result = 1 # set result to failed in case call fails. result = 1 # set result to failed in case call fails.
try: try:
result = call(command) result = call(command)
except: except:
logger.error("Transcoding of video %s has failed", filePath) logger.error("Transcoding of video %s has failed" % (filePath))
if result == 0: if result == 0:
logger.info("Transcoding of video %s to %s succeeded", filePath, newfilePath) logger.info("Transcoding of video %s to %s succeeded" % (filePath, newfilePath))
if nzbtomedia.DUPLICATE == 0: # we get rid of the original file if nzbtomedia.DUPLICATE == 0: # we get rid of the original file
os.unlink(filePath) os.unlink(filePath)
else: else:
logger.error("Transcoding of video %s to %s failed", filePath, newfilePath) logger.error("Transcoding of video %s to %s failed" % (filePath, newfilePath))
# this will be 0 (successful) it all are successful, else will return a positive integer for failure. # this will be 0 (successful) it all are successful, else will return a positive integer for failure.
final_result = final_result + result final_result = final_result + result
return final_result return final_result

View file

@ -31,15 +31,16 @@ NZBGET_POSTPROCESS_NONE = 95
# config constants # config constants
CFG = None CFG = None
CFG_LOGGING = None CFG_LOGGING = None
APP_FILENAME = '' APP_FILENAME = None
APP_NAME = '' APP_NAME = None
PROGRAM_DIR = '' PROGRAM_DIR = None
LOG_DIR = '' LOG_DIR = None
LOG_FILE = '' LOG_FILE = None
CONFIG_FILE = '' LOG_DEBUG = None
CONFIG_SPEC_FILE = '' CONFIG_FILE = None
CONFIG_MOVIE_FILE = '' CONFIG_SPEC_FILE = None
CONFIG_TV_FILE = '' CONFIG_MOVIE_FILE = None
CONFIG_TV_FILE = None
SYS_ENCODING = None SYS_ENCODING = None
SYS_ARGV = None SYS_ARGV = None
@ -129,14 +130,11 @@ def initialize(section=None):
TRANSCODE, GIT_PATH, GIT_USER, GIT_BRANCH, GIT_REPO, SYS_ENCODING, NZB_CLIENTAGENT, SABNZBDHOST, SABNZBDPORT, SABNZBDAPIKEY, \ TRANSCODE, GIT_PATH, GIT_USER, GIT_BRANCH, GIT_REPO, SYS_ENCODING, NZB_CLIENTAGENT, SABNZBDHOST, SABNZBDPORT, SABNZBDAPIKEY, \
DUPLICATE, IGNOREEXTENSIONS, OUTPUTVIDEOEXTENSION, OUTPUTVIDEOCODEC, OUTPUTVIDEOPRESET, OUTPUTVIDEOFRAMERATE, \ DUPLICATE, IGNOREEXTENSIONS, OUTPUTVIDEOEXTENSION, OUTPUTVIDEOCODEC, OUTPUTVIDEOPRESET, OUTPUTVIDEOFRAMERATE, \
OUTPUTVIDEOBITRATE, OUTPUTAUDIOCODEC, OUTPUTAUDIOBITRATE, OUTPUTSUBTITLECODEC, OUTPUTFASTSTART, OUTPUTQUALITYPERCENT, \ OUTPUTVIDEOBITRATE, OUTPUTAUDIOCODEC, OUTPUTAUDIOBITRATE, OUTPUTSUBTITLECODEC, OUTPUTFASTSTART, OUTPUTQUALITYPERCENT, \
NICENESS, MEDIAEXTENSIONS NICENESS, MEDIAEXTENSIONS, LOG_DEBUG
if __INITIALIZED__: if __INITIALIZED__:
return False return False
# add our custom libs to the system path
sys.path.insert(0, os.path.abspath(os.path.join(PROGRAM_DIR, 'lib')))
# init preliminaries # init preliminaries
SYS_ARGV = sys.argv[1:] SYS_ARGV = sys.argv[1:]
APP_FILENAME = sys.argv[0] APP_FILENAME = sys.argv[0]
@ -144,10 +142,13 @@ def initialize(section=None):
PROGRAM_DIR = os.path.dirname(os.path.normpath(os.path.abspath(os.path.join(__file__, os.pardir)))) PROGRAM_DIR = os.path.dirname(os.path.normpath(os.path.abspath(os.path.join(__file__, os.pardir))))
LOG_DIR = os.path.join(PROGRAM_DIR, 'logs') LOG_DIR = os.path.join(PROGRAM_DIR, 'logs')
LOG_FILE = os.path.join(LOG_DIR, 'postprocess.log') LOG_FILE = os.path.join(LOG_DIR, 'postprocess.log')
CONFIG_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg") CONFIG_FILE = os.path.join(PROGRAM_DIR, 'autoProcessMedia.cfg')
CONFIG_SPEC_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg.spec") CONFIG_SPEC_FILE = os.path.join(PROGRAM_DIR, 'autoProcessMedia.cfg.spec')
CONFIG_MOVIE_FILE = os.path.join(PROGRAM_DIR, "autoProcessMovie.cfg") CONFIG_MOVIE_FILE = os.path.join(PROGRAM_DIR, 'autoProcessMovie.cfg')
CONFIG_TV_FILE = os.path.join(PROGRAM_DIR, "autoProcessTv.cfg") CONFIG_TV_FILE = os.path.join(PROGRAM_DIR, 'autoProcessTv.cfg')
# add our custom libs to the system path
sys.path.insert(0, os.path.abspath(os.path.join(PROGRAM_DIR, 'lib')))
try: try:
locale.setlocale(locale.LC_ALL, "") locale.setlocale(locale.LC_ALL, "")
@ -179,19 +180,22 @@ def initialize(section=None):
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. # run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
if not config.migrate(): if not config.migrate():
logger.error("Unable to migrate config file %s, exiting ...", CONFIG_FILE) logger.error("Unable to migrate config file %s, exiting ..." % (CONFIG_FILE))
sys.exit(-1) sys.exit(-1)
# run migrate to convert NzbGet data from old cfg style to new cfg style # run migrate to convert NzbGet data from old cfg style to new cfg style
if os.environ.has_key('NZBOP_SCRIPTDIR'): if os.environ.has_key('NZBOP_SCRIPTDIR'):
if not config.addnzbget(): if not config.addnzbget():
logger.error("Unable to migrate NzbGet config file %s, exiting ...", CONFIG_FILE) logger.error("Unable to migrate NzbGet config file %s, exiting ..." % (CONFIG_FILE))
sys.exit(-1) sys.exit(-1)
# load newly migrated config # load newly migrated config
logger.info("Loading config from %s", CONFIG_FILE) logger.info("Loading config from %s" % CONFIG_FILE)
CFG = config() CFG = config()
# Enable/Disable DEBUG Logging
LOG_DEBUG = int(CFG['General']['log_debug'])
# Set Version and GIT variables # Set Version and GIT variables
NZBTOMEDIA_VERSION = '9.3' NZBTOMEDIA_VERSION = '9.3'
VERSION_NOTIFY = int(CFG['General']['version_notify']) VERSION_NOTIFY = int(CFG['General']['version_notify'])

View file

@ -7,21 +7,13 @@ from nzbtomedia import logger
class autoProcessComics: class autoProcessComics:
def processEpisode(self, dirName, nzbName=None, status=0, clientAgent='manual', inputCategory=None): def processEpisode(self, dirName, nzbName=None, status=0, clientAgent='manual', inputCategory=None):
if dirName is None:
logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section # auto-detect correct section
section = nzbtomedia.CFG.findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
logger.error( logger.error(
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory)
return 1 return 1
logger.postprocess("#########################################################")
logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory)
logger.postprocess("#########################################################")
host = nzbtomedia.CFG[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
port = nzbtomedia.CFG[section][inputCategory]["port"] port = nzbtomedia.CFG[section][inputCategory]["port"]
username = nzbtomedia.CFG[section][inputCategory]["username"] username = nzbtomedia.CFG[section][inputCategory]["username"]
@ -59,16 +51,16 @@ class autoProcessComics:
protocol = "http://" protocol = "http://"
url = "%s%s:%s%s/post_process" % (protocol, host, port, web_root) url = "%s%s:%s%s/post_process" % (protocol, host, port, web_root)
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url), section)
try: try:
r = requests.get(url, params=params, auth=(username, password), stream=True) r = requests.get(url, params=params, auth=(username, password), stream=True)
except requests.ConnectionError: except requests.ConnectionError:
logger.error("Unable to open URL") logger.error("Unable to open URL", section)
return 1 # failure return 1 # failure
for line in r.iter_lines(): for line in r.iter_lines():
if line: logger.postprocess("%s", line) if line: logger.postprocess("%s" % (line), section)
time.sleep(60) #wait 1 minute for now... need to see just what gets logged and how long it takes to process time.sleep(60) #wait 1 minute for now... need to see just what gets logged and how long it takes to process
return 0 # Success return 0 # Success

View file

@ -13,13 +13,9 @@ class autoProcessGames:
section = nzbtomedia.CFG.findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
logger.error( logger.error(
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory)
return 1 return 1
logger.postprocess("#########################################################")
logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory)
logger.postprocess("#########################################################")
status = int(status) status = int(status)
host = nzbtomedia.CFG[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
@ -59,7 +55,7 @@ class autoProcessGames:
params['db_id'] = gamezID params['db_id'] = gamezID
params['status'] = downloadStatus params['status'] = downloadStatus
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url),section)
try: try:
r = requests.get(url, params=params) r = requests.get(url, params=params)
@ -68,11 +64,11 @@ class autoProcessGames:
return 1 # failure return 1 # failure
result = r.json() result = r.json()
logger.postprocess("%s", result) logger.postprocess("%s" % (result),section)
if result['success']: if result['success']:
logger.postprocess("Status for %s has been set to %s in Gamez", gamezID, downloadStatus) logger.postprocess("SUCCESS: Status for %s has been set to %s in Gamez" % (gamezID, downloadStatus),section)
return 0 # Success return 0 # Success
else: else:
logger.error("Status for %s has NOT been updated in Gamez", gamezID) logger.error("FAILED: Status for %s has NOT been updated in Gamez" % (gamezID),section)
return 1 # failure return 1 # failure

View file

@ -1,102 +1,62 @@
import os import os
import re
import time import time
import nzbtomedia import nzbtomedia
from lib import requests from lib import requests
from nzbtomedia.Transcoder import Transcoder from nzbtomedia.Transcoder import Transcoder
from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, create_torrent_class, clean_nzbname from nzbtomedia.nzbToMediaUtil import convert_to_ascii, delete, find_imdbid, find_download
from nzbtomedia import logger from nzbtomedia import logger
class autoProcessMovie: class autoProcessMovie:
def find_imdbid(self, dirName, nzbName): def get_releases(self, baseURL, imdbid=None, download_id=None):
imdbid = None results = {}
nzbName = clean_nzbname(nzbName)
# find imdbid in dirName
m = re.search('(tt\d{7})', dirName)
if m:
imdbid = m.group(1)
logger.postprocess("Found movie id %s in directory", imdbid)
return imdbid
# find imdbid in nzbName
m = re.search('(tt\d{7})', nzbName)
if m:
imdbid = m.group(1)
logger.postprocess("Found imdbid %s in name", imdbid)
return imdbid
m = re.search("^(.+)\W(\d{4})", os.path.basename(dirName))
if m:
title = m.group(1)
year = m.group(2)
url = "http://www.omdbapi.com"
logger.debug("Opening URL: %s", url)
try:
r = requests.get(url, params={'y':year, 't':title})
except requests.ConnectionError:
logger.error("Unable to open URL")
return
results = r.json()
try:
imdbid = results['imdbID']
except:pass
if imdbid:
return imdbid
def get_releases(self, baseURL, download_id, dirName, nzbName):
releases = {}
params = {} params = {}
imdbid = self.find_imdbid(dirName, nzbName)
# determin cmd and params to send to CouchPotato to get our results # determin cmd and params to send to CouchPotato to get our results
section = 'movies' section = 'movies'
cmd = "/media.list" cmd = "/media.list"
params['status'] = 'active,done'
if imdbid: if imdbid:
section = 'media' section = 'media'
cmd = "/media.get" cmd = "/media.get"
params['id'] = imdbid params['id'] = imdbid
if download_id:
params['release_status'] = 'snatched,downloaded'
url = baseURL + cmd url = baseURL + cmd
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % url)
try: try:
r = requests.get(url, params=params) r = requests.get(url, params=params)
except requests.ConnectionError: except requests.ConnectionError:
logger.error("Unable to open URL") logger.error("Unable to open URL %s" % url)
return return
results = r.json() result = r.json()
movies = results[section] movies = result[section]
if not isinstance(movies, list): if not isinstance(movies, list):
movies = [movies] movies = [movies]
for movie in movies: for movie in movies:
if movie['status'] not in ['active','done']:
continue
releases = movie['releases'] releases = movie['releases']
if not isinstance(releases, list):
releases = [releases]
for release in releases: for release in releases:
if release['status'] not in ['snatched','downloaded']:
continue
try: try:
if download_id: if download_id:
if download_id != release['download_info']['id']: if download_id != release['download_info']['id']:
continue continue
id = release['_id'] id = release['_id']
releases[id] = release results[id] = release
except:continue except:continue
return releases # Search downloads on clients for a match to try and narrow our results down to 1
for id, x in results.items():
try:
if not find_download(str(x['download_info']['downloader']).lower(),x['download_info']['id']):
results.pop(id)
except:continue
return results
def releases_diff(self, dict_a, dict_b): def releases_diff(self, dict_a, dict_b):
return dict([ return dict([
@ -109,21 +69,13 @@ class autoProcessMovie:
]) ])
def process(self, dirName, nzbName=None, status=0, clientAgent = "manual", download_id = "", inputCategory=None): def process(self, dirName, nzbName=None, status=0, clientAgent = "manual", download_id = "", inputCategory=None):
if dirName is None:
logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section # auto-detect correct section
section = nzbtomedia.CFG.findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
logger.error( logger.error(
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory)
return 1 return 1
logger.postprocess("#########################################################")
logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory)
logger.postprocess("#########################################################")
status = int(status) status = int(status)
host = nzbtomedia.CFG[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
@ -141,17 +93,11 @@ class autoProcessMovie:
web_root = nzbtomedia.CFG[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except: except:
web_root = "" web_root = ""
try:
transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"])
except:
transcode = 0
try: try:
remote_path = nzbtomedia.CFG[section][inputCategory]["remote_path"] remote_path = nzbtomedia.CFG[section][inputCategory]["remote_path"]
except: except:
remote_path = None remote_path = None
nzbName = str(nzbName) # make sure it is a string
if ssl: if ssl:
protocol = "https://" protocol = "https://"
else: else:
@ -159,10 +105,11 @@ class autoProcessMovie:
baseURL = "%s%s:%s%s/api/%s" % (protocol, host, port, web_root, apikey) baseURL = "%s%s:%s%s/api/%s" % (protocol, host, port, web_root, apikey)
releases = self.get_releases(baseURL, download_id, dirName, nzbName) imdbid = find_imdbid(dirName,nzbName)
releases = self.get_releases(baseURL, imdbid, download_id)
if not releases: if not releases:
logger.error("Could not find any releases marked as WANTED on CouchPotato to compare changes against %s, skipping ...", nzbName) logger.error("Could not find any releases marked as WANTED matching %s, skipping ..." % nzbName, section)
return 1 return 1
# try to get release_id, media_id, and download_id if one was not passed in # try to get release_id, media_id, and download_id if one was not passed in
@ -172,19 +119,19 @@ class autoProcessMovie:
try: try:
release_id = releases.keys()[0] release_id = releases.keys()[0]
media_id = releases[release_id]['media_id'] media_id = releases[release_id]['media_id']
download_id = releases['download_info']['id'] download_id = releases[release_id]['download_info']['id']
except:pass except:pass
process_all_exceptions(nzbName.lower(), dirName) process_all_exceptions(nzbName.lower(), dirName)
nzbName, dirName = convert_to_ascii(nzbName, dirName) nzbName, dirName = convert_to_ascii(nzbName, dirName)
if status == 0: if status == 0:
if transcode == 1: if nzbtomedia.TRANSCODE == 1:
result = Transcoder().Transcode_directory(dirName) result = Transcoder().Transcode_directory(dirName)
if result == 0: if result == 0:
logger.debug("Transcoding succeeded for files in %s", dirName) logger.debug("Transcoding succeeded for files in %s" % (dirName),section)
else: else:
logger.warning("Transcoding failed for files in %s", dirName) logger.warning("Transcoding failed for files in %s" % (dirName),section)
if method == "manage": if method == "manage":
command = "/manage.update" command = "/manage.update"
@ -201,86 +148,88 @@ class autoProcessMovie:
dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/") dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/")
params['media_folder'] = dirName_new params['media_folder'] = dirName_new
url = baseURL + command url = "%s%s" % (baseURL, command)
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url), section)
logger.postprocess("Attempting to perform a %s scan on CouchPotato for %s", method, nzbName) logger.postprocess("Attempting to perform a %s scan for %s" % (method, nzbName), section)
try: try:
r = requests.get(url, params=params) r = requests.get(url, params=params)
except requests.ConnectionError: except requests.ConnectionError:
logger.error("Unable to open URL") logger.error("Unable to open URL", section)
return 1 # failure return 1 # failure
result = r.json() result = r.json()
if result['success']: if result['success']:
logger.postprocess("SUCCESS: %s scan started on CouchPotatoServer for %s", method, nzbName) logger.postprocess("SUCCESS: Started %s scan on folder %s, please wait ..." % (method, dirName), section)
else: else:
logger.error("FAILED: %s scan has NOT started on CouchPotato for %s. Exiting ...", method, nzbName) logger.error("FAILED: %s scan was unable to start for folder %s. exiting!" % (method, dirName), section)
return 1 # failure return 1 # failure
else: else:
logger.postprocess("Download of %s has failed.", nzbName) logger.postprocess("FAILED DOWNLOAD DETECTED FOR %s" % (nzbName), section)
if delete_failed and os.path.isdir(dirName) and not os.path.dirname(dirName) == dirName: if delete_failed and os.path.isdir(dirName) and not os.path.dirname(dirName) == dirName:
logger.postprocess("Deleting failed files and folder %s", dirName) logger.postprocess("Deleting failed files and folder %s" % dirName, section)
delete(dirName) delete(dirName)
if not download_id: if not download_id:
logger.warning("Could not find a movie in the database for release %s", nzbName) logger.error("Could not find a downloaded movie in the database matching %s, exiting!" % nzbName, section)
logger.warning("Please manually ignore this release and refresh the wanted movie from CouchPotato, Exiting ...")
return 1 # failure return 1 # failure
logger.postprocess("Ignoring current failed release %s ...", nzbName) logger.postprocess("Setting failed release %s to ignored ..." % (nzbName), section)
url = baseURL + "/release.ignore" url = baseURL + "/release.ignore"
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url), section)
try: try:
r = requests.get(url, params={'id': release_id}) r = requests.get(url, params={'id': release_id})
except requests.ConnectionError: except requests.ConnectionError:
logger.error("Unable to open URL") logger.error("Unable to open URL %s" % (url), section)
return 1 # failure return 1 # failure
result = r.json() result = r.json()
if result['success']: if result['success']:
logger.postprocess("%s has been set to ignored on CouchPotato", nzbName) logger.postprocess("SUCCESS: %s has been set to ignored ..." % (nzbName), section)
else: else:
logger.warning("Failed to ignore %s on CouchPotato ...", nzbName) logger.warning("FAILED: Unable to set %s to ignored!" % (nzbName), section)
logger.postprocess("Snatching next highest ranked release on CouchPotato ...") logger.postprocess("Trying to snatch the next highest ranked release.", section)
url = baseURL + "/movie.searcher.try_next" url = "%s/movie.searcher.try_next" % (baseURL)
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url), section)
try: try:
r = requests.get(url, params={'media_id': media_id}) r = requests.get(url, params={'media_id': media_id})
except requests.ConnectionError: except requests.ConnectionError:
logger.error("Unable to open URL") logger.error("Unable to open URL %s" % (url), section)
return 1 # failure return 1 # failure
result = r.json() result = r.json()
if result['success']: if result['success']:
logger.postprocess("CouchPotato successfully snatched the next highest release above %s ...", nzbName) logger.postprocess("SUCCESS: Snatched the next highest release ...", section)
return 0 return 0
else: else:
logger.postprocess("CouchPotato was unable to find a higher release then %s to snatch ...", nzbName) logger.postprocess("FAILED: Unable to find a higher ranked release then %s to snatch!" % (nzbName), section)
return 1 return 1
# we will now check to see if CPS has finished renaming before returning to TorrentToMedia and unpausing. # we will now check to see if CPS has finished renaming before returning to TorrentToMedia and unpausing.
timeout = time.time() + 60 * wait_for timeout = time.time() + 60 * wait_for
while (time.time() < timeout): # only wait 2 (default) minutes, then return. while (time.time() < timeout): # only wait 2 (default) minutes, then return.
releases_current = self.get_releases(baseURL, download_id, dirName, nzbName) releases_current = self.get_releases(baseURL, imdbid, download_id)
releasesDiff = self.releases_diff(releases, releases_current) releasesDiff = self.releases_diff(releases, releases_current)
logger.postprocess("Checking for status change, please stand by ...", section)
if releasesDiff: # Something has changed. CPS must have processed this movie. if releasesDiff: # Something has changed. CPS must have processed this movie.
release_status = releasesDiff[releasesDiff.keys()[0]]['status'] try:
logger.postprocess("SUCCESS: Release %s marked as [%s] on CouchPotato", nzbName, release_status) release_status = releasesDiff[releasesDiff.keys()[0]]['status']
return 0 # success logger.postprocess("SUCCESS: Release %s has now been marked with a status of [%s]" % (nzbName, str(release_status).upper()), section)
return 0 # success
except:pass
# pause and let CouchPotatoServer catch its breath # pause and let CouchPotatoServer catch its breath
time.sleep(10 * wait_for) time.sleep(10 * wait_for)
# The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now. # The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now.
logger.warning("The movie does not appear to have changed status after %s minutes. Please check CouchPotato Logs", wait_for) logger.warning("%s does not appear to have changed status after %s minutes, Please check your logs." % (nzbName, wait_for), section)
return 1 # failure return 1 # failure

View file

@ -7,7 +7,7 @@ from nzbtomedia import logger
class autoProcessMusic: class autoProcessMusic:
def get_status(self, baseURL, apikey, dirName): def get_status(self, baseURL, apikey, dirName):
logger.debug("Attempting to get current status for release:%s", os.path.basename(dirName)) logger.debug("Attempting to get current status for release:%s" % (os.path.basename(dirName)))
url = baseURL url = baseURL
@ -15,7 +15,7 @@ class autoProcessMusic:
params['apikey'] = apikey params['apikey'] = apikey
params['cmd'] = "getHistory" params['cmd'] = "getHistory"
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url))
try: try:
r = requests.get(url, params=params) r = requests.get(url, params=params)
@ -31,21 +31,13 @@ class autoProcessMusic:
except:pass except:pass
def process(self, dirName, nzbName=None, status=0, clientAgent="manual", inputCategory=None): def process(self, dirName, nzbName=None, status=0, clientAgent="manual", inputCategory=None):
if dirName is None:
logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section # auto-detect correct section
section = nzbtomedia.CFG.findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if len(section) == 0: if len(section) == 0:
logger.error( logger.error(
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % (inputCategory))
return 1 return 1
logger.postprocess("#########################################################")
logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory)
logger.postprocess("#########################################################")
status = int(status) status = int(status)
host = nzbtomedia.CFG[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
@ -92,29 +84,29 @@ class autoProcessMusic:
if release_status: if release_status:
if release_status not in ["unprocessed", "snatched"]: if release_status not in ["unprocessed", "snatched"]:
logger.warning("%s is marked with a status of %s on HeadPhones, skipping ...", nzbName, release_status) logger.warning("%s is marked with a status of %s, skipping ..." % (nzbName, release_status),section)
return 0 return 0
else: else:
logger.error("Could not find a status for %s on HeadPhones", nzbName) logger.error("Could not find a status for %s" % (nzbName),section)
return 1 return 1
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url),section)
try: try:
r = requests.get(url, params=params) r = requests.get(url, params=params)
except requests.ConnectionError: except requests.ConnectionError:
logger.error("Unable to open URL") logger.error("Unable to open URL %s" % (url),section)
return 1 # failure return 1 # failure
logger.postprocess("HeadPhones returned %s", r.text) logger.debug("Result: %s" % (r.text),section)
if r.text == "OK": if r.text == "OK":
logger.postprocess("Post-processing started on HeadPhones for %s in folder %s", nzbName, dirName) logger.postprocess("SUCCESS: Post-Processing started for %s in folder %s ..." % (nzbName, dirName),section)
else: else:
logger.error("Post-proecssing has NOT started on HeadPhones for %s in folder %s. Exiting", nzbName, dirName) logger.error("FAILED: Post-Processing has NOT started for %s in folder %s. exiting!" % (nzbName, dirName),section)
return 1 # failure return 1 # failure
else: else:
logger.postprocess("The download failed. Nothing to process") logger.warning("FAILED DOWNLOAD DETECTED", section)
return 0 # Success (as far as this script is concerned) return 0 # Success (as far as this script is concerned)
# we will now wait 1 minutes for this album to be processed before returning to TorrentToMedia and unpausing. # we will now wait 1 minutes for this album to be processed before returning to TorrentToMedia and unpausing.
@ -122,11 +114,11 @@ class autoProcessMusic:
while (time.time() < timeout): # only wait 2 (default) minutes, then return. while (time.time() < timeout): # only wait 2 (default) minutes, then return.
current_status = self.get_status(url, apikey, dirName) current_status = self.get_status(url, apikey, dirName)
if current_status is not None and current_status != release_status: # Something has changed. CPS must have processed this movie. if current_status is not None and current_status != release_status: # Something has changed. CPS must have processed this movie.
logger.postprocess("SUCCESS: This release is now marked as status [%s] in HeadPhones",current_status) logger.postprocess("SUCCESS: This release is now marked as status [%s]" % (current_status),section)
return 0 return 0
time.sleep(10 * wait_for) time.sleep(10 * wait_for)
# The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now. # The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now.
logger.warning("The music album does not appear to have changed status after %s minutes. Please check HeadPhones Logs",2) logger.warning("The music album does not appear to have changed status after %s minutes. Please check your Logs" % (wait_for))
return 1 # failure return 1 # failure

View file

@ -10,21 +10,13 @@ from nzbtomedia import logger
class autoProcessTV: class autoProcessTV:
def processEpisode(self, dirName, nzbName=None, failed=False, clientAgent = "manual", inputCategory=None): def processEpisode(self, dirName, nzbName=None, failed=False, clientAgent = "manual", inputCategory=None):
if dirName is None:
logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section # auto-detect correct section
section = nzbtomedia.CFG.findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
logger.error( logger.error(
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory)
return 1 return 1
logger.postprocess("#########################################################")
logger.postprocess("## ..::[%s]::.. :: CATEGORY:[%s]", section, inputCategory)
logger.postprocess("#########################################################")
# auto-detect correct fork # auto-detect correct fork
fork, fork_params = autoFork(inputCategory) fork, fork_params = autoFork(inputCategory)
@ -47,18 +39,10 @@ class autoProcessTV:
web_root = nzbtomedia.CFG[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except: except:
web_root = "" web_root = ""
try:
transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"])
except:
transcode = 0
try: try:
delete_failed = int(nzbtomedia.CFG[section][inputCategory]["delete_failed"]) delete_failed = int(nzbtomedia.CFG[section][inputCategory]["delete_failed"])
except: except:
delete_failed = 0 delete_failed = 0
try:
SampleIDs = (nzbtomedia.CFG["Extensions"]["SampleIDs"])
except:
SampleIDs = ['sample','-s.']
try: try:
nzbExtractionBy = nzbtomedia.CFG[section][inputCategory]["nzbExtractionBy"] nzbExtractionBy = nzbtomedia.CFG[section][inputCategory]["nzbExtractionBy"]
except: except:
@ -98,18 +82,18 @@ class autoProcessTV:
filePath = os.path.join(dirpath, file) filePath = os.path.join(dirpath, file)
fileExtension = os.path.splitext(file)[1] fileExtension = os.path.splitext(file)[1]
if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file
if is_sample(filePath, nzbName, nzbtomedia.MINSAMPLESIZE, SampleIDs): if is_sample(filePath, nzbName, nzbtomedia.MINSAMPLESIZE, nzbtomedia.SAMPLEIDS):
logger.debug("Removing sample file: %s", filePath) logger.debug("Removing sample file: %s" % (filePath), section)
os.unlink(filePath) # remove samples os.unlink(filePath) # remove samples
else: else:
video = video + 1 video = video + 1
if video > 0: # Check that a video exists. if not, assume failed. if video > 0: # Check that a video exists. if not, assume failed.
flatten(dirName) # to make sure SickBeard can find the video (not in sub-folder) flatten(dirName) # to make sure SickBeard can find the video (not in sub-folder)
elif clientAgent == "manual": elif clientAgent == "manual":
logger.warning("No media files found in directory %s to manually process.", dirName) logger.warning("No media files found in directory %s to manually process." % (dirName), section)
return 0 # Success (as far as this script is concerned) return 0 # Success (as far as this script is concerned)
else: else:
logger.warning("No media files found in directory %s. Processing this as a failed download", dirName) logger.warning("No media files found in directory %s. Processing this as a failed download" % (dirName), section)
status = int(1) status = int(1)
failed = True failed = True
@ -140,37 +124,36 @@ class autoProcessTV:
[fork_params.pop(k) for k,v in fork_params.items() if v is None] [fork_params.pop(k) for k,v in fork_params.items() if v is None]
if status == 0: if status == 0:
logger.postprocess("The download succeeded. Sending process request to %s", section) logger.postprocess("SUCCESS: The download succeeded, sending a post-process request", section)
else: else:
if fork in nzbtomedia.SICKBEARD_FAILED: if fork in nzbtomedia.SICKBEARD_FAILED:
logger.postprocess("The download failed. Sending 'failed' process request to SickBeard's %s branch", fork) logger.postprocess("FAILED: The download failed. Sending 'failed' process request to %s branch" % (fork), section)
else: else:
logger.postprocess("The download failed. SickBeard's %s branch does not handle failed downloads. Nothing to process", fork) logger.postprocess("FAILED: The download failed. %s branch does not handle failed downloads. Nothing to process" % (fork), section)
if delete_failed and os.path.isdir(dirName) and not os.path.dirname(dirName) == dirName: if delete_failed and os.path.isdir(dirName) and not os.path.dirname(dirName) == dirName:
logger.postprocess("Deleting failed files and folder %s", dirName) logger.postprocess("Deleting failed files and folder %s" % (dirName), section)
delete(dirName) delete(dirName)
return 0 # Success (as far as this script is concerned) return 0 # Success (as far as this script is concerned)
if status == 0 and transcode == 1: # only transcode successful downlaods if status == 0 and nzbtomedia.TRANSCODE == 1: # only transcode successful downlaods
result = Transcoder().Transcode_directory(dirName) result = Transcoder().Transcode_directory(dirName)
if result == 0: if result == 0:
logger.debug("Transcoding succeeded for files in %s", dirName) logger.debug("SUCCESS: Transcoding succeeded for files in %s" % (dirName), section)
else: else:
logger.warning("Transcoding failed for files in %s", dirName) logger.warning("FAILED: Transcoding failed for files in %s" % (dirName), section)
if ssl: if ssl:
protocol = "https://" protocol = "https://"
else: else:
protocol = "http://" protocol = "http://"
url = None url = None
if section == "SickBeard": if section == "SickBeard":
url = "%s%s:%s%s/home/postprocess/processEpisode" % (protocol,host,port,web_root) url = "%s%s:%s%s/home/postprocess/processEpisode" % (protocol,host,port,web_root)
elif section == "NzbDrone": elif section == "NzbDrone":
url = "%s%s:%s%s/api/command" % (protocol, host, port, web_root) url = "%s%s:%s%s/api/command" % (protocol, host, port, web_root)
logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s" % (url),section)
try: try:
r = None r = None
@ -181,13 +164,13 @@ class autoProcessTV:
headers = {"X-Api-Key": apikey} headers = {"X-Api-Key": apikey}
r = requests.get(url, params=params, headers=headers, stream=True) r = requests.get(url, params=params, headers=headers, stream=True)
except requests.ConnectionError: except requests.ConnectionError:
logger.error("Unable to open URL") logger.error("Unable to open URL: %s" % (url), section)
return 1 # failure return 1 # failure
for line in r.iter_lines(): for line in r.iter_lines():
if line: logger.postprocess("%s", line) if line: logger.postprocess("%s" % (line))
if status != 0 and delete_failed and not os.path.dirname(dirName) == dirName: if status != 0 and delete_failed and not os.path.dirname(dirName) == dirName:
logger.postprocess("Deleting failed files and folder %s", dirName) logger.postprocess("Deleting failed files and folder %s" % (dirName),section)
delete(dirName) delete(dirName)
return 0 # Success return 0 # Success

View file

@ -11,10 +11,10 @@ def os_platform():
# Author Credit: Matthew Scouten @ http://stackoverflow.com/a/7260315 # Author Credit: Matthew Scouten @ http://stackoverflow.com/a/7260315
true_platform = os.environ['PROCESSOR_ARCHITECTURE'] true_platform = os.environ['PROCESSOR_ARCHITECTURE']
try: try:
true_platform = os.environ["PROCESSOR_ARCHITEW6432"] true_platform = os.environ["PROCESSOR_ARCHITEW6432"]
except KeyError: except KeyError:
pass pass
#true_platform not assigned to if this does not exist #true_platform not assigned to if this does not exist
return true_platform return true_platform
@ -27,10 +27,13 @@ def extract(filePath, outputDestination):
platform = 'x86' platform = 'x86'
if not os.path.dirname(sys.argv[0]): if not os.path.dirname(sys.argv[0]):
chplocation = os.path.normpath(os.path.join(os.getcwd(), 'nzbtomedia/extractor/bin/chp.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')) sevenzipLocation = os.path.normpath(
os.path.join(os.getcwd(), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe'))
else: else:
chplocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/chp.exe')) chplocation = os.path.normpath(
sevenzipLocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) 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): if not os.path.exists(sevenzipLocation):
logger.error("EXTRACTOR: Could not find 7-zip, Exiting") logger.error("EXTRACTOR: Could not find 7-zip, Exiting")
return False return False
@ -39,11 +42,11 @@ def extract(filePath, outputDestination):
cmd_7zip = [sevenzipLocation, "x", "-y"] cmd_7zip = [sevenzipLocation, "x", "-y"]
else: else:
cmd_7zip = [chplocation, sevenzipLocation, "x", "-y"] cmd_7zip = [chplocation, sevenzipLocation, "x", "-y"]
ext_7zip = [".rar",".zip",".tar.gz","tgz",".tar.bz2",".tbz",".tar.lzma",".tlz",".7z",".xz"] ext_7zip = [".rar", ".zip", ".tar.gz", "tgz", ".tar.bz2", ".tbz", ".tar.lzma", ".tlz", ".7z", ".xz"]
EXTRACT_COMMANDS = dict.fromkeys(ext_7zip, cmd_7zip) EXTRACT_COMMANDS = dict.fromkeys(ext_7zip, cmd_7zip)
# Using unix # Using unix
else: else:
required_cmds=["unrar", "unzip", "tar", "unxz", "unlzma", "7zr", "bunzip2"] required_cmds = ["unrar", "unzip", "tar", "unxz", "unlzma", "7zr", "bunzip2"]
## Possible future suport: ## Possible future suport:
# gunzip: gz (cmd will delete original archive) # gunzip: gz (cmd will delete original archive)
## the following do not extract to dest dir ## the following do not extract to dest dir
@ -60,14 +63,14 @@ def extract(filePath, outputDestination):
".tar.lzma": ["tar", "--lzma", "-xf"], ".tlz": ["tar", "--lzma", "-xf"], ".tar.lzma": ["tar", "--lzma", "-xf"], ".tlz": ["tar", "--lzma", "-xf"],
".tar.xz": ["tar", "--xz", "-xf"], ".txz": ["tar", "--xz", "-xf"], ".tar.xz": ["tar", "--xz", "-xf"], ".txz": ["tar", "--xz", "-xf"],
".7z": ["7zr", "x"], ".7z": ["7zr", "x"],
} }
# Test command exists and if not, remove # Test command exists and if not, remove
if not os.getenv('TR_TORRENT_DIR'): if not os.getenv('TR_TORRENT_DIR'):
for cmd in required_cmds: for cmd in required_cmds:
if call(['which', cmd]): #note, returns 0 if exists, or 1 if doesn't exist. if call(['which', cmd]): #note, returns 0 if exists, or 1 if doesn't exist.
for k, v in EXTRACT_COMMANDS.items(): for k, v in EXTRACT_COMMANDS.items():
if cmd in v[0]: if cmd in v[0]:
logger.error("EXTRACTOR: %s not found, disabling support for %s", cmd, k) logger.error("EXTRACTOR: %s not found, disabling support for %s" % (cmd, k))
del EXTRACT_COMMANDS[k] del EXTRACT_COMMANDS[k]
else: else:
logger.warning("EXTRACTOR: Cannot determine which tool to use when called from Transmission") logger.warning("EXTRACTOR: Cannot determine which tool to use when called from Transmission")
@ -78,16 +81,16 @@ def extract(filePath, outputDestination):
ext = os.path.splitext(filePath) ext = os.path.splitext(filePath)
cmd = [] cmd = []
if ext[1] in (".gz", ".bz2", ".lzma"): if ext[1] in (".gz", ".bz2", ".lzma"):
# Check if this is a tar # Check if this is a tar
if os.path.splitext(ext[0])[1] == ".tar": if os.path.splitext(ext[0])[1] == ".tar":
cmd = EXTRACT_COMMANDS[".tar" + ext[1]] cmd = EXTRACT_COMMANDS[".tar" + ext[1]]
elif ext[1] in (".1", ".01", ".001") and os.path.splitext(ext[0])[1] in (".rar", ".zip", ".7z"): #support for *.zip.001, *.zip.002 etc. elif ext[1] in (".1", ".01", ".001") and os.path.splitext(ext[0])[1] in (".rar", ".zip", ".7z"):
cmd = EXTRACT_COMMANDS[os.path.splitext(ext[0])[1]] cmd = EXTRACT_COMMANDS[os.path.splitext(ext[0])[1]]
else: else:
if ext[1] in EXTRACT_COMMANDS: if ext[1] in EXTRACT_COMMANDS:
cmd = EXTRACT_COMMANDS[ext[1]] cmd = EXTRACT_COMMANDS[ext[1]]
else: else:
logger.debug("EXTRACTOR: Unknown file type: %s", ext[1]) logger.debug("EXTRACTOR: Unknown file type: %s" % ext[1])
return False return False
# Create outputDestination folder # Create outputDestination folder
@ -99,39 +102,42 @@ def extract(filePath, outputDestination):
else: else:
passwords = [] passwords = []
logger.info("Extracting %s to %s", filePath, outputDestination) logger.info("Extracting %s to %s" % (filePath, outputDestination))
logger.debug("Extracting %s %s %s", cmd, filePath, outputDestination) logger.debug("Extracting %s %s %s" % (cmd, filePath, outputDestination))
pwd = os.getcwd() # Get our Present Working Directory pwd = os.getcwd() # Get our Present Working Directory
os.chdir(outputDestination) # Not all unpack commands accept full paths, so just extract into this directory os.chdir(outputDestination) # Not all unpack commands accept full paths, so just extract into this directory
try: # now works same for nt and *nix try: # now works same for nt and *nix
cmd.append(filePath) # add filePath to final cmd arg. cmd.append(filePath) # add filePath to final cmd arg.
cmd2 = cmd cmd2 = cmd
cmd2.append("-p-") # don't prompt for password. cmd2.append("-p-") # don't prompt for password.
p = Popen(cmd2) # should extract files fine. p = Popen(cmd2) # should extract files fine.
res = p.wait() res = p.wait()
if (res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful. if (
logger.info("EXTRACTOR: Extraction was successful for %s to %s", filePath, outputDestination) res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful.
logger.info("EXTRACTOR: Extraction was successful for %s to %s" % (filePath, outputDestination))
elif len(passwords) > 0: elif len(passwords) > 0:
logger.info("EXTRACTOR: Attempting to extract with passwords") logger.info("EXTRACTOR: Attempting to extract with passwords")
pass_success = int(0) pass_success = int(0)
for password in passwords: for password in passwords:
if password == "": # if edited in windows or otherwise if blank lines. if password == "": # if edited in windows or otherwise if blank lines.
continue continue
cmd2 = cmd cmd2 = cmd
#append password here. #append password here.
passcmd = "-p" + password passcmd = "-p" + password
cmd2.append(passcmd) cmd2.append(passcmd)
p = Popen(cmd2) # should extract files fine. p = Popen(cmd2) # should extract files fine.
res = p.wait() res = p.wait()
if (res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful. if (
logger.info("EXTRACTOR: Extraction was successful for %s to %s using password: %s", filePath, outputDestination, password) res >= 0 and os.name == 'nt') or res == 0: # for windows chp returns process id if successful or -1*Error code. Linux returns 0 for successful.
logger.info("EXTRACTOR: Extraction was successful for %s to %s using password: %s" % (
filePath, outputDestination, password))
pass_success = int(1) pass_success = int(1)
break break
else: else:
continue continue
if pass_success == int(0): if pass_success == int(0):
logger.error("EXTRACTOR: Extraction failed for %s. 7zip result was %s", filePath, res) logger.error("EXTRACTOR: Extraction failed for %s. 7zip result was %s" % (filePath, res))
except: except:
logger.error("EXTRACTOR: Extraction failed for %s. Could not call command %s", filePath, cmd) logger.error("EXTRACTOR: Extraction failed for %s. Could not call command %s" % (filePath, cmd))
os.chdir(pwd) # Go back to our Original Working Directory os.chdir(pwd) # Go back to our Original Working Directory
return True return True

View file

@ -76,8 +76,8 @@ class NTMRotatingLogHandler(object):
# set a format which is simpler for console use # set a format which is simpler for console use
console.setFormatter(DispatchingFormatter( console.setFormatter(DispatchingFormatter(
{'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)s:: %(message)s', '%H:%M:%S'), {'nzbtomedia': logging.Formatter('[%(asctime)s] [%(levelname)s]::%(message)s', '%H:%M:%S'),
'postprocess': logging.Formatter('%(asctime)s %(levelname)s:: %(message)s', '%H:%M:%S') 'postprocess': logging.Formatter('[%(asctime)s] [%(levelname)s]::%(message)s', '%H:%M:%S')
}, },
logging.Formatter('%(message)s'), )) logging.Formatter('%(message)s'), ))
@ -109,8 +109,8 @@ class NTMRotatingLogHandler(object):
file_handler.setLevel(logging.DEBUG) file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(DispatchingFormatter( file_handler.setFormatter(DispatchingFormatter(
{'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)-8s:: %(message)s', '%Y-%m-%d %H:%M:%S'), {'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)-8s::%(message)s', '%Y-%m-%d %H:%M:%S'),
'postprocess': logging.Formatter('%(asctime)s %(levelname)-8s:: %(message)s', '%Y-%m-%d %H:%M:%S') 'postprocess': logging.Formatter('%(asctime)s %(levelname)-8s::%(message)s', '%Y-%m-%d %H:%M:%S')
}, },
logging.Formatter('%(message)s'), )) logging.Formatter('%(message)s'), ))
@ -166,7 +166,7 @@ class NTMRotatingLogHandler(object):
ntm_logger.addHandler(new_file_handler) ntm_logger.addHandler(new_file_handler)
pp_logger.addHandler(new_file_handler) pp_logger.addHandler(new_file_handler)
def log(self, toLog, logLevel=MESSAGE): def log(self, toLog, logLevel=MESSAGE, section='MAIN'):
with self.log_lock: with self.log_lock:
@ -178,7 +178,7 @@ class NTMRotatingLogHandler(object):
else: else:
self.writes_since_check += 1 self.writes_since_check += 1
message = u"" + toLog message = u"%s:: %s" % (str(section).upper(), toLog)
out_line = message out_line = message
@ -188,7 +188,8 @@ class NTMRotatingLogHandler(object):
try: try:
if logLevel == DEBUG: if logLevel == DEBUG:
ntm_logger.debug(out_line) if nzbtomedia.LOG_DEBUG == 1:
ntm_logger.debug(out_line)
elif logLevel == MESSAGE: elif logLevel == MESSAGE:
ntm_logger.info(out_line) ntm_logger.info(out_line)
elif logLevel == WARNING: elif logLevel == WARNING:
@ -221,31 +222,26 @@ class DispatchingFormatter:
ntm_log_instance = NTMRotatingLogHandler("nzbtomedia.log", NUM_LOGS, LOG_SIZE) ntm_log_instance = NTMRotatingLogHandler("nzbtomedia.log", NUM_LOGS, LOG_SIZE)
def log(toLog, logLevel=MESSAGE): def log(toLog, logLevel=MESSAGE, section='MAIN'):
ntm_log_instance.log(toLog, logLevel) ntm_log_instance.log(toLog, logLevel, section)
def info(toLog, *args): def info(toLog, section='MAIN'):
toLog = toLog % args log(toLog, MESSAGE, section)
ntm_log_instance.log(toLog, MESSAGE)
def error(toLog, *args): def error(toLog, section='MAIN'):
toLog = toLog % args log(toLog, ERROR, section)
ntm_log_instance.log(toLog, ERROR)
def warning(toLog, *args): def warning(toLog, section='MAIN'):
toLog = toLog % args log(toLog, WARNING, section)
ntm_log_instance.log(toLog, WARNING)
def debug(toLog, *args): def debug(toLog, section='MAIN'):
toLog = toLog % args log(toLog, DEBUG, section)
ntm_log_instance.log(toLog, DEBUG)
def postprocess(toLog, section='MAIN'):
log(toLog, POSTPROCESS, section)
def log_error_and_exit(error_msg): def log_error_and_exit(error_msg):
ntm_log_instance.log_error_and_exit(error_msg) ntm_log_instance.log_error_and_exit(error_msg)
def postprocess(toLog, *args):
toLog = toLog % args
ntm_log_instance.log(toLog, POSTPROCESS)
def close(): def close():
ntm_log_instance.close_log() ntm_log_instance.close_log()

View file

@ -7,7 +7,7 @@ def autoFork(inputCategory):
section = nzbtomedia.CFG.findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
logger.error( logger.error(
"We were unable to find a section for category %s, please check your autoProcessMedia.cfg file.", inputCategory) "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory)
return 1 return 1
# config settings # config settings
@ -47,9 +47,9 @@ def autoFork(inputCategory):
detected = False detected = False
if fork == "auto": if fork == "auto":
logger.info("Attempting to auto-detect " + section + " fork") logger.info("Attempting to auto-detect %s fork" % inputCategory)
for fork in sorted(nzbtomedia.FORKS.iteritems(), reverse=False): for fork in sorted(nzbtomedia.FORKS.iteritems(), reverse=False):
url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(fork[1]) url = "%s%s:%s%s/home/postprocess/processEpisode?%s" % (protocol,host,port,web_root,urllib.urlencode(fork[1]))
# attempting to auto-detect fork # attempting to auto-detect fork
try: try:
@ -58,7 +58,7 @@ def autoFork(inputCategory):
else: else:
r = requests.get(url) r = requests.get(url)
except requests.ConnectionError: except requests.ConnectionError:
logger.info("Could not connect to " + section + ":" + inputCategory + " to perform auto-fork detection!") logger.info("Could not connect to %s:%s to perform auto-fork detection!" % (section, inputCategory))
break break
if r.ok: if r.ok:
@ -66,10 +66,10 @@ def autoFork(inputCategory):
break break
if detected: if detected:
logger.info("" + section + ":" + inputCategory + " fork auto-detection successful ...") logger.info("%s:%s fork auto-detection successful ..." % (section, inputCategory))
else: else:
logger.info("" + section + ":" + inputCategory + " fork auto-detection failed") logger.info("%s:%s fork auto-detection failed" % (section, inputCategory))
fork = nzbtomedia.FORKS.items()[nzbtomedia.FORKS.keys().index(nzbtomedia.FORK_DEFAULT)] fork = nzbtomedia.FORKS.items()[nzbtomedia.FORKS.keys().index(nzbtomedia.FORK_DEFAULT)]
logger.info("" + section + ":" + inputCategory + " fork set to %s", fork[0]) logger.info("%s:%s inputCategory fork set to %s" % (section, inputCategory, fork[0]))
return fork[0], fork[1] return fork[0], fork[1]

View file

@ -4,7 +4,6 @@ import socket
import stat import stat
import struct import struct
import shutil import shutil
import sys
import time import time
from lib import requests from lib import requests
import nzbtomedia import nzbtomedia
@ -15,9 +14,10 @@ from nzbtomedia.synchronousdeluge.client import DelugeClient
from nzbtomedia.utorrent.client import UTorrentClient from nzbtomedia.utorrent.client import UTorrentClient
from nzbtomedia.transmissionrpc.client import Client as TransmissionClient from nzbtomedia.transmissionrpc.client import Client as TransmissionClient
def safeName(name): def safeName(name):
safename = re.sub(r"[\/\\\:\*\?\"\<\>\|]", "", name) #make this name safe for use in directories for windows etc. return re.sub(r"[\/\\\:\*\?\"\<\>\|]", "", name) #make this name safe for use in directories for windows etc.
return safename
def makeDir(path): def makeDir(path):
if not os.path.isdir(path): if not os.path.isdir(path):
@ -27,6 +27,7 @@ def makeDir(path):
return False return False
return True return True
def category_search(inputDirectory, inputName, inputCategory, root, categories): def category_search(inputDirectory, inputName, inputCategory, root, categories):
single = False single = False
tordir = False tordir = False
@ -49,16 +50,18 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories):
return inputDirectory, inputName, inputCategory, root, single return inputDirectory, inputName, inputCategory, root, single
if inputCategory and os.path.isdir(os.path.join(inputDirectory, inputCategory)): if inputCategory and os.path.isdir(os.path.join(inputDirectory, inputCategory)):
logger.info("SEARCH: Found category directory %s in input directory directory %s", inputCategory, inputDirectory) logger.info(
"SEARCH: Found category directory %s in input directory directory %s" % (inputCategory, inputDirectory))
inputDirectory = os.path.join(inputDirectory, inputCategory) inputDirectory = os.path.join(inputDirectory, inputCategory)
logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory) logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory)
if inputName and os.path.isdir(os.path.join(inputDirectory, inputName)): if inputName and os.path.isdir(os.path.join(inputDirectory, inputName)):
logger.info("SEARCH: Found torrent directory %s in input directory directory %s", inputName, inputDirectory) logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % (inputName, inputDirectory))
inputDirectory = os.path.join(inputDirectory, inputName) inputDirectory = os.path.join(inputDirectory, inputName)
logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory) logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory)
tordir = True tordir = True
if inputName and os.path.isdir(os.path.join(inputDirectory, safeName(inputName))): if inputName and os.path.isdir(os.path.join(inputDirectory, safeName(inputName))):
logger.info("SEARCH: Found torrent directory %s in input directory directory %s", safeName(inputName), inputDirectory) logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % (
safeName(inputName), inputDirectory))
inputDirectory = os.path.join(inputDirectory, safeName(inputName)) inputDirectory = os.path.join(inputDirectory, safeName(inputName))
logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory) logger.info("SEARCH: Setting inputDirectory to %s", inputDirectory)
tordir = True tordir = True
@ -73,8 +76,8 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories):
index = pathlist.index(inputCategory) index = pathlist.index(inputCategory)
if index + 1 < len(pathlist): if index + 1 < len(pathlist):
tordir = True tordir = True
logger.info("SEARCH: Found a unique directory %s in the category directory", pathlist[index+1]) logger.info("SEARCH: Found a unique directory %s in the category directory", pathlist[index + 1])
if not inputName: inputName = pathlist[index+1] if not inputName: inputName = pathlist[index + 1]
except ValueError: except ValueError:
pass pass
@ -93,6 +96,7 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories):
return inputDirectory, inputName, inputCategory, root, single return inputDirectory, inputName, inputCategory, root, single
def is_sample(filePath, inputName, minSampleSize, SampleIDs): def is_sample(filePath, inputName, minSampleSize, SampleIDs):
# 200 MB in bytes # 200 MB in bytes
SIZE_CUTOFF = minSampleSize * 1024 * 1024 SIZE_CUTOFF = minSampleSize * 1024 * 1024
@ -101,7 +105,7 @@ def is_sample(filePath, inputName, minSampleSize, SampleIDs):
return True return True
# Ignore 'sample' in files unless 'sample' in Torrent Name # Ignore 'sample' in files unless 'sample' in Torrent Name
for ident in SampleIDs: for ident in SampleIDs:
if ident.lower() in filePath.lower() and not ident.lower() in inputName.lower(): if ident.lower() in filePath.lower() and not ident.lower() in inputName.lower():
return True return True
# Return False if none of these were met. # Return False if none of these were met.
return False return False
@ -115,41 +119,45 @@ def copy_link(filePath, targetDirectory, useLink, outputDestination):
makeDir(outputDestination) makeDir(outputDestination)
if useLink == "hard": if useLink == "hard":
try: try:
logger.info("COPYLINK: Hard linking %s to %s", filePath, targetDirectory) logger.info("COPYLINK: Hard linking %s to %s" % (filePath, targetDirectory))
linktastic.link(filePath, targetDirectory) linktastic.link(filePath, targetDirectory)
except: except:
logger.error("COPYLINK") logger.error("COPYLINK")
if os.path.isfile(targetDirectory): if os.path.isfile(targetDirectory):
logger.warning("COPYLINK: Something went wrong in linktastic.link, but the destination file was created") logger.warning(
"COPYLINK: Something went wrong in linktastic.link, but the destination file was created")
else: else:
logger.warning("COPYLINK: Something went wrong in linktastic.link, copying instead") logger.warning("COPYLINK: Something went wrong in linktastic.link, copying instead")
logger.debug("COPYLINK: Copying %s to %s", filePath, targetDirectory) logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory))
shutil.copy(filePath, targetDirectory) shutil.copy(filePath, targetDirectory)
elif useLink == "sym": elif useLink == "sym":
try: try:
logger.info("COPYLINK: Moving %s to %s before sym linking", filePath, targetDirectory) logger.info("COPYLINK: Moving %s to %s before sym linking" % (filePath, targetDirectory))
shutil.move(filePath, targetDirectory) shutil.move(filePath, targetDirectory)
logger.info("COPYLINK: Sym linking %s to %s", targetDirectory, filePath) logger.info("COPYLINK: Sym linking %s to %s" % (targetDirectory, filePath))
linktastic.symlink(targetDirectory, filePath) linktastic.symlink(targetDirectory, filePath)
except: except:
logger.error("COPYLINK") logger.error("COPYLINK")
if os.path.isfile(targetDirectory): if os.path.isfile(targetDirectory):
logger.warning("COPYLINK: Something went wrong in linktastic.link, but the destination file was created") logger.warning(
"COPYLINK: Something went wrong in linktastic.link, but the destination file was created")
else: else:
logger.info("COPYLINK: Something went wrong in linktastic.link, copying instead") logger.info("COPYLINK: Something went wrong in linktastic.link, copying instead")
logger.debug("COPYLINK: Copying %s to %s", filePath, targetDirectory) logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory))
shutil.copy(filePath, targetDirectory) shutil.copy(filePath, targetDirectory)
elif useLink == "move": elif useLink == "move":
logger.debug("Moving %s to %s", filePath, targetDirectory) logger.debug("Moving %s to %s" % (filePath, targetDirectory))
shutil.move(filePath, targetDirectory) shutil.move(filePath, targetDirectory)
else: else:
logger.debug("Copying %s to %s", filePath, targetDirectory) logger.debug("Copying %s to %s" % (filePath, targetDirectory))
shutil.copy(filePath, targetDirectory) shutil.copy(filePath, targetDirectory)
return True return True
def flatten(outputDestination): def flatten(outputDestination):
logger.info("FLATTEN: Flattening directory: %s", outputDestination) logger.info("FLATTEN: Flattening directory: %s", outputDestination)
for dirpath, dirnames, filenames in os.walk(outputDestination): # Flatten out the directory to make postprocessing easier for dirpath, dirnames, filenames in os.walk(
outputDestination): # Flatten out the directory to make postprocessing easier
if dirpath == outputDestination: if dirpath == outputDestination:
continue # No need to try and move files in the root destination directory continue # No need to try and move files in the root destination directory
for filename in filenames: for filename in filenames:
@ -161,6 +169,7 @@ def flatten(outputDestination):
logger.error("FLATTEN: Could not flatten %s", source) logger.error("FLATTEN: Could not flatten %s", source)
removeEmptyFolders(outputDestination) # Cleanup empty directories removeEmptyFolders(outputDestination) # Cleanup empty directories
def removeEmptyFolders(path): def removeEmptyFolders(path):
logger.info("REMOVER: Removing empty folders in: %s", path) logger.info("REMOVER: Removing empty folders in: %s", path)
if not os.path.isdir(path): if not os.path.isdir(path):
@ -180,6 +189,7 @@ def removeEmptyFolders(path):
logger.debug("REMOVER: Removing empty folder: %s", path) logger.debug("REMOVER: Removing empty folder: %s", path)
os.rmdir(path) os.rmdir(path)
def remove_read_only(path): def remove_read_only(path):
if not os.path.isdir(path): if not os.path.isdir(path):
return return
@ -188,16 +198,16 @@ def remove_read_only(path):
logger.debug("Removing Read Only Flag for: %s", filename) logger.debug("Removing Read Only Flag for: %s", filename)
os.chmod(os.path.join(dirpath, filename), stat.S_IWRITE) os.chmod(os.path.join(dirpath, filename), stat.S_IWRITE)
#Wake function #Wake function
def WakeOnLan(ethernet_address): def WakeOnLan(ethernet_address):
addr_byte = ethernet_address.split(':') addr_byte = ethernet_address.split(':')
hw_addr = struct.pack('BBBBBB', int(addr_byte[0], 16), hw_addr = struct.pack('BBBBBB', int(addr_byte[0], 16),
int(addr_byte[1], 16), int(addr_byte[1], 16),
int(addr_byte[2], 16), int(addr_byte[2], 16),
int(addr_byte[3], 16), int(addr_byte[3], 16),
int(addr_byte[4], 16), int(addr_byte[4], 16),
int(addr_byte[5], 16)) int(addr_byte[5], 16))
# Build the Wake-On-LAN "Magic Packet"... # Build the Wake-On-LAN "Magic Packet"...
@ -210,6 +220,7 @@ def WakeOnLan(ethernet_address):
ss.sendto(msg, ('<broadcast>', 9)) ss.sendto(msg, ('<broadcast>', 9))
ss.close() ss.close()
#Test Connection function #Test Connection function
def TestCon(host, port): def TestCon(host, port):
try: try:
@ -218,50 +229,55 @@ def TestCon(host, port):
except: except:
return "Down" return "Down"
def WakeUp(): def WakeUp():
wake = int(nzbtomedia.CFG["WakeOnLan"]["wake"]) wake = int(nzbtomedia.CFG["WakeOnLan"]["wake"])
if wake == 0: # just return if we don't need to wake anything. if wake == 0: # just return if we don't need to wake anything.
return return
logger.info(("Loading WakeOnLan config from %s", nzbtomedia.CONFIG_FILE)) logger.info(("Loading WakeOnLan config from %s", nzbtomedia.CONFIG_FILE))
host = nzbtomedia.CFG["WakeOnLan"]["host"] host = nzbtomedia.CFG["WakeOnLan"]["host"]
port = int(nzbtomedia.CFG["WakeOnLan"]["port"]) port = int(nzbtomedia.CFG["WakeOnLan"]["port"])
mac = nzbtomedia.CFG["WakeOnLan"]["mac"] mac = nzbtomedia.CFG["WakeOnLan"]["mac"]
i=1 i = 1
while TestCon(host, port) == "Down" and i < 4: while TestCon(host, port) == "Down" and i < 4:
logger.info(("Sending WakeOnLan Magic Packet for mac: %s", mac)) logger.info(("Sending WakeOnLan Magic Packet for mac: %s", mac))
WakeOnLan(mac) WakeOnLan(mac)
time.sleep(20) time.sleep(20)
i=i+1 i = i + 1
if TestCon(host,port) == "Down": # final check. if TestCon(host, port) == "Down": # final check.
logger.warning("System with mac: %s has not woken after 3 attempts. Continuing with the rest of the script.", mac) logger.warning("System with mac: %s has not woken after 3 attempts. Continuing with the rest of the script.",
mac)
else: else:
logger.info("System with mac: %s has been woken. Continuing with the rest of the script.", mac) logger.info("System with mac: %s has been woken. Continuing with the rest of the script.", mac)
def convert_to_ascii(nzbName, dirName): def convert_to_ascii(nzbName, dirName):
ascii_convert = int(nzbtomedia.CFG["ASCII"]["convert"]) ascii_convert = int(nzbtomedia.CFG["ASCII"]["convert"])
if ascii_convert == 0 or os.name == 'nt': # just return if we don't want to convert or on windows os and "\" is replaced!. if ascii_convert == 0 or os.name == 'nt': # just return if we don't want to convert or on windows os and "\" is replaced!.
return nzbName, dirName return nzbName, dirName
nzbName2 = str(nzbName.decode('ascii', 'replace').replace(u'\ufffd', '_')) nzbName2 = str(nzbName.decode('ascii', 'replace').replace(u'\ufffd', '_'))
dirName2 = str(dirName.decode('ascii', 'replace').replace(u'\ufffd', '_')) dirName2 = str(dirName.decode('ascii', 'replace').replace(u'\ufffd', '_'))
if dirName != dirName2: if dirName != dirName2:
logger.info("Renaming directory:%s to: %s.", dirName, dirName2) logger.info("Renaming directory:%s to: %s." % (dirName, dirName2))
shutil.move(dirName, dirName2) shutil.move(dirName, dirName2)
for dirpath, dirnames, filesnames in os.walk(dirName2): for dirpath, dirnames, filesnames in os.walk(dirName2):
for filename in filesnames: for filename in filesnames:
filename2 = str(filename.decode('ascii', 'replace').replace(u'\ufffd', '_')) filename2 = str(filename.decode('ascii', 'replace').replace(u'\ufffd', '_'))
if filename != filename2: if filename != filename2:
logger.info("Renaming file:%s to: %s.", filename, filename2) logger.info("Renaming file:%s to: %s." % (filename, filename2))
shutil.move(filename, filename2) shutil.move(filename, filename2)
nzbName = nzbName2 nzbName = nzbName2
dirName = dirName2 dirName = dirName2
return nzbName, dirName return nzbName, dirName
def parse_other(args): def parse_other(args):
return os.path.normpath(args[1]), '', '', '', '' return os.path.normpath(args[1]), '', '', '', ''
def parse_rtorrent(args): def parse_rtorrent(args):
# rtorrent usage: system.method.set_key = event.download.finished,TorrentToMedia, # rtorrent usage: system.method.set_key = event.download.finished,TorrentToMedia,
# "execute={/path/to/nzbToMedia/TorrentToMedia.py,\"$d.get_base_path=\",\"$d.get_name=\",\"$d.get_custom1=\",\"$d.get_hash=\"}" # "execute={/path/to/nzbToMedia/TorrentToMedia.py,\"$d.get_base_path=\",\"$d.get_name=\",\"$d.get_custom1=\",\"$d.get_hash=\"}"
@ -285,6 +301,7 @@ def parse_rtorrent(args):
return inputDirectory, inputName, inputCategory, inputHash, inputID return inputDirectory, inputName, inputCategory, inputHash, inputID
def parse_utorrent(args): def parse_utorrent(args):
# uTorrent usage: call TorrentToMedia.py "%D" "%N" "%L" "%I" # uTorrent usage: call TorrentToMedia.py "%D" "%N" "%L" "%I"
inputDirectory = os.path.normpath(args[1]) inputDirectory = os.path.normpath(args[1])
@ -324,21 +341,23 @@ def parse_transmission(args):
inputID = os.getenv('TR_TORRENT_ID') inputID = os.getenv('TR_TORRENT_ID')
return inputDirectory, inputName, inputCategory, inputHash, inputID return inputDirectory, inputName, inputCategory, inputHash, inputID
def parse_args(clientAgent, args): def parse_args(clientAgent, args):
clients = { clients = {
'other': parse_other, 'other': parse_other,
'rtorrent': parse_rtorrent, 'rtorrent': parse_rtorrent,
'utorrent': parse_utorrent, 'utorrent': parse_utorrent,
'deluge': parse_deluge, 'deluge': parse_deluge,
'transmission': parse_transmission, 'transmission': parse_transmission,
} }
try: try:
return clients[clientAgent](args) return clients[clientAgent](args)
except:return None, None, None, None, None except:
return None, None, None, None, None
def get_dirnames(section, subsections=None): def get_dirnames(section, subsections=None):
dirNames = [] dirNames = []
if subsections is None: if subsections is None:
@ -386,13 +405,14 @@ def get_dirnames(section, subsections=None):
shutil.move(mediafile, p) shutil.move(mediafile, p)
dirNames.extend([os.path.join(outputDirectory, o) for o in os.listdir(outputDirectory) if dirNames.extend([os.path.join(outputDirectory, o) for o in os.listdir(outputDirectory) if
os.path.isdir(os.path.join(outputDirectory, o))]) os.path.isdir(os.path.join(outputDirectory, o))])
if not dirNames: if not dirNames:
logger.warning("%s:%s has no directories identified for post-processing", section, subsection) logger.warning("%s:%s has no directories identified for post-processing" % (section, subsection))
return list(set(dirNames)) return list(set(dirNames))
def delete(dirName): def delete(dirName):
logger.info("Deleting %s", dirName) logger.info("Deleting %s", dirName)
try: try:
@ -400,6 +420,7 @@ def delete(dirName):
except: except:
logger.error("Unable to delete folder %s", dirName) logger.error("Unable to delete folder %s", dirName)
def cleanup_directories(inputCategory, processCategories, result, directory): def cleanup_directories(inputCategory, processCategories, result, directory):
if inputCategory in processCategories and result == 0 and os.path.isdir(directory): if inputCategory in processCategories and result == 0 and os.path.isdir(directory):
num_files_new = int(0) num_files_new = int(0)
@ -415,90 +436,97 @@ def cleanup_directories(inputCategory, processCategories, result, directory):
logger.info("All files have been processed. Cleaning directory %s", directory) logger.info("All files have been processed. Cleaning directory %s", directory)
shutil.rmtree(directory) shutil.rmtree(directory)
else: else:
logger.info("Directory %s still contains %s media and/or meta files. This directory will not be removed.", directory, num_files_new) logger.info(
"Directory %s still contains %s media and/or meta files. This directory will not be removed." % (
directory, num_files_new))
for item in file_list: for item in file_list:
logger.debug("media/meta file found: %s", item) logger.debug("media/meta file found: %s", item)
def create_torrent_class(clientAgent): def create_torrent_class(clientAgent):
# Hardlink solution for Torrents # Hardlink solution for Torrents
TorrentClass = None TorrentClass = None
if clientAgent == 'utorrent': if clientAgent == 'utorrent':
try: try:
logger.debug("Connecting to %s: %s", clientAgent, nzbtomedia.UTORRENTWEBUI) logger.debug("Connecting to %s: %s" % (clientAgent, nzbtomedia.UTORRENTWEBUI))
TorrentClass = UTorrentClient(nzbtomedia.UTORRENTWEBUI, nzbtomedia.UTORRENTUSR, nzbtomedia.UTORRENTPWD) TorrentClass = UTorrentClient(nzbtomedia.UTORRENTWEBUI, nzbtomedia.UTORRENTUSR, nzbtomedia.UTORRENTPWD)
except: except:
logger.error("Failed to connect to uTorrent") logger.error("Failed to connect to uTorrent")
if clientAgent == 'transmission': if clientAgent == 'transmission':
try: try:
logger.debug("Connecting to %s: http://%s:%s", clientAgent, nzbtomedia.TRANSMISSIONHOST, logger.debug("Connecting to %s: http://%s:%s" % (
nzbtomedia.TRANSMISSIONPORT) clientAgent, nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT))
TorrentClass = TransmissionClient(nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT, nzbtomedia.TRANSMISSIONUSR, TorrentClass = TransmissionClient(nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT,
nzbtomedia.TRANSMISSIONUSR,
nzbtomedia.TRANSMISSIONPWD) nzbtomedia.TRANSMISSIONPWD)
except: except:
logger.error("Failed to connect to Transmission") logger.error("Failed to connect to Transmission")
if clientAgent == 'deluge': if clientAgent == 'deluge':
try: try:
logger.debug("Connecting to %s: http://%s:%s", clientAgent, nzbtomedia.DELUGEHOST, logger.debug("Connecting to %s: http://%s:%s" % (clientAgent, nzbtomedia.DELUGEHOST, nzbtomedia.DELUGEPORT))
nzbtomedia.DELUGEPORT)
TorrentClass = DelugeClient() TorrentClass = DelugeClient()
TorrentClass.connect(host =nzbtomedia.DELUGEHOST, port =nzbtomedia.DELUGEPORT, username =nzbtomedia.DELUGEUSR, password =nzbtomedia.DELUGEPWD) TorrentClass.connect(host=nzbtomedia.DELUGEHOST, port=nzbtomedia.DELUGEPORT, username=nzbtomedia.DELUGEUSR,
password=nzbtomedia.DELUGEPWD)
except: except:
logger.error("Failed to connect to Deluge") logger.error("Failed to connect to Deluge")
return TorrentClass return TorrentClass
def pause_torrent(clientAgent, TorrentClass, inputHash, inputID, inputName): 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 # if we are using links with Torrents it means we need to pause it in order to access the files
logger.debug("Stoping torrent %s in %s while processing", inputName, clientAgent) logger.debug("Stoping torrent %s in %s while processing" % (inputName, clientAgent))
if clientAgent == 'utorrent' and TorrentClass != "": if clientAgent == 'utorrent' and TorrentClass != "":
TorrentClass.stop(inputHash) TorrentClass.stop(inputHash)
if clientAgent == 'transmission' and TorrentClass !="": if clientAgent == 'transmission' and TorrentClass != "":
TorrentClass.stop_torrent(inputID) TorrentClass.stop_torrent(inputID)
if clientAgent == 'deluge' and TorrentClass != "": if clientAgent == 'deluge' and TorrentClass != "":
TorrentClass.core.pause_torrent([inputID]) TorrentClass.core.pause_torrent([inputID])
time.sleep(5) # Give Torrent client some time to catch up with the change time.sleep(5) # Give Torrent client some time to catch up with the change
def resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName): def resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName):
# Hardlink solution for uTorrent, need to implent support for deluge, transmission # Hardlink solution for uTorrent, need to implent support for deluge, transmission
if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash: if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash:
# Delete torrent and torrentdata from Torrent client if processing was successful. # Delete torrent and torrentdata from Torrent client if processing was successful.
if (int(nzbtomedia.CFG["Torrent"]["deleteOriginal"]) is 1 and result != 1) or nzbtomedia.USELINK == 'move': # if we move files, nothing to resume seeding. if (int(nzbtomedia.CFG["Torrent"][
logger.debug("Deleting torrent %s from %s", inputName, clientAgent) "deleteOriginal"]) is 1 and result != 1) or nzbtomedia.USELINK == 'move': # if we move files, nothing to resume seeding.
logger.debug("Deleting torrent %s from %s" % (inputName, clientAgent))
if clientAgent == 'utorrent' and TorrentClass != "": if clientAgent == 'utorrent' and TorrentClass != "":
TorrentClass.removedata(inputHash) TorrentClass.removedata(inputHash)
TorrentClass.remove(inputHash) TorrentClass.remove(inputHash)
if clientAgent == 'transmission' and TorrentClass !="": if clientAgent == 'transmission' and TorrentClass != "":
TorrentClass.remove_torrent(inputID, True) TorrentClass.remove_torrent(inputID, True)
if clientAgent == 'deluge' and TorrentClass != "": if clientAgent == 'deluge' and TorrentClass != "":
TorrentClass.core.remove_torrent(inputID, True) TorrentClass.core.remove_torrent(inputID, True)
# we always want to resume seeding, for now manually find out what is wrong when extraction fails # we always want to resume seeding, for now manually find out what is wrong when extraction fails
else: else:
logger.debug("Starting torrent %s in %s", inputName, clientAgent) logger.debug("Starting torrent %s in %s" % (inputName, clientAgent))
if clientAgent == 'utorrent' and TorrentClass != "": if clientAgent == 'utorrent' and TorrentClass != "":
TorrentClass.start(inputHash) TorrentClass.start(inputHash)
if clientAgent == 'transmission' and TorrentClass !="": if clientAgent == 'transmission' and TorrentClass != "":
TorrentClass.start_torrent(inputID) TorrentClass.start_torrent(inputID)
if clientAgent == 'deluge' and TorrentClass != "": if clientAgent == 'deluge' and TorrentClass != "":
TorrentClass.core.resume_torrent([inputID]) TorrentClass.core.resume_torrent([inputID])
time.sleep(5) time.sleep(5)
def find_download(clientAgent, nzbName, download_id):
def find_download(clientAgent, download_id):
tc = create_torrent_class(clientAgent) tc = create_torrent_class(clientAgent)
logger.debug("Searching for Download on %s ...", clientAgent) logger.debug("Searching for Download on %s ...", clientAgent)
if clientAgent == 'utorrent': if clientAgent == 'utorrent':
torrents = tc.list()[1]['torrents'] torrents = tc.list()[1]['torrents']
if torrents: for torrent in torrents:
for torrent in torrents: if download_id in torrent:
if nzbName in torrent and download_id in torrent: return True
return True
if clientAgent == 'transmission': if clientAgent == 'transmission':
torrent = tc.get_torrent(download_id) torrents = tc.get_torrents()
if torrent: for torrent in torrents:
name = torrent.name hash = torrent.hashString
if name == nzbName: if hash == download_id:
return True return True
if clientAgent == 'deluge': if clientAgent == 'deluge':
pass pass
@ -507,9 +535,9 @@ def find_download(clientAgent, nzbName, download_id):
url = baseURL url = baseURL
params = {} params = {}
params['apikey'] = nzbtomedia.SABNZBDAPIKEY params['apikey'] = nzbtomedia.SABNZBDAPIKEY
params['mode'] = "history" params['mode'] = "get_files"
params['output'] = 'json' params['output'] = 'json'
params['value'] = download_id
try: try:
r = requests.get(url, params=params) r = requests.get(url, params=params)
except requests.ConnectionError: except requests.ConnectionError:
@ -517,7 +545,8 @@ def find_download(clientAgent, nzbName, download_id):
return 1 # failure return 1 # failure
result = r.json() result = r.json()
pass if result['files']:
return True
def clean_nzbname(nzbname): def clean_nzbname(nzbname):
@ -537,6 +566,7 @@ def clean_nzbname(nzbname):
nzbname = re.sub("^\[.*\]", "", nzbname) nzbname = re.sub("^\[.*\]", "", nzbname)
return nzbname.strip() return nzbname.strip()
def isMediaFile(filename): def isMediaFile(filename):
# ignore samples # ignore samples
if re.search('(^|[\W_])(sample\d*)[\W_]', filename, re.I): if re.search('(^|[\W_])(sample\d*)[\W_]', filename, re.I):
@ -556,6 +586,7 @@ def isMediaFile(filename):
else: else:
return False return False
def listMediaFiles(path): def listMediaFiles(path):
if not dir or not os.path.isdir(path): if not dir or not os.path.isdir(path):
return [] return []
@ -571,4 +602,56 @@ def listMediaFiles(path):
elif isMediaFile(curFile): elif isMediaFile(curFile):
files.append(fullCurFile) files.append(fullCurFile)
return files return files
def find_imdbid(dirName, nzbName):
imdbid = None
nzbName = clean_nzbname(nzbName)
logger.info('Attemping imdbID lookup for %s' % (nzbName))
# find imdbid in dirName
logger.info('Searching folder name for imdbID ...')
m = re.search('(tt\d{7})', dirName)
if m:
imdbid = m.group(1)
logger.info("Found movie id %s in directory" % imdbid)
return imdbid
# find imdbid in nzbName
logger.info('Searching filename for imdbID ...')
m = re.search('(tt\d{7})', nzbName)
if m:
imdbid = m.group(1)
logger.info("Found imdbid %s in name" % imdbid)
return imdbid
logger.info('Searching IMDB for imdbID ...')
m = re.search("^(.+)(\d{4})\W", nzbName)
if m:
title = m.group(1)
year = m.group(2)
url = "http://www.omdbapi.com"
logger.debug("Opening URL: %s" % url)
try:
r = requests.get(url, params={'y': year, 't': title})
except requests.ConnectionError:
logger.error("Unable to open URL %s" % url)
return
results = r.json()
try:
imdbid = results['imdbID']
except:
pass
if imdbid:
return imdbid
else:
logger.warning('Unable to find a imdbID for %s' % (nzbName))

View file

@ -225,7 +225,7 @@ class GitUpdateManager(UpdateManager):
branch = branch_info.strip().replace('refs/heads/', '', 1) branch = branch_info.strip().replace('refs/heads/', '', 1)
if branch: if branch:
nzbtomedia.NZBTOMEDIA_BRANCH = branch nzbtomedia.NZBTOMEDIA_BRANCH = branch
return nzbtomedia.NZBTOMEDIA_BRANCH return nzbtomedia.GIT_BRANCH
def _check_github_for_update(self): def _check_github_for_update(self):
""" """
@ -273,7 +273,7 @@ class GitUpdateManager(UpdateManager):
logger.log(u"git didn't return numbers for behind and ahead, not using it", logger.DEBUG) logger.log(u"git didn't return numbers for behind and ahead, not using it", logger.DEBUG)
return return
logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u", newest_commit = " + str(self._newest_commit_hash) logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u" % (newest_commit)= " + str(self._newest_commit_hash)
+ u", num_commits_behind = " + str(self._num_commits_behind) + u", num_commits_ahead = " + str( + u", num_commits_behind = " + str(self._num_commits_behind) + u", num_commits_ahead = " + str(
self._num_commits_ahead), logger.DEBUG) self._num_commits_ahead), logger.DEBUG)
@ -405,7 +405,7 @@ class SourceUpdateManager(UpdateManager):
# when _cur_commit_hash doesn't match anything _num_commits_behind == 100 # when _cur_commit_hash doesn't match anything _num_commits_behind == 100
self._num_commits_behind += 1 self._num_commits_behind += 1
logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u", newest_commit = " + str(self._newest_commit_hash) logger.log(u"cur_commit = " + str(self._cur_commit_hash) + u" % (newest_commit)= " + str(self._newest_commit_hash)
+ u", num_commits_behind = " + str(self._num_commits_behind), logger.DEBUG) + u", num_commits_behind = " + str(self._num_commits_behind), logger.DEBUG)
def set_newest_text(self): def set_newest_text(self):

View file

@ -4,29 +4,10 @@ import nzbtomedia
import TorrentToMedia import TorrentToMedia
from nzbtomedia.nzbToMediaUtil import find_download, clean_nzbname, listMediaFiles from nzbtomedia.nzbToMediaUtil import find_download, clean_nzbname, listMediaFiles
os.environ['TR_TORRENT_DIR']="z:/downloads/complete/movie/The.Art.of.the.Steal.2013.LIMITED.1080p.BRRip.h264.AAC-RARBG"
os.environ['TR_TORRENT_NAME']="The.Art.of.the.Steal.2013.LIMITED.1080p.BRRip.h264.AAC-RARBG"
os.environ['TR_TORRENT_ID']="154206e6390a03bbf01e61f013e1a52494a52dfa"
os.environ['TR_TORRENT_HASH']="154206e6390a03bbf01e61f013e1a52494a52dfa"
#TorrentToMedia.main(sys.argv)
test = 'The.Art.of.the.Steal.2013.LIMITED.1080p.BRRip.h264.AAC-RARBG'
cleaned = clean_nzbname(test)
# Initialize the config
nzbtomedia.initialize() nzbtomedia.initialize()
dirName = 'Z:/complete/tv/' download_id = 'SABnzbd_nzo_qhoQ7m'
test = listMediaFiles('Z:/complete/tv/') if find_download('sabnzbd', download_id):
for filename in test:
parentDir = os.path.dirname(filename)
if parentDir == dirName:
pass
clientAgent = nzbtomedia.NZB_CLIENTAGENT
nzbName = 'Anger.Management.S02E57.HDTV.x264-KILLERS'
#download_id = '51C9B415382894727C5C7D8442554D3AC08B390F'
download_id = 'SABnzbd_nzo_uBYaGb'
if find_download(clientAgent, nzbName, download_id):
print 'found' print 'found'
else: else:
print 'no luck' print 'no luck'