Massive changes to the way we handle our config, its now loaded and stored in memory so that we don't keep loading it and possibly get corrupt values.

New logger class added,logger options removed from settings.
This commit is contained in:
echel0n 2014-04-11 20:09:00 -07:00
commit 18926d1db8
30 changed files with 1603 additions and 1058 deletions

View file

@ -62,13 +62,13 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
print "Please enable option \"Unpack\" in nzbget configuration file, exiting." print "Please enable option \"Unpack\" in nzbget configuration file, exiting."
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
print "Par-check successful, but Par-repair disabled, exiting." print "Par-check successful, but Par-repair disabled, exiting."
print "Please check your Par-repair settings for future downloads." print "Please check your Par-repair settings for future downloads."
sys.exit(config.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':
print "Par-repair failed, setting status \"failed\"." print "Par-repair failed, setting status \"failed\"."
@ -99,7 +99,7 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
# All checks done, now launching the script. # All checks done, now launching the script.
if status == 1: if status == 1:
sys.exit(config.NZBGET_POSTPROCESS_NONE) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_NONE)
mediaContainer = os.environ['NZBPO_MEDIAEXTENSIONS'].split(',') mediaContainer = os.environ['NZBPO_MEDIAEXTENSIONS'].split(',')
SampleIDs = os.environ['NZBPO_SAMPLEIDS'].split(',') SampleIDs = os.environ['NZBPO_SAMPLEIDS'].split(',')
@ -116,8 +116,8 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
os.unlink(filePath) os.unlink(filePath)
except: except:
print "Error: unable to delete file", filePath print "Error: unable to delete file", filePath
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
print "This script can only be called from NZBGet (11.0 or later)." print "This script can only be called from NZBGet (11.0 or later)."

View file

@ -29,13 +29,13 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
print "Please enable option \"Unpack\" in nzbget configuration file, exiting." print "Please enable option \"Unpack\" in nzbget configuration file, exiting."
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
print "Par-check successful, but Par-repair disabled, exiting." print "Par-check successful, but Par-repair disabled, exiting."
print "Please check your Par-repair settings for future downloads." print "Please check your Par-repair settings for future downloads."
sys.exit(config.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':
print "Par-repair failed, setting status \"failed\"." print "Par-repair failed, setting status \"failed\"."
@ -66,7 +66,7 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
# All checks done, now launching the script. # All checks done, now launching the script.
if status == 1: if status == 1:
sys.exit(config.NZBGET_POSTPROCESS_NONE) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_NONE)
directory = os.path.normpath(os.environ['NZBPP_DIRECTORY']) directory = os.path.normpath(os.environ['NZBPP_DIRECTORY'])
for dirpath, dirnames, filenames in os.walk(directory): for dirpath, dirnames, filenames in os.walk(directory):
@ -78,8 +78,8 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
continue continue
except: except:
print "Error: unable to reset time for file", file print "Error: unable to reset time for file", file
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
print "This script can only be called from NZBGet (11.0 or later)." print "This script can only be called from NZBGet (11.0 or later)."

View file

@ -1,14 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
# adds lib directory to system path
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib')))
import datetime import datetime
import os
import time import time
import logging
import re import re
import shutil import shutil
import sys
import nzbtomedia
from subprocess import Popen from subprocess import Popen
from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics
from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames
@ -16,13 +14,11 @@ from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie
from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
from nzbtomedia.extractor import extractor from nzbtomedia.extractor import extractor
from nzbtomedia.nzbToMediaAutoFork import autoFork from nzbtomedia.nzbToMediaUtil import category_search, safeName, is_sample, copy_link, parse_args, flatten, get_dirnames
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaUtil import category_search, safeName, is_sample, copy_link, WakeUp, parse_args, flatten, \
nzbtomedia_configure_logging, get_dirnames
from nzbtomedia.synchronousdeluge.client import DelugeClient 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
from nzbtomedia import logger
def main(inputDirectory, inputName, inputCategory, inputHash, inputID): def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
@ -32,54 +28,51 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
archive = int(0) archive = int(0)
foundFile = int(0) foundFile = int(0)
extracted_folder = [] extracted_folder = []
extractionSuccess = False
copy_list = [] copy_list = []
file = None
Logger.debug("MAIN: 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, 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("MAIN: Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory) logger.debug("Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory)
TorrentClass = create_torrent_class(clientAgent, inputHash) TorrentClass = create_torrent_class(nzbtomedia.CLIENTAGENT, inputHash)
pause_torrent(clientAgent, TorrentClass, inputHash, inputID, inputName) pause_torrent(nzbtomedia.CLIENTAGENT, TorrentClass, inputHash, inputID, inputName)
processCategories = config()[sections].sections processCategories = nzbtomedia.CFG[nzbtomedia.SECTIONS].sections
outputDestination = ""
if inputCategory == "": if inputCategory == "":
inputCategory = "UNCAT" inputCategory = "UNCAT"
outputDestination = os.path.normpath(os.path.join(outputDirectory, inputCategory, safeName(inputName))) outputDestination = os.path.normpath(os.path.join(nzbtomedia.OUTPUTDIRECTORY, inputCategory, safeName(inputName)))
Logger.info("MAIN: Output directory set to: %s", outputDestination) logger.postprocess("Output directory set to: %s", outputDestination)
if config()["SickBeard"].issubsection(inputCategory): if nzbtomedia.CFG["SickBeard"].issubsection(inputCategory):
Torrent_NoLink = int(config()["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0 Torrent_NoLink = int(nzbtomedia.CFG["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0
if Torrent_NoLink == 1: if Torrent_NoLink == 1:
Logger.info("MAIN: Calling autoProcessTV to post-process: %s",inputName) logger.postprocess("Calling autoProcessTV to post-process: %s",inputName)
result = autoProcessTV().processEpisode(inputDirectory, inputName, 0, clientAgent=clientAgent, inputCategory=inputCategory) result = autoProcessTV().processEpisode(inputDirectory, inputName, 0, clientAgent=nzbtomedia.CLIENTAGENT, inputCategory=inputCategory)
if result != 0: if result != 0:
Logger.info("MAIN: A problem was reported in the autoProcessTV script.") logger.error("A problem was reported in the autoProcessTV script.")
resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName) resume_torrent(nzbtomedia.CLIENTAGENT, TorrentClass, inputHash, inputID, result, inputName)
cleanup_output(inputCategory, processCategories, result, outputDestination) cleanup_output(inputCategory, processCategories, result, outputDestination)
Logger.info("MAIN: All done.") logger.postprocess("All done.")
sys.exit() sys.exit()
processOnly = config()[sections].sections processOnly = nzbtomedia.CFG[nzbtomedia.SECTIONS].sections
if not "NONE" in user_script_categories: # if None, we only process the 5 listed. if not "NONE" in nzbtomedia.USER_SCRIPT_CATEGORIES: # if None, we only process the 5 listed.
if "ALL" in user_script_categories: # All defined categories if "ALL" in nzbtomedia.USER_SCRIPT_CATEGORIES: # All defined categories
processOnly = categories processOnly = nzbtomedia.CATEGORIES
processOnly.extend(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.info("MAIN: No processing to be done for category: %s. Exiting", inputCategory) logger.postprocess("No processing to be done for category: %s. Exiting", inputCategory)
Logger.info("MAIN: All done.") logger.postprocess("All done.")
sys.exit() sys.exit()
Logger.debug("MAIN: Scanning files in directory: %s", inputDirectory) logger.debug("Scanning files in directory: %s", inputDirectory)
if config()["HeadPhones"].issubsection(inputCategory): if nzbtomedia.CFG["HeadPhones"].issubsection(inputCategory):
noFlatten.extend(config()["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.
outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards. outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards.
now = datetime.datetime.now() now = datetime.datetime.now()
@ -88,132 +81,133 @@ def main(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("MAIN: 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)
if inputCategory in noFlatten and not single: if inputCategory in nzbtomedia.NOFLATTEN and not single:
newDir = dirpath # find the full path newDir = dirpath # find the full path
newDir = newDir.replace(inputDirectory, "") #find the extra-depth directory newDir = newDir.replace(inputDirectory, "") #find the extra-depth directory
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("MAIN: 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("MAIN: 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("MAIN: 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
if root == 2: if root == 2:
if foundFile == int(0): if foundFile == int(0):
Logger.debug("MAIN: Looking for files with modified/created dates less than 5 minutes old.") logger.debug("Looking for files with modified/created dates less than 5 minutes old.")
mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(os.path.join(dirpath, file))) mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(os.path.join(dirpath, file)))
ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(os.path.join(dirpath, file))) ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(os.path.join(dirpath, file)))
if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): 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("MAIN: 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 mediaContainer and is_sample(filePath, inputName, minSampleSize, SampleIDs) and not config()["HeadPhones"].issubsection(inputCategory): # Ignore samples if fileExtension in nzbtomedia.MEDIACONTAINER and is_sample(filePath, inputName, nzbtomedia.MINSAMPLESIZE,
Logger.info("MAIN: Ignoring sample file: %s ", filePath) nzbtomedia.SAMPLEIDS) and not nzbtomedia.CFG["HeadPhones"].issubsection(inputCategory): # Ignore samples
logger.postprocess("Ignoring sample file: %s ", filePath)
continue continue
if fileExtension in compressedContainer: if fileExtension in nzbtomedia.COMPRESSEDCONTAINER:
if (config()["SickBeard"].issubsection(inputCategory) and config()["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination"): if (nzbtomedia.CFG["SickBeard"].issubsection(inputCategory) and nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination"):
# find part numbers in second "extension" from right, if we have more than 1 compressed file in the same directory. # find part numbers in second "extension" from right, if we have more than 1 compressed file in the same directory.
if re.search(r'\d+', os.path.splitext(fileName)[1]) and os.path.dirname(filePath) in extracted_folder and not any(item in os.path.splitext(fileName)[1] for item in ['.720p','.1080p','.x264']): 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("MAIN: 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("MAIN: 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.info("MAIN: 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.exception("MAIN: Extraction failed for: %s", file) logger.error("Extraction failed for: %s", file)
continue continue
try: try:
copy_link(filePath, targetDirectory, 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.exception("MAIN: 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 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.
flatten(outputDestination) flatten(outputDestination)
# Now check if video files exist in destination: # Now check if video files exist in destination:
if config()["SickBeard","NzbDrone", "CouchPotato"].issubsection(inputCategory): if nzbtomedia.CFG["SickBeard","NzbDrone", "CouchPotato"].issubsection(inputCategory):
for dirpath, dirnames, filenames in os.walk(outputDestination): for dirpath, dirnames, filenames in os.walk(outputDestination):
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)
if fileExtension in mediaContainer: # If the file is a video file if fileExtension in nzbtomedia.MEDIACONTAINER: # If the file is a video file
Logger.debug("MAIN: Found media file: %s", filePath) logger.debug("Found media file: %s", filePath)
video += 1 video += 1
if fileExtension in 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("MAIN: Found %s media files", str(video)) logger.debug("Found %s media files", str(video))
status = int(0) status = int(0)
elif not (config()["SickBeard"].issubsection(inputCategory) and config()["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination") and archive > int(0): elif not (nzbtomedia.CFG["SickBeard"].issubsection(inputCategory) and nzbtomedia.CFG["SickBeard"][inputCategory]["nzbExtractionBy"] == "Destination") and archive > int(0):
Logger.debug("MAIN: 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("MAIN: Found no media files in output.") logger.warning("Found no media files in output.")
if (inputCategory in user_script_categories and not "NONE" in user_script_categories) or ("ALL" in 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.info("MAIN: Processing user script %s.", user_script) logger.postprocess("Processing user script %s.", user_script)
result = external_script(outputDestination,inputName,inputCategory) result = external_script(outputDestination,inputName,inputCategory)
elif status == int(0) or (config()['HeadPhones','Mylar','Gamez'].issubsection(inputCategory)): # if movies linked/extracted or for other categories. elif status == int(0) or (nzbtomedia.CFG['HeadPhones','Mylar','Gamez'].issubsection(inputCategory)): # if movies linked/extracted or for other categories.
Logger.debug("MAIN: Calling autoProcess script for successful download.") logger.debug("Calling autoProcess script for successful download.")
status = int(0) # hp, my, gz don't support failed. status = int(0) # hp, my, gz don't support failed.
else: else:
Logger.error("MAIN: Something failed! Please check logs. Exiting") logger.error("Something failed! Please check logs. Exiting")
sys.exit(-1) sys.exit(-1)
result = 0 result = 0
if config()['CouchPotato'].issubsection(inputCategory): if nzbtomedia.CFG['CouchPotato'].issubsection(inputCategory):
Logger.info("MAIN: 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, nzbtomedia.CLIENTAGENT, download_id, inputCategory)
elif config()['SickBeard'].issubsection(inputCategory): elif nzbtomedia.CFG['SickBeard'].issubsection(inputCategory):
Logger.info("MAIN: 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, nzbtomedia.CLIENTAGENT, inputCategory)
elif config()['NzbDrone'].issubsection(inputCategory): elif nzbtomedia.CFG['NzbDrone'].issubsection(inputCategory):
Logger.info("MAIN: 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, nzbtomedia.CLIENTAGENT, inputCategory)
elif config()['HeadPhones'].issubsection(inputCategory): elif nzbtomedia.CFG['HeadPhones'].issubsection(inputCategory):
Logger.info("MAIN: Calling HeadPhones:" + inputCategory + " to post-process: %s", inputName) logger.postprocess("Calling HeadPhones:" + inputCategory + " to post-process: %s", inputName)
result = autoProcessMusic().process(inputDirectory, inputName, status, clientAgent, inputCategory) result = autoProcessMusic().process(inputDirectory, inputName, status, nzbtomedia.CLIENTAGENT, inputCategory)
elif config()['Mylar'].issubsection(inputCategory): elif nzbtomedia.CFG['Mylar'].issubsection(inputCategory):
Logger.info("MAIN: 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, nzbtomedia.CLIENTAGENT, inputCategory)
elif config()['Gamez'].issubsection(inputCategory): elif nzbtomedia.CFG['Gamez'].issubsection(inputCategory):
Logger.info("MAIN: 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, nzbtomedia.CLIENTAGENT, inputCategory)
if result == 1: if result == 1:
Logger.info("MAIN: A problem was reported in the autoProcess* script. If torrent was paused we will resume seeding") logger.error("A problem was reported in the autoProcess* script. If torrent was paused we will resume seeding")
resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName) resume_torrent(nzbtomedia.CLIENTAGENT, TorrentClass, inputHash, inputID, result, inputName)
cleanup_output(inputCategory, processCategories, result, outputDestination) cleanup_output(inputCategory, processCategories, result, outputDestination)
Logger.info("MAIN: All done.") logger.postprocess("All done.")
def create_torrent_class(clientAgent, inputHash): def create_torrent_class(clientAgent, inputHash):
# Hardlink solution for Torrents # Hardlink solution for Torrents
@ -221,31 +215,34 @@ def create_torrent_class(clientAgent, inputHash):
if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash: if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash:
if clientAgent == 'utorrent': if clientAgent == 'utorrent':
try: try:
Logger.debug("MAIN: Connecting to %s: %s", clientAgent, uTorrentWEBui) logger.debug("Connecting to %s: %s", clientAgent, nzbtomedia.UTORRENTWEBUI)
TorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD) TorrentClass = UTorrentClient(nzbtomedia.UTORRENTWEBUI, nzbtomedia.UTORRENTUSR, nzbtomedia.UTORRENTPWD)
except: except:
Logger.exception("MAIN: Failed to connect to uTorrent") logger.error("Failed to connect to uTorrent")
if clientAgent == 'transmission': if clientAgent == 'transmission':
try: try:
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, TransmissionHost, TransmissionPort) logger.debug("Connecting to %s: http://%s:%s", clientAgent, nzbtomedia.TRANSMISSIONHOST,
TorrentClass = TransmissionClient(TransmissionHost, TransmissionPort, TransmissionUSR, TransmissionPWD) nzbtomedia.TRANSMISSIONPORT)
TorrentClass = TransmissionClient(nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT, nzbtomedia.TRANSMISSIONUSR,
nzbtomedia.TRANSMISSIONPWD)
except: except:
Logger.exception("MAIN: Failed to connect to Transmission") logger.error("Failed to connect to Transmission")
if clientAgent == 'deluge': if clientAgent == 'deluge':
try: try:
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, DelugeHost, DelugePort) logger.debug("Connecting to %s: http://%s:%s", clientAgent, nzbtomedia.DELUGEHOST,
nzbtomedia.DELUGEPORT)
TorrentClass = DelugeClient() TorrentClass = DelugeClient()
TorrentClass.connect(host = DelugeHost, port = DelugePort, username = DelugeUSR, password = DelugePWD) TorrentClass.connect(host =nzbtomedia.DELUGEHOST, port =nzbtomedia.DELUGEPORT, username =nzbtomedia.DELUGEUSR, password =nzbtomedia.DELUGEPWD)
except: except:
Logger.exception("MAIN: 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("MAIN: 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 !="":
@ -258,8 +255,8 @@ def resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputN
# 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(config()["Torrent"]["deleteOriginal"]) is 1 and result != 1) or useLink == 'move': # if we move files, nothing to resume seeding. if (int(nzbtomedia.CFG["Torrent"]["deleteOriginal"]) is 1 and result != 1) or nzbtomedia.USELINK == 'move': # if we move files, nothing to resume seeding.
Logger.debug("MAIN: Deleting torrent %s from %s", inputName, clientAgent) 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)
@ -269,7 +266,7 @@ def resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputN
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("MAIN: 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 !="":
@ -286,16 +283,16 @@ def cleanup_output(inputCategory, processCategories, result, outputDestination):
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)
if fileExtension in mediaContainer or fileExtension in metaContainer: if fileExtension in nzbtomedia.MEDIACONTAINER or fileExtension in nzbtomedia.METACONTAINER:
num_files_new += 1 num_files_new += 1
file_list.append(file) file_list.append(file)
if num_files_new is 0 or int(config()["Torrent"]["forceClean"]) is 1: if num_files_new is 0 or int(nzbtomedia.CFG["Torrent"]["forceClean"]) is 1:
Logger.info("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)
else: else:
Logger.info("outputDirectory %s still contains %s media and/or meta files. This directory will not be removed.", outputDestination, num_files_new) logger.postprocess("outputDirectory %s still contains %s media and/or meta files. This directory will not be removed.", outputDestination, num_files_new)
for item in file_list: for item in file_list:
Logger.debug("media/meta file found: %s", item) logger.debug("media/meta file found: %s", item)
def external_script(outputDestination, torrentName, torrentLabel): def external_script(outputDestination, torrentName, torrentLabel):
@ -337,19 +334,19 @@ def external_script(outputDestination, torrentName, torrentLabel):
cmd = "" cmd = ""
for item in command: for item in command:
cmd = cmd + " " + item cmd = cmd + " " + item
Logger.info("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 user_script_successCodes: # Linux returns 0 for successful. if str(res) in user_script_successCodes: # Linux returns 0 for successful.
Logger.info("UserScript %s was successfull", command[0]) 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.info("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.exception("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
@ -364,90 +361,49 @@ def external_script(outputDestination, torrentName, torrentLabel):
num_files_new = num_files_new + 1 num_files_new = num_files_new + 1
if user_script_clean == int(1) and num_files_new == int(0) and final_result == int(0): if user_script_clean == int(1) and num_files_new == int(0) and final_result == int(0):
Logger.info("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 user_script_clean == int(1) and num_files_new != int(0): elif user_script_clean == int(1) and num_files_new != int(0):
Logger.info("%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
if __name__ == "__main__": if __name__ == "__main__":
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. # Initialize the config
if config().migrate(): nzbtomedia.initialize()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("TorrentToMedia %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
WakeUp()
# EXAMPLE VALUES: # EXAMPLE VALUES:
clientAgent = config()["Torrent"]["clientAgent"] # utorrent | deluge | transmission | rtorrent | other if not "NONE" in nzbtomedia.USER_SCRIPT_CATEGORIES:
useLink = config()["Torrent"]["useLink"] # no | hard | sym user_script_mediaExtensions = (nzbtomedia.CFG["UserScript"]["user_script_mediaExtensions"])
outputDirectory = config()["Torrent"]["outputDirectory"] # /abs/path/to/complete/ user_script = nzbtomedia.CFG["UserScript"]["user_script_path"]
categories = (config()["Torrent"]["categories"]) # music,music_videos,pictures,software user_script_param = (nzbtomedia.CFG["UserScript"]["user_script_param"])
noFlatten = (config()["Torrent"]["noFlatten"]) user_script_successCodes = (nzbtomedia.CFG["UserScript"]["user_script_successCodes"])
user_script_clean = int(nzbtomedia.CFG["UserScript"]["user_script_clean"])
user_delay = int(nzbtomedia.CFG["UserScript"]["delay"])
user_script_runOnce = int(nzbtomedia.CFG["UserScript"]["user_script_runOnce"])
uTorrentWEBui = config()["Torrent"]["uTorrentWEBui"] # http://localhost:8090/gui/ transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"])
uTorrentUSR = config()["Torrent"]["uTorrentUSR"] # mysecretusr
uTorrentPWD = config()["Torrent"]["uTorrentPWD"] # mysecretpwr
TransmissionHost = config()["Torrent"]["TransmissionHost"] # localhost
TransmissionPort = config()["Torrent"]["TransmissionPort"] # 8084
TransmissionUSR = config()["Torrent"]["TransmissionUSR"] # mysecretusr
TransmissionPWD = config()["Torrent"]["TransmissionPWD"] # mysecretpwr
DelugeHost = config()["Torrent"]["DelugeHost"] # localhost
DelugePort = config()["Torrent"]["DelugePort"] # 8084
DelugeUSR = config()["Torrent"]["DelugeUSR"] # mysecretusr
DelugePWD = config()["Torrent"]["DelugePWD"] # mysecretpwr
compressedContainer = (config()["Extensions"]["compressedExtensions"]) # .zip,.rar,.7z
mediaContainer = (config()["Extensions"]["mediaExtensions"]) # .mkv,.avi,.divx
metaContainer = (config()["Extensions"]["metaExtensions"]) # .nfo,.sub,.srt
minSampleSize = int(config()["Extensions"]["minSampleSize"]) # 200 (in MB)
SampleIDs = (config()["Extensions"]["SampleIDs"]) # sample,-s.
sections = ("CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez")
subsections = config()[sections].subsections
categories += config()[sections].sections
user_script_categories = config()["UserScript"]["user_script_categories"] # NONE
if not "NONE" in user_script_categories:
user_script_mediaExtensions = (config()["UserScript"]["user_script_mediaExtensions"])
user_script = config()["UserScript"]["user_script_path"]
user_script_param = (config()["UserScript"]["user_script_param"])
user_script_successCodes = (config()["UserScript"]["user_script_successCodes"])
user_script_clean = int(config()["UserScript"]["user_script_clean"])
user_delay = int(config()["UserScript"]["delay"])
user_script_runOnce = int(config()["UserScript"]["user_script_runOnce"])
transcode = int(config()["Transcoder"]["transcode"])
n = 0 n = 0
for arg in sys.argv: for arg in sys.argv:
Logger.debug("arg %s is: %s", n, arg) logger.debug("arg %s is: %s", n, arg)
n = n+1 n = n+1
try: try:
inputDirectory, inputName, inputCategory, inputHash, inputID = parse_args(clientAgent) inputDirectory, inputName, inputCategory, inputHash, inputID = parse_args(nzbtomedia.CLIENTAGENT)
except: except:
Logger.exception("MAIN: There was a problem loading variables") logger.error("There was a problem loading variables")
sys.exit(-1) sys.exit(-1)
# check if this is a manual run # check if this is a manual run
if inputDirectory is None: if inputDirectory is None:
for section, subsection in subsections.items(): for section, subsection in nzbtomedia.SUBSECTIONS.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: TorrentToMedia 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)
main(dirName, os.path.basename(dirName), category, inputHash, inputID) main(dirName, os.path.basename(dirName), category, inputHash, inputID)
else: else:
Logger.info("MAIN: nzbTo%s %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...",section, section, category) logger.warning("%s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category)
else: else:
main(inputDirectory, inputName, inputCategory, inputHash, inputID) main(inputDirectory, inputName, inputCategory, inputHash, inputID)

View file

@ -1,23 +0,0 @@
[loggers]
keys = root
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = NOTSET
handlers = console
qualname =
[handler_console]
class = StreamHandler
args = (sys.stdout,)
level = INFO
formatter = generic
[formatter_generic]
format = %(asctime)s|%(levelname)-7.7s %(message)s
datefmt = %H:%M:%S

View file

@ -1,23 +0,0 @@
[loggers]
keys = root
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = NOTSET
handlers = console
qualname =
[handler_console]
class = StreamHandler
args = (sys.stdout,)
level = INFO
formatter = generic
[formatter_generic]
format = %(asctime)s|%(levelname)-7.7s %(message)s
datefmt = %H:%M:%S

100
logs/nzbtomedia.log Normal file
View file

@ -0,0 +1,100 @@
2014-04-11 15:52:44 INFO :: MAIN :: nzbToMedia None
2014-04-11 15:52:44 INFO :: MAIN :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 15:52:44 POSTPROCESS:: CouchPotato:movie is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:52:44 POSTPROCESS:: NzbDrone:tv is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:52:44 WARNING :: MAIN :: SickBeard:tv has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 15:52:44 WARNING :: MAIN :: SickBeard:tvs has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 15:52:44 POSTPROCESS:: HeadPhones:music is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:52:44 POSTPROCESS:: Gamez:games is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:52:44 POSTPROCESS:: Mylar:comics is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:53:23 INFO :: nzbToMedia None
2014-04-11 15:53:23 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 15:53:23 POSTPROCESS:: CouchPotato:movie is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:53:23 POSTPROCESS:: NzbDrone:tv is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:53:23 WARNING :: SickBeard:tv has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 15:53:23 WARNING :: SickBeard:tvs has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 15:53:23 POSTPROCESS:: HeadPhones:music is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:53:23 POSTPROCESS:: Gamez:games is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:53:23 POSTPROCESS:: Mylar:comics is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:59:32 INFO :: nzbToMedia None
2014-04-11 15:59:32 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 15:59:32 WARNING :: CouchPotato:movie is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:59:32 WARNING :: NzbDrone:tv is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:59:32 WARNING :: SickBeard:tv has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 15:59:32 WARNING :: SickBeard:tvs has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 15:59:32 WARNING :: HeadPhones:music is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:59:32 WARNING :: Gamez:games is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 15:59:32 WARNING :: Mylar:comics is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 16:02:05 INFO :: nzbToMedia None
2014-04-11 16:02:05 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 16:02:05 INFO :: Checking if nzbToMedia needs an update
2014-04-11 16:02:46 INFO :: nzbToMedia None
2014-04-11 16:02:46 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 16:02:46 INFO :: Checking if nzbToMedia needs an update
2014-04-11 16:03:52 INFO :: nzbToMedia None
2014-04-11 16:03:52 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 16:03:52 INFO :: Checking if nzbToMedia needs an update
2014-04-11 16:06:18 INFO :: nzbToMedia None
2014-04-11 16:06:18 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 16:06:18 INFO :: Checking if nzbToMedia needs an update
2014-04-11 16:07:29 INFO :: nzbToMedia None
2014-04-11 16:07:29 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 16:07:29 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:16:55 INFO :: nzbToMedia None
2014-04-11 19:16:55 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:16:55 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:18:48 INFO :: nzbToMedia None
2014-04-11 19:18:48 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:18:48 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:22:01 INFO :: nzbToMedia None
2014-04-11 19:22:04 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:22:09 INFO :: nzbToMedia None
2014-04-11 19:22:26 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:22:41 INFO :: nzbToMedia None
2014-04-11 19:23:02 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:23:44 INFO :: nzbToMedia None
2014-04-11 19:23:45 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:23:48 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:25:01 INFO :: nzbToMedia None
2014-04-11 19:25:01 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:25:01 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:25:14 INFO :: nzbToMedia None
2014-04-11 19:25:14 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:25:14 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:25:44 INFO :: nzbToMedia None
2014-04-11 19:25:44 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:29:50 INFO :: nzbToMedia None
2014-04-11 19:29:50 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:29:50 WARNING :: CouchPotato:movie is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:29:50 WARNING :: NzbDrone:tv is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:29:50 WARNING :: SickBeard:tv has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 19:29:50 WARNING :: SickBeard:tvs has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 19:29:50 WARNING :: HeadPhones:music is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:29:50 WARNING :: Gamez:games is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:29:50 WARNING :: Mylar:comics is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:33:19 INFO :: nzbToMedia None
2014-04-11 19:33:19 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:33:19 WARNING :: CouchPotato:movie is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:33:19 WARNING :: NzbDrone:tv is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:33:19 WARNING :: SickBeard:tv has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 19:33:19 WARNING :: SickBeard:tvs has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.
2014-04-11 19:33:19 WARNING :: HeadPhones:music is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:33:19 WARNING :: Gamez:games is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:33:19 WARNING :: Mylar:comics is DISABLED, you can enable this in autoProcessMedia.cfg ...
2014-04-11 19:33:27 INFO :: nzbToMedia None
2014-04-11 19:33:27 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:33:30 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:37:17 POSTPROCESS:: nzbToMedia None
2014-04-11 19:37:17 POSTPROCESS:: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:37:17 POSTPROCESS:: Checking if nzbToMedia needs an update
2014-04-11 19:38:15 INFO :: nzbToMedia None
2014-04-11 19:38:15 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:38:15 POSTPROCESS:: test
2014-04-11 19:38:15 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:38:55 INFO :: nzbToMedia None
2014-04-11 19:38:55 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:38:55 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:39:26 INFO :: nzbToMedia None
2014-04-11 19:39:26 INFO :: Loading config from C:\Users\Justin\Documents\Git Projects\nzbToMedia\autoProcessMedia.cfg
2014-04-11 19:39:26 INFO :: Checking if nzbToMedia needs an update
2014-04-11 19:39:27 INFO :: Unknown current version number, don't know if we should update or not

View file

@ -1,10 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# adds lib directory to system path
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib')))
# #
############################################################################## ##############################################################################
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
@ -128,31 +122,20 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
############################################################################## ##############################################################################
import logging import logging
import os
import sys
import nzbtomedia
from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import get_dirnames
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames from nzbtomedia import logger
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. # Initialize the config
if config().migrate(): nzbtomedia.initialize()
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config().addnzbget()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("nzbToCouchPotato %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
WakeUp()
# 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.info("MAIN: Script triggered from NZBGet (11.0 or later).") logger.postprocess("Script triggered from NZBGet (11.0 or later).")
# NZBGet argv: all passed as environment variables. # NZBGet argv: all passed as environment variables.
clientAgent = "nzbget" clientAgent = "nzbget"
@ -161,49 +144,49 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
status = 0 status = 0
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.") logger.postprocess("Please check your Par-repair settings for future downloads.")
sys.exit(config.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':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"") logger.warning("Par-repair failed, setting status \"failed\"")
status = 1 status = 1
# Check unpack status # Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1': if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"") logger.warning("Unpack failed, setting status \"failed\"")
status = 1 status = 1
if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0': if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
# Unpack was skipped due to nzb-file properties or due to errors during par-check # Unpack was skipped due to nzb-file properties or due to errors during par-check
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
Logger.warning("MAIN: 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.info("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
Logger.info("MAIN: Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") 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("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("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("MAIN: 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
# All checks done, now launching the script. # All checks done, now launching the script.
download_id = "" download_id = ""
if os.environ.has_key('NZBPR_COUCHPOTATO'): download_id = os.environ['NZBPR_COUCHPOTATO'] if os.environ.has_key('NZBPR_COUCHPOTATO'): download_id = os.environ['NZBPR_COUCHPOTATO']
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessMovie...") logger.postprocess("Script triggered from NZBGet, starting autoProcessMovie...")
result = autoProcessMovie().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], clientAgent="nzbget", inputCategory=os.environ['NZBPP_CATEGORY']) result = autoProcessMovie().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], clientAgent="nzbget", inputCategory=os.environ['NZBPP_CATEGORY'])
# SABnzbd Pre 0.7.17 # SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS: elif len(sys.argv) == nzbtomedia.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -212,10 +195,10 @@ elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# 5 User-defined category # 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessMovie...") logger.postprocess("Script triggered from SABnzbd, starting autoProcessMovie...")
result = autoProcessMovie().process(sys.argv[1], sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='') result = autoProcessMovie().process(sys.argv[1], sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='')
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: elif len(sys.argv) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -225,31 +208,30 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# 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
# 8 Failure URL # 8 Failure URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessMovie...") logger.postprocess("Script triggered from SABnzbd 0.7.17+, starting autoProcessMovie...")
result = autoProcessMovie().process(sys.argv[1], sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='') result = autoProcessMovie().process(sys.argv[1], sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='')
else: else:
result = 0 result = 0
subsections = config()["CouchPotato"].subsections logger.warning("Invalid number of arguments received from client.")
Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in nzbtomedia.SUBSECTIONS['CouchPotato'].items():
for section, subsection in subsections.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: nzbToCouchPotato running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.postprocess("Running %s:%s as a manual run on folder %s ...", section, category, dirName)
results = autoProcessMovie().process(dirName, os.path.basename(dirName), 0, inputCategory=category) results = autoProcessMovie().process(dirName, os.path.basename(dirName), 0, inputCategory=category)
if results != 0: if results != 0:
result = results result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) logger.error("A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName)
else: else:
Logger.info("MAIN: nzbToCouchPotato %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.info("MAIN: The autoProcessMovie script completed successfully.") logger.postprocess("The script completed successfully.")
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(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
Logger.info("MAIN: A problem was reported in the autoProcessMovie script.") logger.error("A problem was reported in the script.")
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(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -1,10 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# adds lib directory to system path
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib')))
# #
############################################################################## ##############################################################################
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
@ -62,81 +56,67 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
############################################################################## ##############################################################################
import logging import os
import sys
import nzbtomedia
from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import get_dirnames
from nzbtomedia.nzbToMediaUtil import WakeUp, nzbtomedia_configure_logging, get_dirnames from nzbtomedia import logger
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. # Initialize the config
if config().migrate(): nzbtomedia.initialize()
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config().addnzbget()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("nzbToGamez %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
# gamez category
sections = config().get_subsections(['Gamez'])
WakeUp()
# 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.info("MAIN: Script triggered from NZBGet (11.0 or later).") logger.postprocess("Script triggered from NZBGet (11.0 or later).")
# Check nzbget.conf options # Check nzbget.conf options
status = 0 status = 0
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.") logger.postprocess("Please check your Par-repair settings for future downloads.")
sys.exit(config.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':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"") logger.warning("Par-repair failed, setting status \"failed\"")
status = 1 status = 1
# Check unpack status # Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1': if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"") logger.warning("Unpack failed, setting status \"failed\"")
status = 1 status = 1
if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0': if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
# Unpack was skipped due to nzb-file properties or due to errors during par-check # Unpack was skipped due to nzb-file properties or due to errors during par-check
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
Logger.warning("MAIN: 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.info("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
Logger.info("MAIN: Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") 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("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("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("MAIN: 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
# All checks done, now launching the script. # All checks done, now launching the script.
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessGames...") logger.postprocess("Script triggered from NZBGet, starting post-processing ...")
clientAgent = "nzbget" clientAgent = "nzbget"
result = autoProcessGames().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY']) result = autoProcessGames().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY'])
# SABnzbd Pre 0.7.17 # SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS: elif len(sys.argv) == nzbtomedia.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -145,11 +125,11 @@ elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# 5 User-defined category # 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessGames...") logger.postprocess("Script triggered from SABnzbd, starting post-processing ...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessGames().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessGames().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: elif len(sys.argv) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -159,32 +139,31 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# 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
# 8 Failure URL # 8 Failure URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessGames...") logger.postprocess("Script triggered from SABnzbd 0.7.17+, starting post-processing ...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessGames().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessGames().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
else: else:
result = 0 result = 0
subsections = config()["Gamez"].subsections logger.warning("Invalid number of arguments received from client.")
Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in nzbtomedia.SUBSECTIONS['Gamez'].items():
for section, subsection in subsections.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: nzbToGamez running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.postprocess("Running %s:%s as a manual run on folder %s ...", section, category, dirName)
results = autoProcessGames().process(dirName, os.path.basename(dirName), 0, inputCategory=category) results = autoProcessGames().process(dirName, os.path.basename(dirName), 0, inputCategory=category)
if results != 0: if results != 0:
result = results result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) logger.error("A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName)
else: else:
Logger.info("MAIN: nzbToGamez %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.info("MAIN: The autoProcessGames script completed successfully.") logger.postprocess("The script completed successfully.")
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(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
Logger.info("MAIN: A problem was reported in the autoProcessGames script.") logger.error("A problem was reported in the script.")
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(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -1,10 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# adds lib directory to system path
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib')))
# #
############################################################################## ##############################################################################
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
@ -72,81 +66,67 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
############################################################################## ##############################################################################
import os
import sys
import nzbtomedia
# NZBGet argv: all passed as environment variables.
# Exit codes used by NZBGet
import logging
from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import get_dirnames
from nzbtomedia.nzbToMediaUtil import get_dirnames, WakeUp, nzbtomedia_configure_logging from nzbtomedia import logger
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. # Initialize the config
if config().migrate(): nzbtomedia.initialize()
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config().addnzbget()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("nzbToHeadPhones %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
WakeUp()
# 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.info("MAIN: Script triggered from NZBGet (11.0 or later).") logger.postprocess("Script triggered from NZBGet (11.0 or later).")
# Check nzbget.conf options # Check nzbget.conf options
status = 0 status = 0
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.") logger.postprocess("Please check your Par-repair settings for future downloads.")
sys.exit(config.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':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"") logger.warning("Par-repair failed, setting status \"failed\"")
status = 1 status = 1
# Check unpack status # Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1': if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"") logger.warning("Unpack failed, setting status \"failed\"")
status = 1 status = 1
if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0': if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
# Unpack was skipped due to nzb-file properties or due to errors during par-check # Unpack was skipped due to nzb-file properties or due to errors during par-check
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
Logger.warning("MAIN: 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.info("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
Logger.info("MAIN: Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") 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("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("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("MAIN: 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
# All checks done, now launching the script. # All checks done, now launching the script.
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessMusic...") logger.postprocess("Script triggered from NZBGet, starting autoProcessMusic...")
clientAgent = "nzbget" clientAgent = "nzbget"
result = autoProcessMusic().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY']) result = autoProcessMusic().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY'])
# SABnzbd Pre 0.7.17 # SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS: elif len(sys.argv) == nzbtomedia.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -155,11 +135,11 @@ elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# 5 User-defined category # 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessMusic...") logger.postprocess("Script triggered from SABnzbd, starting autoProcessMusic...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessMusic().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessMusic().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: elif len(sys.argv) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -169,33 +149,32 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# 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
# 8 Failue URL # 8 Failue URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessMusic...") logger.postprocess("Script triggered from SABnzbd 0.7.17+, starting autoProcessMusic...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessMusic().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessMusic().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
else: else:
result = 0 result = 0
subsections = config()["HeadPhones"].subsections logger.warning("Invalid number of arguments received from client.")
Logger.warn("MAIN: Invalid number of arguments received from client.") for section, subsection in nzbtomedia.SUBSECTIONS['HeadPhones'].items():
for section, subsection in subsections.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: nzbToHeadPhones running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.postprocess("nzbToHeadPhones running %s:%s as a manual run on folder %s ...", section, category, dirName)
results = autoProcessMusic().process(dirName, os.path.basename(dirName), 0, inputCategory=category) results = autoProcessMusic().process(dirName, os.path.basename(dirName), 0, inputCategory=category)
if results != 0: if results != 0:
result = results result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) logger.error("A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName)
else: else:
Logger.info("MAIN: nzbToHeadPhones %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) logger.postprocess("nzbToHeadPhones %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category)
if result == 0: if result == 0:
Logger.info("MAIN: The autoProcessMusic script completed successfully.") logger.postprocess("The autoProcessMusic script completed successfully.")
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(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
Logger.info("MAIN: A problem was reported in the autoProcessMusic script.") logger.error("A problem was reported in the autoProcessMusic script.")
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(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -1,10 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# adds lib directory to system path
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib')))
# #
############################################################################## ##############################################################################
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
@ -305,57 +299,44 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
############################################################################## ##############################################################################
import logging import os
import sys
import nzbtomedia
from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics
from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames
from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie
from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import get_dirnames
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames 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):
if config()["CouchPotato"].issubsection(inputCategory): if nzbtomedia.CFG["CouchPotato"].issubsection(inputCategory):
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName) logger.postprocess("Calling CouchPotatoServer to post-process: %s", logger.MESSAGE), inputName
return autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory) return autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory)
elif config()["SickBeard", "NzbDrone"].issubsection(inputCategory): elif nzbtomedia.CFG["SickBeard", "NzbDrone"].issubsection(inputCategory):
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName) logger.postprocess("Calling Sick-Beard to post-process: %s",logger.MESSAGE), inputName
return autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) return autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
elif config()["HeadPhones"].issubsection(inputCategory): elif nzbtomedia.CFG["HeadPhones"].issubsection(inputCategory):
Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName) logger.postprocess("Calling HeadPhones to post-process: %s", logger.MESSAGE), inputName
return autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory) return autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory)
elif config()["Mylar"].issubsection(inputCategory): elif nzbtomedia.CFG["Mylar"].issubsection(inputCategory):
Logger.info("MAIN: Calling Mylar to post-process: %s", inputName) logger.postprocess("Calling Mylar to post-process: %s",logger.MESSAGE), inputName
return autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory) return autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
elif config()["Gamez"].issubsection(inputCategory): elif nzbtomedia.CFG["Gamez"].issubsection(inputCategory):
Logger.info("MAIN: Calling Gamez to post-process: %s", inputName) logger.postprocess("Calling Gamez to post-process: %s",logger.MESSAGE), inputName
return autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory) return autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory)
else: else:
Logger.warning("MAIN: We could not find the section %s with a download category of %s in your autoProcessMedia.cfg. Exiting.", section, inputCategory) logger.postprocess("We could not find the section %s with a download category of %s in your autoProcessMedia.cfg. Exiting.",logger.WARNING), section, inputCategory
return -1 return -1
######################################################################################################################## ########################################################################################################################
logger.postprocess("====================") # Seperate old from new log
logger.postprocess("nzbToMedia %s", nzbtomedia.NZBTOMEDIA_VERSION)
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. logger.postprocess("Loading config from %s", nzbtomedia.CONFIG_FILE)
if config().migrate():
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config().addnzbget()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger()
Logger.info("====================") # Seperate old from new log
Logger.info("nzbToMedia %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
print("Unable to find " + config.CONFIG_FILE + " or " + config.SAMPLE_CONFIG_FILE)
sys.exit(-1)
WakeUp()
# Post-Processing Result # Post-Processing Result
result = 0 result = 0
@ -363,7 +344,7 @@ result = 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.info("MAIN: Script triggered from NZBGet (11.0 or later).") logger.postprocess("Script triggered from NZBGet (11.0 or later).")
# NZBGet argv: all passed as environment variables. # NZBGet argv: all passed as environment variables.
clientAgent = "nzbget" clientAgent = "nzbget"
@ -372,48 +353,48 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
status = 0 status = 0
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.") logger.postprocess("Please check your Par-repair settings for future downloads.")
sys.exit(config.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':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"") logger.warning("Par-repair failed, setting status \"failed\"")
status = 1 status = 1
# Check unpack status # Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1': if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"") logger.warning("Unpack failed, setting status \"failed\"")
status = 1 status = 1
if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0': if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
# Unpack was skipped due to nzb-file properties or due to errors during par-check # Unpack was skipped due to nzb-file properties or due to errors during par-check
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
Logger.warning("MAIN: 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.info("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
Logger.info("MAIN: Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") 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("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("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("MAIN: 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
# All checks done, now launching the script. # All checks done, now launching the script.
download_id = "" download_id = ""
if os.environ.has_key('NZBPR_COUCHPOTATO'):download_id = os.environ['NZBPR_COUCHPOTATO'] if os.environ.has_key('NZBPR_COUCHPOTATO'):download_id = os.environ['NZBPR_COUCHPOTATO']
result = process(os.environ['NZBPP_DIRECTORY'], inputName=os.environ['NZBPP_NZBFILENAME'], clientAgent = "nzbget", inputCategory=os.environ['NZBPP_CATEGORY']) result = process(os.environ['NZBPP_DIRECTORY'], inputName=os.environ['NZBPP_NZBFILENAME'], clientAgent = "nzbget", inputCategory=os.environ['NZBPP_CATEGORY'])
if result != 0: Logger.info("MAIN: A problem was reported in the autoProcess* script.") if result != 0: logger.error("A problem was reported in the autoProcess* script.")
# SABnzbd Pre 0.7.17 # SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS: elif len(sys.argv) == nzbtomedia.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -422,11 +403,11 @@ elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# 5 User-defined category # 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd") logger.postprocess("Script triggered from SABnzbd")
result = process(sys.argv[1], inputName=sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='') result = process(sys.argv[1], inputName=sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='')
if result != 0: Logger.info("MAIN: A problem was reported in the autoProcess* script.") if result != 0: logger.error("A problem was reported in the autoProcess* script.")
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: elif len(sys.argv) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -436,33 +417,33 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# 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
# 8 Failure URL # 8 Failure URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+") logger.postprocess("Script triggered from SABnzbd 0.7.17+")
result = process(sys.argv[1], inputName=sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='') result = process(sys.argv[1], inputName=sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='')
if result != 0:Logger.info("MAIN: A problem was reported in the autoProcess* script.") if result != 0:logger.error("A problem was reported in the autoProcess* script.")
else: else:
result = 0 result = 0
# init sub-sections # init sub-sections
subsections = config()["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"].subsections subsections = nzbtomedia.CFG["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"].subsections
Logger.warn("MAIN: Invalid number of arguments received from client.") logger.warning("Invalid number of arguments received from client.")
for section, subsection in subsections.items(): for section, subsection in subsections.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: nzbToMedia running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.postprocess("nzbToMedia running %s:%s as a manual run on folder %s ...", section, category, dirName)
results = process(dirName, os.path.basename(dirName), 0, inputCategory=category) results = process(dirName, os.path.basename(dirName), 0, inputCategory=category)
if results != 0: if results != 0:
result = results result = results
Logger.info("MAIN: 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.info("MAIN: nzbToMedia %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) logger.postprocess("nzbToMedia %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category)
if result == 0: if result == 0:
Logger.info("MAIN: The nzbToMedia script completed successfully.") logger.postprocess("The nzbToMedia script completed successfully.")
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(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
Logger.info("MAIN: A problem was reported in the nzbToMedia script.") logger.error("A problem was reported in the nzbToMedia script.")
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(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -67,78 +67,63 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
############################################################################## ##############################################################################
# Exit codes used by NZBGet # Exit codes used by NZBGet
import logging import nzbtomedia
from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import get_dirnames
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames from nzbtomedia import logger
# Initialize the config
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. nzbtomedia.initialize()
if config().migrate():
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config().addnzbget()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("nzbToMylar %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
WakeUp()
# 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.info("MAIN: Script triggered from NZBGet (11.0 or later).") logger.postprocess("Script triggered from NZBGet (11.0 or later).")
# Check nzbget.conf options # Check nzbget.conf options
status = 0 status = 0
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.") logger.postprocess("Please check your Par-repair settings for future downloads.")
sys.exit(config.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':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"") logger.warning("Par-repair failed, setting status \"failed\"")
status = 1 status = 1
# Check unpack status # Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1': if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"") logger.warning("Unpack failed, setting status \"failed\"")
status = 1 status = 1
if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0': if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
# Unpack was skipped due to nzb-file properties or due to errors during par-check # Unpack was skipped due to nzb-file properties or due to errors during par-check
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
Logger.warning("MAIN: 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.info("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
Logger.info("MAIN: Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") 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("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("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("MAIN: 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
# All checks done, now launching the script. # All checks done, now launching the script.
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessComics...") logger.postprocess("Script triggered from NZBGet, starting autoProcessComics...")
clientAgent = "nzbget" clientAgent = "nzbget"
result = autoProcessComics().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY']) result = autoProcessComics().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY'])
# SABnzbd Pre 0.7.17 # SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS: elif len(sys.argv) == nzbtomedia.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -147,11 +132,11 @@ elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# 5 User-defined category # 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessComics...") logger.postprocess("Script triggered from SABnzbd, starting autoProcessComics...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessComics().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessComics().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: elif len(sys.argv) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -161,32 +146,32 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# 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
# 8 Failure URL # 8 Failure URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessComics...") logger.postprocess("Script triggered from SABnzbd 0.7.17+, starting autoProcessComics...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessComics().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessComics().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
else: else:
result = 0 result = 0
subsections = config()["Mylar"].subsections subsections = nzbtomedia.CFG["Mylar"].subsections
Logger.warn("MAIN: Invalid number of arguments received from client.") logger.warning("Invalid number of arguments received from client.")
for section, subsection in subsections.items(): for section, subsection in subsections.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: nzbToMylar running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.postprocess("nzbToMylar running %s:%s as a manual run on folder %s ...", section, category, dirName)
results = autoProcessComics().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category) results = autoProcessComics().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category)
if results != 0: if results != 0:
result = results result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) logger.error("A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName)
else: else:
Logger.info("MAIN: nzbToMylar %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) logger.postprocess("nzbToMylar %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category)
if result == 0: if result == 0:
Logger.info("MAIN: The autoProcessComics script completed successfully.") logger.postprocess("The autoProcessComics script completed successfully.")
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(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
Logger.info("MAIN: A problem was reported in the autoProcessComics script.") logger.error("A problem was reported in the autoProcessComics script.")
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(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -96,78 +96,64 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
############################################################################## ##############################################################################
import logging import nzbtomedia
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import get_dirnames
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames from nzbtomedia import logger
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. # Initialize the config
if config().migrate(): nzbtomedia.initialize()
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config().addnzbget()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("nzbToNzbDrone %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
WakeUp()
# 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.info("MAIN: Script triggered from NZBGet (11.0 or later).") logger.postprocess("Script triggered from NZBGet (11.0 or later).")
# Check nzbget.conf options # Check nzbget.conf options
status = 0 status = 0
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.") logger.postprocess("Please check your Par-repair settings for future downloads.")
sys.exit(config.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':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"") logger.warning("Par-repair failed, setting status \"failed\"")
status = 1 status = 1
# Check unpack status # Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1': if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"") logger.warning("Unpack failed, setting status \"failed\"")
status = 1 status = 1
if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0': if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
# Unpack was skipped due to nzb-file properties or due to errors during par-check # Unpack was skipped due to nzb-file properties or due to errors during par-check
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
Logger.warning("MAIN: 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.info("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
Logger.info("MAIN: Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") 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("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("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("MAIN: 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
# All checks done, now launching the script. # All checks done, now launching the script.
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessTV...") logger.postprocess("Script triggered from NZBGet, starting autoProcessTV...")
clientAgent = "nzbget" clientAgent = "nzbget"
result = autoProcessTV().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY']) result = autoProcessTV().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY'])
# SABnzbd Pre 0.7.17 # SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS: elif len(sys.argv) == nzbtomedia.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -176,11 +162,11 @@ elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# 5 User-defined category # 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessTV...") logger.postprocess("Script triggered from SABnzbd, starting autoProcessTV...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: elif len(sys.argv) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -190,32 +176,32 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# 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
# 8 Failure URL # 8 Failure URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessTV...") logger.postprocess("Script triggered from SABnzbd 0.7.17+, starting autoProcessTV...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
else: else:
result = 0 result = 0
subsections = config()["NzbDrone"].subsections subsections = nzbtomedia.CFG["NzbDrone"].subsections
Logger.warn("MAIN: Invalid number of arguments received from client.") logger.warning("Invalid number of arguments received from client.")
for section, subsection in subsections.items(): for section, subsection in subsections.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: nzbToNzbDrone running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.postprocess("nzbToNzbDrone running %s:%s as a manual run on folder %s ...", section, category, dirName)
results = autoProcessTV().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category) results = autoProcessTV().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category)
if results != 0: if results != 0:
result = results result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) logger.error("A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName)
else: else:
Logger.info("MAIN: nzbToNzbDrone %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) logger.postprocess("nzbToNzbDrone %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category)
if result == 0: if result == 0:
Logger.info("MAIN: The autoProcessTV script completed successfully.") logger.postprocess("The autoProcessTV script completed successfully.")
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(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
Logger.info("MAIN: A problem was reported in the autoProcessTV script.") logger.error("A problem was reported in the autoProcessTV script.")
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(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -129,78 +129,64 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
### NZBGET POST-PROCESSING SCRIPT ### ### NZBGET POST-PROCESSING SCRIPT ###
############################################################################## ##############################################################################
import logging import nzbtomedia
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia.nzbToMediaUtil import get_dirnames
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames from nzbtomedia import logger
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options. # Initialize the config
if config().migrate(): nzbtomedia.initialize()
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config().addnzbget()
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("nzbToSickBeard %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
WakeUp()
# 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.info("MAIN: Script triggered from NZBGet (11.0 or later).") logger.postprocess("Script triggered from NZBGet (11.0 or later).")
# Check nzbget.conf options # Check nzbget.conf options
status = 0 status = 0
if os.environ['NZBOP_UNPACK'] != 'yes': if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting") logger.error("Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)
# Check par status # Check par status
if os.environ['NZBPP_PARSTATUS'] == '3': if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting") logger.warning("Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.") logger.postprocess("Please check your Par-repair settings for future downloads.")
sys.exit(config.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':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"") logger.warning("Par-repair failed, setting status \"failed\"")
status = 1 status = 1
# Check unpack status # Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1': if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"") logger.warning("Unpack failed, setting status \"failed\"")
status = 1 status = 1
if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0': if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
# Unpack was skipped due to nzb-file properties or due to errors during par-check # Unpack was skipped due to nzb-file properties or due to errors during par-check
if os.environ['NZBPP_HEALTH'] < 1000: if os.environ['NZBPP_HEALTH'] < 1000:
Logger.warning("MAIN: 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.info("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("Please check your Par-check/repair settings for future downloads.")
status = 1 status = 1
else: else:
Logger.info("MAIN: Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful") 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("MAIN: Please check your Par-check/repair settings for future downloads.") logger.postprocess("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("MAIN: 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
# All checks done, now launching the script. # All checks done, now launching the script.
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessTV...") logger.postprocess("Script triggered from NZBGet, starting autoProcessTV...")
clientAgent = "nzbget" clientAgent = "nzbget"
result = autoProcessTV().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY']) result = autoProcessTV().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY'])
# SABnzbd Pre 0.7.17 # SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS: elif len(sys.argv) == nzbtomedia.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -209,11 +195,11 @@ elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# 5 User-defined category # 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessTV...") logger.postprocess("Script triggered from SABnzbd, starting autoProcessTV...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
# SABnzbd 0.7.17+ # SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS: elif len(sys.argv) >= nzbtomedia.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv: # SABnzbd argv:
# 1 The final directory of the job (full path) # 1 The final directory of the job (full path)
# 2 The original name of the NZB file # 2 The original name of the NZB file
@ -223,32 +209,32 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# 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
# 8 Failure URL # 8 Failure URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessTV...") logger.postprocess("Script triggered from SABnzbd 0.7.17+, starting autoProcessTV...")
clientAgent = "sabnzbd" clientAgent = "sabnzbd"
result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5]) result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
else: else:
result = 0 result = 0
subsections = config()["SickBeard"].subsections subsections = nzbtomedia.CFG["SickBeard"].subsections
Logger.warn("MAIN: Invalid number of arguments received from client.") logger.warning("Invalid number of arguments received from client.")
for section, subsection in subsections.items(): for section, subsection in subsections.items():
for category in subsection: for category in subsection:
if config()[section].isenabled(category): if nzbtomedia.CFG[section].isenabled(category):
dirNames = get_dirnames(section, category) dirNames = get_dirnames(section, category)
for dirName in dirNames: for dirName in dirNames:
Logger.info("MAIN: nzbToSickBeard running %s:%s as a manual run on folder %s ...", section, category, dirName) logger.postprocess("nzbToSickBeard running %s:%s as a manual run on folder %s ...", section, category, dirName)
results = autoProcessTV().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category) results = autoProcessTV().processEpisode(dirName, os.path.basename(dirName), 0, inputCategory=category)
if results != 0: if results != 0:
result = results result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName) logger.error("A problem was reported when trying to manually run %s:%s on folder %s ...", section, category, dirName)
else: else:
Logger.info("MAIN: nzbToSickBeard %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category) logger.postprocess("nzbToSickBeard %s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ...", section, category)
if result == 0: if result == 0:
Logger.info("MAIN: The autoProcessTV script completed successfully.") logger.postprocess("The autoProcessTV script completed successfully.")
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(config.NZBGET_POSTPROCESS_SUCCESS) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_SUCCESS)
else: else:
Logger.info("MAIN: A problem was reported in the autoProcessTV script.") logger.error("A problem was reported in the autoProcessTV script.")
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(config.NZBGET_POSTPROCESS_ERROR) sys.exit(nzbtomedia.NZBGET_POSTPROCESS_ERROR)

View file

@ -14,15 +14,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'
@ -30,33 +30,33 @@ class Transcoder:
ffmpeg = 'ffmpeg' ffmpeg = 'ffmpeg'
useNiceness = True useNiceness = True
Logger.info("Loading config from %s", config.CONFIG_FILE) logger.info("Loading config from %s", nzbtomedia.CONFIG_FILE)
if not config(): if not nzbtomedia.CFG:
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
return 1 # failure return 1 # failure
mediaContainer = (config()["Transcoder"]["duplicate"]) mediaContainer = (nzbtomedia.CFG["Transcoder"]["duplicate"])
duplicate = int(config()["Transcoder"]["duplicate"]) duplicate = int(nzbtomedia.CFG["Transcoder"]["duplicate"])
ignoreExtensions = (config()["Transcoder"]["ignoreExtensions"]) ignoreExtensions = (nzbtomedia.CFG["Transcoder"]["ignoreExtensions"])
outputVideoExtension = config()["Transcoder"]["outputVideoExtension"].strip() outputVideoExtension = nzbtomedia.CFG["Transcoder"]["outputVideoExtension"].strip()
outputVideoCodec = config()["Transcoder"]["outputVideoCodec"].strip() outputVideoCodec = nzbtomedia.CFG["Transcoder"]["outputVideoCodec"].strip()
outputVideoPreset = config()["Transcoder"]["outputVideoPreset"].strip() outputVideoPreset = nzbtomedia.CFG["Transcoder"]["outputVideoPreset"].strip()
outputVideoFramerate = config()["Transcoder"]["outputVideoFramerate"].strip() outputVideoFramerate = nzbtomedia.CFG["Transcoder"]["outputVideoFramerate"].strip()
outputVideoBitrate = config()["Transcoder"]["outputVideoBitrate"].strip() outputVideoBitrate = nzbtomedia.CFG["Transcoder"]["outputVideoBitrate"].strip()
outputAudioCodec = config()["Transcoder"]["outputAudioCodec"].strip() outputAudioCodec = nzbtomedia.CFG["Transcoder"]["outputAudioCodec"].strip()
outputAudioBitrate = config()["Transcoder"]["outputAudioBitrate"].strip() outputAudioBitrate = nzbtomedia.CFG["Transcoder"]["outputAudioBitrate"].strip()
outputSubtitleCodec = config()["Transcoder"]["outputSubtitleCodec"].strip() outputSubtitleCodec = nzbtomedia.CFG["Transcoder"]["outputSubtitleCodec"].strip()
outputFastStart = int(config()["Transcoder"]["outputFastStart"]) outputFastStart = int(nzbtomedia.CFG["Transcoder"]["outputFastStart"])
outputQualityPercent = int(config()["Transcoder"]["outputQualityPercent"]) outputQualityPercent = int(nzbtomedia.CFG["Transcoder"]["outputQualityPercent"])
niceness = None niceness = None
if useNiceness:niceness = int(config()["Transcoder"]["niceness"]) if useNiceness:niceness = int(nzbtomedia.CFG["Transcoder"]["niceness"])
map(lambda ext: ext.strip(), mediaContainer) map(lambda ext: ext.strip(), mediaContainer)
map(lambda ext: ext.strip(), ignoreExtensions) map(lambda ext: ext.strip(), ignoreExtensions)
Logger.info("Checking for files to be transcoded") logger.info("Checking for files to be transcoded")
final_result = 0 # initialize as successful final_result = 0 # initialize as successful
for dirpath, dirnames, filenames in os.walk(dirName): for dirpath, dirnames, filenames in os.walk(dirName):
for file in filenames: for file in filenames:
@ -64,7 +64,7 @@ class Transcoder:
name, ext = os.path.splitext(filePath) name, ext = os.path.splitext(filePath)
if ext in mediaContainer: # If the file is a video file if ext in mediaContainer: # If the file is a video file
if ext in ignoreExtensions: if ext in 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'
@ -119,26 +119,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.exception("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 duplicate == 0: # we get rid of the original file if 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

@ -0,0 +1,163 @@
import os
import sys
from nzbtomedia import logger
from nzbtomedia.nzbToMediaConfig import config
# sabnzbd constants
from nzbtomedia.nzbToMediaUtil import WakeUp
SABNZB_NO_OF_ARGUMENTS = 8
SABNZB_0717_NO_OF_ARGUMENTS = 9
# sickbeard fork/branch constants
FORKS = {}
FORK_DEFAULT = "default"
FORK_FAILED = "failed"
FORK_FAILED_TORRENT = "failed-torrent"
FORKS[FORK_DEFAULT] = {"dir": None, "method": None}
FORKS[FORK_FAILED] = {"dirName": None, "failed": None}
FORKS[FORK_FAILED_TORRENT] = {"dir": None, "failed": None, "process_method": None}
SICKBEARD_FAILED = [FORK_FAILED, FORK_FAILED_TORRENT]
SICKBEARD_TORRENT = [FORK_FAILED_TORRENT]
# NZBGet Exit Codes
NZBGET_POSTPROCESS_PARCHECK = 92
NZBGET_POSTPROCESS_SUCCESS = 93
NZBGET_POSTPROCESS_ERROR = 94
NZBGET_POSTPROCESS_NONE = 95
# config constants
CFG = None
CFG_LOGGING = None
PROGRAM_DIR = ''
LOG_DIR = ''
LOG_FILE = ''
CONFIG_FILE = ''
CONFIG_SPEC_FILE = ''
CONFIG_MOVIE_FILE = ''
CONFIG_TV_FILE = ''
SYS_ENCODING = ''
# version constants
NZBTOMEDIA_VERSION = None
NEWEST_VERSION = None
NEWEST_VERSION_STRING = None
VERSION_NOTIFY = None
CLIENTAGENT = None
USELINK = None
OUTPUTDIRECTORY = None
CATEGORIES = []
NOFLATTEN = []
UTORRENTWEBUI = None
UTORRENTUSR = None
UTORRENTPWD = None
TRANSMISSIONHOST = None
TRANSMISSIONPORT = None
TRANSMISSIONUSR = None
TRANSMISSIONPWD = None
DELUGEHOST = None
DELUGEPORT = None
DELUGEUSR = None
DELUGEPWD = None
COMPRESSEDCONTAINER = None
MEDIACONTAINER = None
METACONTAINER = None
MINSAMPLESIZE = None
SAMPLEIDS = None
SECTIONS = []
SUBSECTIONS = {}
USER_SCRIPT_CATEGORIES = None
__INITIALIZED__ = False
def initialize():
global NZBGET_POSTPROCESS_ERROR, NZBGET_POSTPROCESS_NONE, NZBGET_POSTPROCESS_PARCHECK, NZBGET_POSTPROCESS_SUCCESS, \
NZBTOMEDIA_TIMEOUT, FORKS, FORK_DEFAULT, FORK_FAILED_TORRENT, FORK_FAILED, SICKBEARD_TORRENT, SICKBEARD_FAILED, \
PROGRAM_DIR, CFG, CFG_LOGGING, CONFIG_FILE, CONFIG_MOVIE_FILE, CONFIG_SPEC_FILE, LOG_DIR, \
CONFIG_TV_FILE, LOG_FILE, NZBTOMEDIA_VERSION, NEWEST_VERSION, NEWEST_VERSION_STRING, VERSION_NOTIFY, \
SABNZB_NO_OF_ARGUMENTS, SABNZB_0717_NO_OF_ARGUMENTS, CATEGORIES, CLIENTAGENT, USELINK, OUTPUTDIRECTORY, NOFLATTEN, \
UTORRENTPWD, UTORRENTUSR, UTORRENTWEBUI, DELUGEHOST, DELUGEPORT, DELUGEUSR, DELUGEPWD, TRANSMISSIONHOST, TRANSMISSIONPORT, \
TRANSMISSIONPWD, TRANSMISSIONUSR, COMPRESSEDCONTAINER, MEDIACONTAINER, METACONTAINER, MINSAMPLESIZE, SAMPLEIDS, \
SECTIONS, SUBSECTIONS, USER_SCRIPT_CATEGORIES, __INITIALIZED__
if __INITIALIZED__:
return False
# add our custom libs to the system path
sys.path.insert(0, os.path.abspath(os.path.join(PROGRAM_DIR, 'lib')))
# init paths and filenames
PROGRAM_DIR = os.path.dirname(os.path.normpath(os.path.abspath(os.path.join(__file__, os.pardir))))
LOG_DIR = os.path.join(PROGRAM_DIR, 'logs')
LOG_FILE = os.path.join(LOG_DIR, 'postprocess.log')
CONFIG_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg")
CONFIG_SPEC_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg.spec")
CONFIG_MOVIE_FILE = os.path.join(PROGRAM_DIR, "autoProcessMovie.cfg")
CONFIG_TV_FILE = os.path.join(PROGRAM_DIR, "autoProcessTv.cfg")
if not nzbToMediaUtil.makeDir(LOG_DIR):
logger.error("!!! No log folder, logging to screen only!")
# init logging
logger.ntm_log_instance.initLogging()
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
if not config.migrate():
logger.error("Unable to load config from %s", CONFIG_FILE)
sys.exit(-1)
if os.environ.has_key('NZBOP_SCRIPTDIR'):
config.addnzbget()
NZBTOMEDIA_VERSION = 'nzbToMedia ' + version.SICKBEARD_VERSION.replace(' ', '-') + ' (' + sys.platform.system() + '; ' + sys.platform.release()
logger.info("nzbToMedia %s", NZBTOMEDIA_VERSION)
logger.info("Loading config from %s", CONFIG_FILE)
WakeUp()
CLIENTAGENT = CFG["Torrent"]["clientAgent"] # utorrent | deluge | transmission | rtorrent | other
USELINK = CFG["Torrent"]["useLink"] # no | hard | sym
OUTPUTDIRECTORY = CFG["Torrent"]["outputDirectory"] # /abs/path/to/complete/
CATEGORIES = (CFG["Torrent"]["categories"]) # music,music_videos,pictures,software
NOFLATTEN = (CFG["Torrent"]["noFlatten"])
UTORRENTWEBUI = CFG["Torrent"]["uTorrentWEBui"] # http://localhost:8090/gui/
UTORRENTUSR = CFG["Torrent"]["uTorrentUSR"] # mysecretusr
UTORRENTPWD = CFG["Torrent"]["uTorrentPWD"] # mysecretpwr
TRANSMISSIONHOST = CFG["Torrent"]["TransmissionHost"] # localhost
TRANSMISSIONPORT = CFG["Torrent"]["TransmissionPort"] # 8084
TRANSMISSIONUSR = CFG["Torrent"]["TransmissionUSR"] # mysecretusr
TRANSMISSIONPWD = CFG["Torrent"]["TransmissionPWD"] # mysecretpwr
DELUGEHOST = CFG["Torrent"]["DelugeHost"] # localhost
DELUGEPORT = CFG["Torrent"]["DelugePort"] # 8084
DELUGEUSR = CFG["Torrent"]["DelugeUSR"] # mysecretusr
DELUGEPWD = CFG["Torrent"]["DelugePWD"] # mysecretpwr
COMPRESSEDCONTAINER = (CFG["Extensions"]["compressedExtensions"]) # .zip,.rar,.7z
MEDIACONTAINER = (CFG["Extensions"]["mediaExtensions"]) # .mkv,.avi,.divx
METACONTAINER = (CFG["Extensions"]["metaExtensions"]) # .nfo,.sub,.srt
MINSAMPLESIZE = int(CFG["Extensions"]["minSampleSize"]) # 200 (in MB)
SAMPLEIDS = (CFG["Extensions"]["SampleIDs"]) # sample,-s.
SECTIONS = ("CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez")
SUBSECTIONS = CFG[SECTIONS].subsections
CATEGORIES += CFG[SECTIONS].sections
USER_SCRIPT_CATEGORIES = CFG["UserScript"]["user_script_categories"] # NONE
__INITIALIZED__ = True
return True

View file

@ -1,47 +1,42 @@
import logging
import urllib import urllib
import socket
import time import time
import nzbtomedia
from lib import requests from lib import requests
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaUtil import convert_to_ascii from nzbtomedia.nzbToMediaUtil import convert_to_ascii
from nzbtomedia import logger
Logger = logging.getLogger()
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: if dirName is None:
Logger.error("No directory was given!") logger.error("No directory was given!")
return 1 # failure return 1 # failure
# auto-detect correct section # auto-detect correct section
section = config().findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
Logger.error( logger.error(
"MAIN: 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
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. logger.postprocess("Loading config from %s", nzbtomedia.CONFIG_FILE)
Logger.info("Loading config from %s", config.CONFIG_FILE) host = nzbtomedia.CFG[section][inputCategory]["host"]
port = nzbtomedia.CFG[section][inputCategory]["port"]
host = config()[section][inputCategory]["host"] username = nzbtomedia.CFG[section][inputCategory]["username"]
port = config()[section][inputCategory]["port"] password = nzbtomedia.CFG[section][inputCategory]["password"]
username = config()[section][inputCategory]["username"]
password = config()[section][inputCategory]["password"]
try: try:
ssl = int(config()[section][inputCategory]["ssl"]) ssl = int(nzbtomedia.CFG[section][inputCategory]["ssl"])
except: except:
ssl = 0 ssl = 0
try: try:
web_root = config()[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except: except:
web_root = "" web_root = ""
try: try:
watch_dir = config()[section][inputCategory]["watch_dir"] watch_dir = nzbtomedia.CFG[section][inputCategory]["watch_dir"]
except: except:
watch_dir = "" watch_dir = ""
params = {} params = {}
@ -62,16 +57,16 @@ class autoProcessComics:
url = protocol + host + ":" + port + web_root + "/post_process?" + urllib.urlencode(params) url = protocol + host + ":" + port + web_root + "/post_process?" + urllib.urlencode(params)
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = requests.get(url, auth=(username, password), stream=True) r = requests.get(url, auth=(username, password), stream=True)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
return 1 # failure return 1 # failure
for line in r.iter_lines(): for line in r.iter_lines():
if line: Logger.info("%s", line) if line: logger.postprocess("%s", line)
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

@ -1,42 +1,37 @@
import json import json
import logging import nzbtomedia
import socket
from lib import requests from lib import requests
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaUtil import convert_to_ascii from nzbtomedia.nzbToMediaUtil import convert_to_ascii
from nzbtomedia import logger
Logger = logging.getLogger()
class autoProcessGames: class autoProcessGames:
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: if dirName is None:
Logger.error("No directory was given!") logger.error("No directory was given!")
return 1 # failure return 1 # failure
# auto-detect correct section # auto-detect correct section
section = config().findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
Logger.error( logger.error(
"MAIN: 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
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. logger.postprocess("Loading config from %s", nzbtomedia.CONFIG_FILE)
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(status) status = int(status)
host = config()[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"] port = nzbtomedia.CFG[section][inputCategory]["port"]
apikey = config()[section][inputCategory]["apikey"] apikey = nzbtomedia.CFG[section][inputCategory]["apikey"]
try: try:
ssl = int(config()[section][inputCategory]["ssl"]) ssl = int(nzbtomedia.CFG[section][inputCategory]["ssl"])
except: except:
ssl = 0 ssl = 0
try: try:
web_root = config()[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except: except:
web_root = "" web_root = ""
@ -57,23 +52,23 @@ class autoProcessGames:
url = baseURL + "UPDATEREQUESTEDSTATUS&db_id=" + gamezID + "&status=" + downloadStatus url = baseURL + "UPDATEREQUESTEDSTATUS&db_id=" + gamezID + "&status=" + downloadStatus
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = requests.get(url, stream=True) r = requests.get(url, stream=True)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
return 1 # failure return 1 # failure
result = {} result = {}
for line in r.iter_lines(): for line in r.iter_lines():
if line: if line:
Logger.info("%s", line) logger.postprocess("%s", line)
result.update(json.load(line)) result.update(json.load(line))
if result['success']: if result['success']:
Logger.info("Status for %s has been set to %s in Gamez", gamezID, downloadStatus) logger.postprocess("Status for %s has been set to %s in Gamez", gamezID, downloadStatus)
return 0 # Success return 0 # Success
else: else:
Logger.error("Status for %s has NOT been updated in Gamez", gamezID) logger.error("Status for %s has NOT been updated in Gamez", gamezID)
return 1 # failure return 1 # failure

View file

@ -1,17 +1,14 @@
import time import time
import datetime import datetime
import logging
import socket import socket
import urllib import urllib
import shutil import shutil
import json import nzbtomedia
from lib import requests from lib import requests
from nzbtomedia.Transcoder import Transcoder from nzbtomedia.Transcoder import Transcoder
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions
from nzbtomedia.nzbToMediaUtil import getDirectorySize, convert_to_ascii from nzbtomedia.nzbToMediaUtil import getDirectorySize, convert_to_ascii
from nzbtomedia import logger
Logger = logging.getLogger()
class autoProcessMovie: class autoProcessMovie:
@ -24,7 +21,7 @@ class autoProcessMovie:
imdbid = nzbName[a:b] imdbid = nzbName[a:b]
if imdbid: if imdbid:
Logger.info("Found movie id %s in name", imdbid) logger.postprocess("Found movie id %s in name", imdbid)
return imdbid return imdbid
a = dirName.find('.cp(') + 4 #search for .cptt( in dirname a = dirName.find('.cp(') + 4 #search for .cptt( in dirname
@ -33,14 +30,14 @@ class autoProcessMovie:
imdbid = dirName[a:b] imdbid = dirName[a:b]
if imdbid: if imdbid:
Logger.info("Found movie id %s in directory", imdbid) logger.postprocess("Found movie id %s in directory", imdbid)
return imdbid return imdbid
else: else:
Logger.debug("Could not find an imdb id in directory or name") logger.debug("Could not find an imdb id in directory or name")
return "" return ""
def get_movie_info(self, baseURL, imdbid, download_id): def get_movie_postprocess(self, baseURL, imdbid, download_id):
movie_id = None movie_id = None
movie_status = None movie_status = None
@ -57,12 +54,12 @@ class autoProcessMovie:
while True: while True:
url = baseURL + "media.list/?status=active&release_status=snatched&limit_offset=50," + str(offset) url = baseURL + "media.list/?status=active&release_status=snatched&limit_offset=50," + str(offset)
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = requests.get(url) r = requests.get(url)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
break break
library2 = [] library2 = []
@ -77,7 +74,7 @@ class autoProcessMovie:
release2 = [item["releases"] for item in result["movies"]] release2 = [item["releases"] for item in result["movies"]]
moviestatus2 = [item["status"] for item in result["movies"]] moviestatus2 = [item["status"] for item in result["movies"]]
except Exception, e: except Exception, e:
Logger.exception("Unable to parse json data for movies") logger.error("Unable to parse json data for movies")
break break
movieid.extend(movieid2) movieid.extend(movieid2)
@ -99,7 +96,7 @@ class autoProcessMovie:
if imdbid and library[index] == imdbid: if imdbid and library[index] == imdbid:
movie_id = str(movieid[index]) movie_id = str(movieid[index])
movie_status = str(moviestatus[index]) movie_status = str(moviestatus[index])
Logger.info("Found movie id %s with status %s in CPS database for movie %s", movie_id, movie_status, imdbid) logger.postprocess("Found movie id %s with status %s in CPS database for movie %s", movie_id, movie_status, imdbid)
if not download_id and len(releaselist) == 1: if not download_id and len(releaselist) == 1:
download_id = releaselist[0]["download_info"]["id"] download_id = releaselist[0]["download_info"]["id"]
@ -107,19 +104,19 @@ class autoProcessMovie:
movie_id = str(movieid[index]) movie_id = str(movieid[index])
movie_status = str(moviestatus[index]) movie_status = str(moviestatus[index])
imdbid = str(library[index]) imdbid = str(library[index])
Logger.info("Found movie id %s and imdb %s with status %s in CPS database via download_id %s", movie_id, imdbid, movie_status, download_id) logger.postprocess("Found movie id %s and imdb %s with status %s in CPS database via download_id %s", movie_id, imdbid, movie_status, download_id)
else: else:
continue continue
if len(releaselist) == 1: if len(releaselist) == 1:
release_status = releaselist[0]["status"] release_status = releaselist[0]["status"]
Logger.debug("Found a single release with download_id: %s. Release status is: %s", download_id, release_status) logger.debug("Found a single release with download_id: %s. Release status is: %s", download_id, release_status)
break break
if not movie_id: if not movie_id:
Logger.exception("Could not parse database results to determine imdbid or movie id") logger.error("Could not parse database results to determine imdbid or movie id")
return movie_id, imdbid, download_id, movie_status, release_status return movie_id, imdbid, download_id, movie_status, release_status
@ -130,22 +127,22 @@ class autoProcessMovie:
if not movie_id: if not movie_id:
return movie_status, release_status return movie_status, release_status
Logger.debug("Looking for status of movie: %s", movie_id) logger.debug("Looking for status of movie: %s", movie_id)
url = baseURL + "media.get/?id=" + str(movie_id) url = baseURL + "media.get/?id=" + str(movie_id)
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = requests.get(url) r = requests.get(url)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
return None, None return None, None
try: try:
result = r.json() result = r.json()
movie_status = str(result["media"]["status"]) movie_status = str(result["media"]["status"])
Logger.debug("This movie is marked as status %s in CouchPotatoServer", movie_status) logger.debug("This movie is marked as status %s in CouchPotatoServer", movie_status)
except: except:
Logger.exception("Could not find a status for this movie") logger.error("Could not find a status for this movie")
try: try:
if len(result["media"]["releases"]) == 1 and result["media"]["releases"][0]["status"] == "done": if len(result["media"]["releases"]) == 1 and result["media"]["releases"][0]["status"] == "done":
@ -154,55 +151,54 @@ class autoProcessMovie:
release_status_list = [item["status"] for item in result["media"]["releases"] if "download_info" in item and item["download_info"]["id"].lower() == download_id.lower()] release_status_list = [item["status"] for item in result["media"]["releases"] if "download_info" in item and item["download_info"]["id"].lower() == download_id.lower()]
if len(release_status_list) == 1: if len(release_status_list) == 1:
release_status = release_status_list[0] release_status = release_status_list[0]
Logger.debug("This release is marked as status %s in CouchPotatoServer", release_status) logger.debug("This release is marked as status %s in CouchPotatoServer", release_status)
except: # index out of range/doesn't exist? except: # index out of range/doesn't exist?
Logger.exception("Could not find a status for this release") logger.error("Could not find a status for this release")
return movie_status, release_status return movie_status, release_status
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: if dirName is None:
Logger.error("No directory was given!") logger.error("No directory was given!")
return 1 # failure return 1 # failure
# auto-detect correct section # auto-detect correct section
section = config().findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
Logger.error( logger.error(
"MAIN: 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
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. logger.postprocess("Loading config from %s", nzbtomedia.CONFIG_FILE)
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(status) status = int(status)
host = config()[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"] port = nzbtomedia.CFG[section][inputCategory]["port"]
apikey = config()[section][inputCategory]["apikey"] apikey = nzbtomedia.CFG[section][inputCategory]["apikey"]
delay = float(config()[section][inputCategory]["delay"]) delay = float(nzbtomedia.CFG[section][inputCategory]["delay"])
method = config()[section][inputCategory]["method"] method = nzbtomedia.CFG[section][inputCategory]["method"]
delete_failed = int(config()[section][inputCategory]["delete_failed"]) delete_failed = int(nzbtomedia.CFG[section][inputCategory]["delete_failed"])
wait_for = int(config()[section][inputCategory]["wait_for"]) wait_for = int(nzbtomedia.CFG[section][inputCategory]["wait_for"])
try: try:
TimePerGiB = int(config()[section][inputCategory]["TimePerGiB"]) TimePerGiB = int(nzbtomedia.CFG[section][inputCategory]["TimePerGiB"])
except: except:
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute. TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
try: try:
ssl = int(config()[section][inputCategory]["ssl"]) ssl = int(nzbtomedia.CFG[section][inputCategory]["ssl"])
except: except:
ssl = 0 ssl = 0
try: try:
web_root = config()[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except: except:
web_root = "" web_root = ""
try: try:
transcode = int(config()["Transcoder"]["transcode"]) transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"])
except: except:
transcode = 0 transcode = 0
try: try:
remoteCPS = int(config()[section][inputCategory]["remoteCPS"]) remoteCPS = int(nzbtomedia.CFG[section][inputCategory]["remoteCPS"])
except: except:
remoteCPS = 0 remoteCPS = 0
@ -221,7 +217,7 @@ class autoProcessMovie:
baseURL = protocol + host + ":" + port + web_root + "/api/" + apikey + "/" baseURL = protocol + host + ":" + port + web_root + "/api/" + apikey + "/"
movie_id, imdbid, download_id, initial_status, initial_release_status = self.get_movie_info(baseURL, imdbid, download_id) # get the CPS database movie id for this movie. movie_id, imdbid, download_id, initial_status, initial_release_status = self.get_movie_postprocess(baseURL, imdbid, download_id) # get the CPS database movie id for this movie.
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)
@ -230,9 +226,9 @@ class autoProcessMovie:
if transcode == 1: if 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)
else: else:
Logger.warning("Transcoding failed for files in %s", dirName) logger.warning("Transcoding failed for files in %s", dirName)
if method == "manage": if method == "manage":
command = "manage.update" command = "manage.update"
@ -251,55 +247,55 @@ class autoProcessMovie:
url = baseURL + command url = baseURL + command
Logger.info("Waiting for %s seconds to allow CPS to process newly extracted files", str(delay)) logger.postprocess("Waiting for %s seconds to allow CPS to process newly extracted files", str(delay))
time.sleep(delay) time.sleep(delay)
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = requests.get(url) r = requests.get(url)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
return 1 # failure return 1 # failure
result = r.json() result = r.json()
Logger.info("CouchPotatoServer returned %s", result) logger.postprocess("CouchPotatoServer returned %s", result)
if result['success']: if result['success']:
Logger.info("%s scan started on CouchPotatoServer for %s", method, nzbName) logger.postprocess("%s scan started on CouchPotatoServer for %s", method, nzbName)
else: else:
Logger.error("%s scan has NOT started on CouchPotatoServer for %s. Exiting", method, nzbName) logger.error("%s scan has NOT started on CouchPotatoServer for %s. Exiting", method, nzbName)
return 1 # failure return 1 # failure
else: else:
Logger.info("Download of %s has failed.", nzbName) logger.postprocess("Download of %s has failed.", nzbName)
Logger.info("Trying to re-cue the next highest ranked release") logger.postprocess("Trying to re-cue the next highest ranked release")
if not movie_id: if not movie_id:
Logger.warning("Cound not find a movie in the database for release %s", nzbName) logger.warning("Cound not find a movie in the database for release %s", nzbName)
Logger.warning("Please manually ignore this release and refresh the wanted movie") logger.warning("Please manually ignore this release and refresh the wanted movie")
Logger.error("Exiting autoProcessMovie script") logger.error("Exiting autoProcessMovie script")
return 1 # failure return 1 # failure
url = baseURL + "movie.searcher.try_next/?media_id=" + movie_id url = baseURL + "movie.searcher.try_next/?media_id=" + movie_id
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = requests.get(url, stream=True) r = requests.get(url, stream=True)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
return 1 # failure return 1 # failure
for line in r.iter_lines(): for line in r.iter_lines():
if line: Logger.info("%s", line) if line: logger.postprocess("%s", line)
Logger.info("Movie %s set to try the next best release on CouchPotatoServer", movie_id) logger.postprocess("Movie %s set to try the next best release on CouchPotatoServer", movie_id)
if delete_failed and not dirName in ['sys.argv[0]','/','']: if delete_failed and not dirName in ['sys.argv[0]','/','']:
Logger.info("Deleting failed files and folder %s", dirName) logger.postprocess("Deleting failed files and folder %s", dirName)
try: try:
shutil.rmtree(dirName) shutil.rmtree(dirName)
except: except:
Logger.exception("Unable to delete folder %s", dirName) logger.error("Unable to delete folder %s", dirName)
return 0 # success return 0 # success
if clientAgent == "manual": if clientAgent == "manual":
@ -311,21 +307,19 @@ class autoProcessMovie:
return 0 # success return 0 # success
# 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.
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
release_status = None release_status = None
start = datetime.datetime.now() # set time for timeout start = datetime.datetime.now() # set time for timeout
pause_for = int(wait_for) * 10 # keep this so we only ever have 6 complete loops. This may not be necessary now? pause_for = int(wait_for) * 10 # keep this so we only ever have 6 complete loops. This may not be necessary now?
while (datetime.datetime.now() - start) < datetime.timedelta(minutes=wait_for): # only wait 2 (default) minutes, then return. while (datetime.datetime.now() - start) < datetime.timedelta(minutes=wait_for): # only wait 2 (default) minutes, then return.
movie_status, release_status = self.get_status(baseURL, movie_id, download_id) # get the current status fo this movie. movie_status, release_status = self.get_status(baseURL, movie_id, download_id) # get the current status fo this movie.
if movie_status and initial_status and movie_status != initial_status: # Something has changed. CPS must have processed this movie. if movie_status and initial_status and movie_status != initial_status: # Something has changed. CPS must have processed this movie.
Logger.info("SUCCESS: This movie is now marked as status %s in CouchPotatoServer", movie_status) logger.postprocess("SUCCESS: This movie is now marked as status %s in CouchPotatoServer", movie_status)
return 0 # success return 0 # success
time.sleep(pause_for) # Just stop this looping infinitely and hogging resources for 2 minutes ;) time.sleep(pause_for) # Just stop this looping infinitely and hogging resources for 2 minutes ;)
else: else:
if release_status and initial_release_status and release_status != initial_release_status: # Something has changed. CPS must have processed this movie. if release_status and initial_release_status and release_status != initial_release_status: # Something has changed. CPS must have processed this movie.
Logger.info("SUCCESS: This release is now marked as status %s in CouchPotatoServer", release_status) logger.postprocess("SUCCESS: This release is now marked as status %s in CouchPotatoServer", release_status)
return 0 # success return 0 # success
else: # The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resule seeding now. else: # 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("The movie does not appear to have changed status after %s minutes. Please check CouchPotato Logs", wait_for)
return 1 # failure return 1 # failure

View file

@ -1,48 +1,44 @@
import time import time
import datetime import datetime
import logging
import socket import socket
import urllib import urllib
import nzbtomedia
from lib import requests from lib import requests
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, getDirectorySize from nzbtomedia.nzbToMediaUtil import convert_to_ascii, getDirectorySize
from nzbtomedia import logger
Logger = logging.getLogger()
class autoProcessMusic: class autoProcessMusic:
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: if dirName is None:
Logger.error("No directory was given!") logger.error("No directory was given!")
return 1 # failure return 1 # failure
# auto-detect correct section # auto-detect correct section
section = config().findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if len(section) == 0: if len(section) == 0:
Logger.error( logger.error(
"MAIN: 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
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. logger.postprocess("Loading config from %s", nzbtomedia.CONFIG_FILE)
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(status) status = int(status)
host = config()[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"] port = nzbtomedia.CFG[section][inputCategory]["port"]
apikey = config()[section][inputCategory]["apikey"] apikey = nzbtomedia.CFG[section][inputCategory]["apikey"]
delay = float(config()[section][inputCategory]["delay"]) delay = float(nzbtomedia.CFG[section][inputCategory]["delay"])
try: try:
ssl = int(config()[section][inputCategory]["ssl"]) ssl = int(nzbtomedia.CFG[section][inputCategory]["ssl"])
except: except:
ssl = 0 ssl = 0
try: try:
web_root = config()[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except: except:
web_root = "" web_root = ""
try: try:
TimePerGiB = int(config()[section][inputCategory]["TimePerGiB"]) TimePerGiB = int(nzbtomedia.CFG[section][inputCategory]["TimePerGiB"])
except: except:
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute. TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
@ -72,27 +68,27 @@ class autoProcessMusic:
url = baseURL + urllib.urlencode(params) url = baseURL + urllib.urlencode(params)
Logger.info("Waiting for %s seconds to allow HeadPhones to process newly extracted files", str(delay)) logger.postprocess("Waiting for %s seconds to allow HeadPhones to process newly extracted files", str(delay))
time.sleep(delay) time.sleep(delay)
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = requests.get(url) r = requests.get(url)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
return 1 # failure return 1 # failure
Logger.info("HeadPhones returned %s", r.text) logger.postprocess("HeadPhones returned %s", r.text)
if r.text == "OK": if r.text == "OK":
Logger.info("Post-processing started on HeadPhones for %s in folder %s", nzbName, dirName) logger.postprocess("Post-processing started on HeadPhones for %s in folder %s", nzbName, dirName)
else: else:
Logger.error("Post-proecssing has NOT started on HeadPhones for %s in folder %s. Exiting", nzbName, dirName) logger.error("Post-proecssing has NOT started on HeadPhones for %s in folder %s. Exiting", nzbName, dirName)
return 1 # failure return 1 # failure
else: else:
Logger.info("The download failed. Nothing to process") logger.postprocess("The download failed. Nothing to process")
return 0 # Success (as far as this script is concerned) return 0 # Success (as far as this script is concerned)
if clientAgent == "manual": if clientAgent == "manual":
@ -104,7 +100,7 @@ class autoProcessMusic:
while (datetime.datetime.now() - start) < datetime.timedelta(minutes=1): # only wait 2 minutes, then return to TorrentToMedia while (datetime.datetime.now() - start) < datetime.timedelta(minutes=1): # only wait 2 minutes, then return to TorrentToMedia
time.sleep(20) # Just stop this looping infinitely and hogging resources for 2 minutes ;) time.sleep(20) # Just stop this looping infinitely and hogging resources for 2 minutes ;)
else: # The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resume seeding now. else: # The status hasn't changed. we have waited 2 minutes which is more than enough. uTorrent can resume seeding now.
Logger.info("This album should have completed processing. Please check HeadPhones Logs") logger.postprocess("This album should have completed processing. Please check HeadPhones Logs")
# Logger.warning("The album does not appear to have changed status after 2 minutes. Please check HeadPhones Logs") # logger.warning("The album does not appear to have changed status after 2 minutes. Please check HeadPhones Logs")
# return 1 # failure # return 1 # failure
return 0 # success for now. return 0 # success for now.

View file

@ -1,99 +1,95 @@
import copy import copy
import json import json
import logging
import os import os
import socket import socket
import urllib import urllib
import time import time
import nzbtomedia
from lib import requests from lib import requests
from nzbtomedia.Transcoder import Transcoder from nzbtomedia.Transcoder import Transcoder
from nzbtomedia.nzbToMediaAutoFork import autoFork from nzbtomedia.nzbToMediaAutoFork import autoFork
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, is_sample, flatten, getDirectorySize, delete from nzbtomedia.nzbToMediaUtil import convert_to_ascii, is_sample, flatten, getDirectorySize, delete
from nzbtomedia import logger
Logger = logging.getLogger()
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: if dirName is None:
Logger.error("No directory was given!") logger.error("No directory was given!")
return 1 # failure return 1 # failure
# auto-detect correct section # auto-detect correct section
section = config().findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
Logger.error( logger.error(
"MAIN: 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
# auto-detect correct fork # auto-detect correct fork
fork, fork_params = autoFork(inputCategory) fork, fork_params = autoFork(inputCategory)
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout. logger.postprocess("Loading config from %s", nzbtomedia.CONFIG_FILE)
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(failed) status = int(failed)
host = config()[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"] port = nzbtomedia.CFG[section][inputCategory]["port"]
username = config()[section][inputCategory]["username"] username = nzbtomedia.CFG[section][inputCategory]["username"]
password = config()[section][inputCategory]["password"] password = nzbtomedia.CFG[section][inputCategory]["password"]
try: try:
apikey = config()[section][inputCategory]["apikey"] apikey = nzbtomedia.CFG[section][inputCategory]["apikey"]
except: except:
apikey = "" apikey = ""
try: try:
ssl = int(config()[section][inputCategory]["ssl"]) ssl = int(nzbtomedia.CFG[section][inputCategory]["ssl"])
except: except:
ssl = 0 ssl = 0
try: try:
web_root = config()[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except: except:
web_root = "" web_root = ""
try: try:
watch_dir = config()[section][inputCategory]["watch_dir"] watch_dir = nzbtomedia.CFG[section][inputCategory]["watch_dir"]
except: except:
watch_dir = "" watch_dir = ""
try: try:
transcode = int(config()["Transcoder"]["transcode"]) transcode = int(nzbtomedia.CFG["Transcoder"]["transcode"])
except: except:
transcode = 0 transcode = 0
try: try:
delete_failed = int(config()[section][inputCategory]["delete_failed"]) delete_failed = int(nzbtomedia.CFG[section][inputCategory]["delete_failed"])
except: except:
delete_failed = 0 delete_failed = 0
try: try:
delay = float(config()[section][inputCategory]["delay"]) delay = float(nzbtomedia.CFG[section][inputCategory]["delay"])
except: except:
delay = 0 delay = 0
try: try:
TimePerGiB = int(config()[section][inputCategory]["TimePerGiB"]) TimePerGiB = int(nzbtomedia.CFG[section][inputCategory]["TimePerGiB"])
except: except:
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute. TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
try: try:
SampleIDs = (config()["Extensions"]["SampleIDs"]) SampleIDs = (nzbtomedia.CFG["Extensions"]["SampleIDs"])
except: except:
SampleIDs = ['sample','-s.'] SampleIDs = ['sample','-s.']
try: try:
nzbExtractionBy = config()[section][inputCategory]["nzbExtractionBy"] nzbExtractionBy = nzbtomedia.CFG[section][inputCategory]["nzbExtractionBy"]
except: except:
nzbExtractionBy = "Downloader" nzbExtractionBy = "Downloader"
try: try:
process_method = config()[section][inputCategory]["process_method"] process_method = nzbtomedia.CFG[section][inputCategory]["process_method"]
except: except:
process_method = None process_method = None
try: try:
Torrent_NoLink = int(config()[section][inputCategory]["Torrent_NoLink"]) Torrent_NoLink = int(nzbtomedia.CFG[section][inputCategory]["Torrent_NoLink"])
except: except:
Torrent_NoLink = 0 Torrent_NoLink = 0
mediaContainer = (config()["Extensions"]["mediaExtensions"]) mediaContainer = (nzbtomedia.CFG["Extensions"]["mediaExtensions"])
minSampleSize = int(config()["Extensions"]["minSampleSize"]) minSampleSize = int(nzbtomedia.CFG["Extensions"]["minSampleSize"])
if not os.path.isdir(dirName) and os.path.isfile(dirName): # If the input directory is a file, assume single file download and split dir/name. if not os.path.isdir(dirName) and os.path.isfile(dirName): # If the input directory is a file, assume single file download and split dir/name.
dirName = os.path.split(os.path.normpath(dirName))[0] dirName = os.path.split(os.path.normpath(dirName))[0]
@ -105,7 +101,7 @@ class autoProcessTV:
if os.path.isdir(SpecificPath): if os.path.isdir(SpecificPath):
dirName = SpecificPath dirName = SpecificPath
if fork not in config.SICKBEARD_TORRENT or (clientAgent in ['nzbget','sabnzbd'] and nzbExtractionBy != "Destination"): if fork not in nzbtomedia.SICKBEARD_TORRENT or (clientAgent in ['nzbget','sabnzbd'] and nzbExtractionBy != "Destination"):
if nzbName: if nzbName:
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)
@ -118,17 +114,17 @@ class autoProcessTV:
fileExtension = os.path.splitext(file)[1] fileExtension = os.path.splitext(file)[1]
if fileExtension in mediaContainer: # If the file is a video file if fileExtension in mediaContainer: # If the file is a video file
if is_sample(filePath, nzbName, minSampleSize, SampleIDs): if is_sample(filePath, nzbName, minSampleSize, SampleIDs):
Logger.debug("Removing sample file: %s", filePath) logger.debug("Removing sample file: %s", filePath)
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)
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)
status = int(1) status = int(1)
failed = True failed = True
@ -150,7 +146,7 @@ class autoProcessTV:
fork_params[param] = dirName fork_params[param] = dirName
if param == "process_method": if param == "process_method":
if fork in config.SICKBEARD_TORRENT and Torrent_NoLink == 1 and not clientAgent in ['nzbget','sabnzbd']: #use default SickBeard settings here. if fork in nzbtomedia.SICKBEARD_TORRENT and Torrent_NoLink == 1 and not clientAgent in ['nzbget','sabnzbd']: #use default SickBeard settings here.
del fork_params[param] del fork_params[param]
if process_method: if process_method:
fork_params[param] = process_method fork_params[param] = process_method
@ -161,22 +157,22 @@ 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.info("The download succeeded. Sending process request to %s", section) logger.postprocess("The download succeeded. Sending process request to %s", section)
elif fork in config.SICKBEARD_FAILED: elif fork in nzbtomedia.SICKBEARD_FAILED:
Logger.info("The download failed. Sending 'failed' process request to SickBeard's %s branch", fork) logger.postprocess("The download failed. Sending 'failed' process request to SickBeard's %s branch", fork)
else: else:
Logger.info("The download failed. SickBeard's %s branch does not handle failed downloads. Nothing to process", fork) logger.postprocess("The download failed. SickBeard's %s branch does not handle failed downloads. Nothing to process", fork)
if delete_failed and os.path.isdir(dirName) and not dirName in ['sys.argv[0]','/','']: if delete_failed and os.path.isdir(dirName) and not dirName in ['sys.argv[0]','/','']:
Logger.info("Deleting directory: %s", dirName) logger.postprocess("Deleting directory: %s", dirName)
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 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("Transcoding succeeded for files in %s", dirName)
else: else:
Logger.warning("Transcoding failed for files in %s", dirName) logger.warning("Transcoding failed for files in %s", dirName)
if ssl: if ssl:
protocol = "https://" protocol = "https://"
@ -191,13 +187,14 @@ class autoProcessTV:
url = protocol + host + ":" + port + web_root + "/api/command" url = protocol + host + ":" + port + web_root + "/api/command"
if clientAgent == "manual":delay = 0 if clientAgent == "manual":delay = 0
Logger.info("Waiting for %s seconds to allow %s to process newly extracted files", str(delay), section) logger.postprocess("Waiting for %s seconds to allow %s to process newly extracted files", str(delay), section)
time.sleep(delay) time.sleep(delay)
Logger.debug("Opening URL: %s", url) logger.debug("Opening URL: %s", url)
try: try:
r = None
if section == "SickBeard": if section == "SickBeard":
r = requests.get(url, auth=(username, password), stream=True) r = requests.get(url, auth=(username, password), stream=True)
elif section == "NzbDrone": elif section == "NzbDrone":
@ -205,11 +202,11 @@ class autoProcessTV:
headers = {"X-Api-Key": apikey} headers = {"X-Api-Key": apikey}
r = requests.get(url, data=data, headers=headers, stream=True) r = requests.get(url, data=data, headers=headers, stream=True)
except requests.ConnectionError: except requests.ConnectionError:
Logger.exception("Unable to open URL") logger.error("Unable to open URL")
return 1 # failure return 1 # failure
for line in r.iter_lines(): for line in r.iter_lines():
if line: Logger.info("%s", line) if line: logger.postprocess("%s", line)
if status != 0 and delete_failed and not dirName in ['sys.argv[0]','/','']: if status != 0 and delete_failed and not dirName in ['sys.argv[0]','/','']:
delete(dirName) delete(dirName)

View file

@ -37,7 +37,7 @@ def extract(filePath, outputDestination):
chplocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/chp.exe')) chplocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/chp.exe'))
sevenzipLocation = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), 'nzbtomedia/extractor/bin/' + platform + '/7z.exe')) 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
else: else:
if not os.path.exists(chplocation): if not os.path.exists(chplocation):
@ -72,7 +72,7 @@ def extract(filePath, outputDestination):
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.warn("EXTRACTOR: Cannot determine which tool to use when called from Transmission") Logger.warn("EXTRACTOR: Cannot determine which tool to use when called from Transmission")
@ -91,22 +91,22 @@ def extract(filePath, outputDestination):
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
create_destination(outputDestination) create_destination(outputDestination)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE) logger.info("Loading config from %s", nzbtomedia.CONFIG_FILE)
passwordsfile = config()["passwords"]["PassWordFile"] passwordsfile = nzbtomedia.CFG["passwords"]["PassWordFile"]
if passwordsfile != "" and os.path.isfile(os.path.normpath(passwordsfile)): if passwordsfile != "" and os.path.isfile(os.path.normpath(passwordsfile)):
passwords = [line.strip() for line in open(os.path.normpath(passwordsfile))] passwords = [line.strip() for line in open(os.path.normpath(passwordsfile))]
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
@ -116,9 +116,9 @@ def extract(filePath, outputDestination):
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 (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) 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.
@ -130,14 +130,14 @@ def extract(filePath, outputDestination):
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 (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) 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.exception("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

62
nzbtomedia/gh_api.py Normal file
View file

@ -0,0 +1,62 @@
import json
from lib import requests
class GitHub(object):
"""
Simple api wrapper for the Github API v3.
"""
def __init__(self, github_repo_user, github_repo, branch='master'):
self.github_repo_user = github_repo_user
self.github_repo = github_repo
self.branch = branch
def _access_API(self, path, params=None):
"""
Access the API at the path given and with the optional params given.
"""
url = 'https://api.github.com/' + '/'.join(path)
if params and type(params) is dict:
url += '?' + '&'.join([str(x) + '=' + str(params[x]) for x in params.keys()])
data = requests.get(url)
if data.ok:
json_data = data.json()
return json_data
else:
return []
def commits(self):
"""
Uses the API to get a list of the 100 most recent commits from the specified user/repo/branch, starting from HEAD.
user: The github username of the person whose repo you're querying
repo: The repo name to query
branch: Optional, the branch name to show commits from
Returns a deserialized json object containing the commit info. See http://developer.github.com/v3/repos/commits/
"""
access_API = self._access_API(['repos', self.github_repo_user, self.github_repo, 'commits'],
params={'per_page': 100, 'sha': self.branch})
return access_API
def compare(self, base, head, per_page=1):
"""
Uses the API to get a list of compares between base and head.
user: The github username of the person whose repo you're querying
repo: The repo name to query
base: Start compare from branch
head: Current commit sha or branch name to compare
per_page: number of items per page
Returns a deserialized json object containing the compare info. See http://developer.github.com/v3/repos/commits/
"""
access_API = self._access_API(
['repos', self.github_repo_user, self.github_repo, 'compare', base + '...' + head],
params={'per_page': per_page})
return access_API

245
nzbtomedia/logger.py Normal file
View file

@ -0,0 +1,245 @@
from __future__ import with_statement
import os
import sys
import threading
import logging
import nzbtomedia
# number of log files to keep
NUM_LOGS = 3
# log size in bytes
LOG_SIZE = 10000000 # 10 megs
ERROR = logging.ERROR
WARNING = logging.WARNING
MESSAGE = logging.INFO
DEBUG = logging.DEBUG
POSTPROCESS = 5
reverseNames = {u'ERROR': ERROR,
u'WARNING': WARNING,
u'INFO': MESSAGE,
u'DEBUG': DEBUG,
u'POSTPROCESS': POSTPROCESS}
class NTMRotatingLogHandler(object):
def __init__(self, log_file, num_files, num_bytes):
self.num_files = num_files
self.num_bytes = num_bytes
self.log_file = log_file
self.log_file_path = log_file
self.cur_handler = None
self.writes_since_check = 0
self.console_logging = True
self.log_lock = threading.Lock()
def close_log(self, handler=None):
if not handler:
handler = self.cur_handler
if handler:
ntm_logger = logging.getLogger('nzbtomedia')
pp_logger = logging.getLogger('postprocess')
ntm_logger.removeHandler(handler)
pp_logger.removeHandler(handler)
handler.flush()
handler.close()
def initLogging(self, consoleLogging=True):
if consoleLogging:
self.console_logging = consoleLogging
old_handler = None
# get old handler in case we want to close it
if self.cur_handler:
old_handler = self.cur_handler
else:
#Add a new logging level POSTPROCESS
logging.addLevelName(5, 'POSTPROCESS')
# only start consoleLogging on first initialize
if self.console_logging:
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
# set a format which is simpler for console use
console.setFormatter(DispatchingFormatter(
{'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)s:: %(message)s', '%H:%M:%S'),
'postprocess': logging.Formatter('%(asctime)s %(levelname)s:: %(message)s', '%H:%M:%S')
},
logging.Formatter('%(message)s'), ))
# add the handler to the root logger
logging.getLogger('nzbtomedia').addHandler(console)
logging.getLogger('postprocess').addHandler(console)
self.log_file_path = os.path.join(nzbtomedia.LOG_DIR, self.log_file)
self.cur_handler = self._config_handler()
logging.getLogger('nzbtomedia').addHandler(self.cur_handler)
logging.getLogger('postprocess').addHandler(self.cur_handler)
logging.getLogger('nzbtomedia').setLevel(logging.INFO)
logging.getLogger('postprocess').setLevel(POSTPROCESS)
# already logging in new log folder, close the old handler
if old_handler:
self.close_log(old_handler)
def _config_handler(self):
"""
Configure a file handler to log at file_name and return it.
"""
file_handler = logging.FileHandler(self.log_file_path, encoding='utf-8')
file_handler.setFormatter(DispatchingFormatter(
{'nzbtomedia': logging.Formatter('%(asctime)s %(levelname)-8s:: %(message)s', '%Y-%m-%d %H:%M:%S'),
'postprocess': logging.Formatter('%(asctime)s %(levelname)-8s:: %(message)s', '%Y-%m-%d %H:%M:%S')
},
logging.Formatter('%(message)s'), ))
return file_handler
def _log_file_name(self, i):
"""
Returns a numbered log file name depending on i. If i==0 it just uses logName, if not it appends
it to the extension (blah.log.3 for i == 3)
i: Log number to ues
"""
return self.log_file_path + ('.' + str(i) if i else '')
def _num_logs(self):
"""
Scans the log folder and figures out how many log files there are already on disk
Returns: The number of the last used file (eg. mylog.log.3 would return 3). If there are no logs it returns -1
"""
cur_log = 0
while os.path.isfile(self._log_file_name(cur_log)):
cur_log += 1
return cur_log - 1
def _rotate_logs(self):
ntm_logger = logging.getLogger('nzbtomedia')
pp_logger = logging.getLogger('postprocess')
# delete the old handler
if self.cur_handler:
self.close_log()
# rename or delete all the old log files
for i in range(self._num_logs(), -1, -1):
cur_file_name = self._log_file_name(i)
try:
if i >= NUM_LOGS:
os.remove(cur_file_name)
else:
os.rename(cur_file_name, self._log_file_name(i + 1))
except OSError:
pass
# the new log handler will always be on the un-numbered .log file
new_file_handler = self._config_handler()
self.cur_handler = new_file_handler
ntm_logger.addHandler(new_file_handler)
pp_logger.addHandler(new_file_handler)
def log(self, toLog, logLevel=MESSAGE):
with self.log_lock:
# check the size and see if we need to rotate
if self.writes_since_check >= 10:
if os.path.isfile(self.log_file_path) and os.path.getsize(self.log_file_path) >= LOG_SIZE:
self._rotate_logs()
self.writes_since_check = 0
else:
self.writes_since_check += 1
message = u"" + toLog
out_line = message
ntm_logger = logging.getLogger('nzbtomedia')
pp_logger = logging.getLogger('postprocess')
setattr(pp_logger, 'postprocess', lambda *args: pp_logger.log(POSTPROCESS, *args))
try:
if logLevel == DEBUG:
ntm_logger.debug(out_line)
elif logLevel == MESSAGE:
ntm_logger.info(out_line)
elif logLevel == WARNING:
ntm_logger.warning(out_line)
elif logLevel == ERROR:
ntm_logger.error(out_line)
elif logLevel == POSTPROCESS:
pp_logger.postprocess(out_line)
else:
ntm_logger.info(logLevel, out_line)
except ValueError:
pass
def log_error_and_exit(self, error_msg):
log(error_msg, ERROR)
if not self.console_logging:
sys.exit(error_msg.encode(nzbtomedia.SYS_ENCODING, 'xmlcharrefreplace'))
else:
sys.exit(1)
class DispatchingFormatter:
def __init__(self, formatters, default_formatter):
self._formatters = formatters
self._default_formatter = default_formatter
def format(self, record):
formatter = self._formatters.get(record.name, self._default_formatter)
return formatter.format(record)
ntm_log_instance = NTMRotatingLogHandler("nzbtomedia.log", NUM_LOGS, LOG_SIZE)
def log(toLog, logLevel=MESSAGE):
ntm_log_instance.log(toLog, logLevel)
def info(toLog, *args):
toLog = toLog % args
ntm_log_instance.log(toLog, MESSAGE)
def error(toLog, *args):
toLog = toLog % args
ntm_log_instance.log(toLog, ERROR)
def warning(toLog, *args):
toLog = toLog % args
ntm_log_instance.log(toLog, WARNING)
def debug(toLog, *args):
toLog = toLog % args
ntm_log_instance.log(toLog, DEBUG)
def log_error_and_exit(error_msg):
ntm_log_instance.log_error_and_exit(error_msg)
def postprocess(toLog, *args):
toLog = toLog % args
ntm_log_instance.log(toLog, POSTPROCESS)
def close():
ntm_log_instance.close_log()

View file

@ -1,8 +1,9 @@
import logging import logging
import urllib import urllib
from lib import requests import nzbtomedia
from lib import requests
from nzbToMediaConfig import config from nzbToMediaConfig import config
def autoFork(inputCategory): def autoFork(inputCategory):
@ -10,39 +11,39 @@ def autoFork(inputCategory):
Logger = logging.getLogger() Logger = logging.getLogger()
# auto-detect correct section # auto-detect correct section
section = config().findsection(inputCategory) section = nzbtomedia.CFG.findsection(inputCategory)
if not section: if not section:
Logger.error( logger.error(
"MAIN: 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
try: try:
host = config()[section][inputCategory]["host"] host = nzbtomedia.CFG[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"] port = nzbtomedia.CFG[section][inputCategory]["port"]
except: except:
host = None host = None
port = None port = None
try: try:
username = config()[section][inputCategory]["username"] username = nzbtomedia.CFG[section][inputCategory]["username"]
password = config()[section][inputCategory]["password"] password = nzbtomedia.CFG[section][inputCategory]["password"]
except: except:
username = None username = None
password = None password = None
try: try:
ssl = int(config()[section][inputCategory]["ssl"]) ssl = int(nzbtomedia.CFG[section][inputCategory]["ssl"])
except (config, ValueError): except (config, ValueError):
ssl = 0 ssl = 0
try: try:
web_root = config()[section][inputCategory]["web_root"] web_root = nzbtomedia.CFG[section][inputCategory]["web_root"]
except config: except config:
web_root = "" web_root = ""
try: try:
fork = config.FORKS.items()[config.FORKS.keys().index(config()[section][inputCategory]["fork"])] fork = nzbtomedia.FORKS.items()[nzbtomedia.FORKS.keys().index(nzbtomedia.CFG[section][inputCategory]["fork"])]
except: except:
fork = "auto" fork = "auto"
@ -53,8 +54,8 @@ 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 " + section + " fork")
for fork in sorted(config.FORKS.iteritems()): for fork in sorted(nzbtomedia.FORKS.iteritems()):
url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(fork[1]) url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(fork[1])
# attempting to auto-detect fork # attempting to auto-detect fork
@ -64,7 +65,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 " + section + ":" + inputCategory + " to perform auto-fork detection!")
break break
if r.ok: if r.ok:
@ -72,10 +73,10 @@ def autoFork(inputCategory):
break break
if detected: if detected:
Logger.info("" + section + ":" + inputCategory + " fork auto-detection successful ...") logger.info("" + section + ":" + inputCategory + " fork auto-detection successful ...")
else: else:
Logger.info("" + section + ":" + inputCategory + " fork auto-detection failed") logger.info("" + section + ":" + inputCategory + " fork auto-detection failed")
fork = config.FORKS.items()[config.FORKS.keys().index(config.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("" + section + ":" + inputCategory + " fork set to %s", fork[0])
return fork[0], fork[1] return fork[0], fork[1]

View file

@ -1,5 +1,6 @@
import os import os
import shutil import shutil
import nzbtomedia
import lib.configobj import lib.configobj
from itertools import chain from itertools import chain
@ -66,52 +67,9 @@ class Section(lib.configobj.Section):
return subsection return subsection
class ConfigObj(lib.configobj.ConfigObj, Section): class ConfigObj(lib.configobj.ConfigObj, Section):
# constants for nzbtomedia
NZBTOMEDIA_VERSION = 'V9.3'
NZBTOMEDIA_TIMEOUT = 60
# Constants pertinant to SabNzb
SABNZB_NO_OF_ARGUMENTS = 8
SABNZB_0717_NO_OF_ARGUMENTS = 9
# Constants pertaining to SickBeard Branches:
FORKS = {}
FORK_DEFAULT = "default"
FORK_FAILED = "failed"
FORK_FAILED_TORRENT = "failed-torrent"
FORKS[FORK_DEFAULT] = {"dir": None, "method": None}
FORKS[FORK_FAILED] = {"dirName": None, "failed": None}
FORKS[FORK_FAILED_TORRENT] = {"dir": None, "failed": None, "process_method": None}
SICKBEARD_FAILED = [FORK_FAILED, FORK_FAILED_TORRENT]
SICKBEARD_TORRENT = [FORK_FAILED_TORRENT]
# NZBGet Exit Codes
NZBGET_POSTPROCESS_PARCHECK = 92
NZBGET_POSTPROCESS_SUCCESS = 93
NZBGET_POSTPROCESS_ERROR = 94
NZBGET_POSTPROCESS_NONE = 95
# config files
PROGRAM_DIR = os.path.dirname(os.path.normpath(os.path.abspath(os.path.join(__file__, os.pardir))))
CONFIG_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg")
SAMPLE_CONFIG_FILE = os.path.join(PROGRAM_DIR, "autoProcessMedia.cfg.sample")
MOVIE_CONFIG_FILE = os.path.join(PROGRAM_DIR, "autoProcessMovie.cfg")
TV_CONFIG_FILE = os.path.join(PROGRAM_DIR, "autoProcessTv.cfg")
LOG_FILE = os.path.join(PROGRAM_DIR, "postprocess.log")
LOG_CONFIG = os.path.join(PROGRAM_DIR, "logging.cfg")
SAMPLE_LOG_CONFIG = os.path.join(PROGRAM_DIR, "logging.cfg.sample")
try:
repo = check_output(["git", "config", "--get", "remote.origin.url"]).splitlines()[0]
branch = check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).splitlines()[0]
hash = check_output(["git", "rev-parse", "--short", "HEAD"]).splitlines()[0]
NZBTOMEDIA_VERSION = 'repo:' + repo + ' branch:' + branch + ' hash: ' + hash
except CalledProcessError:
pass
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
if len(args) == 0: if len(args) == 0:
args = (self.CONFIG_FILE,) args = (nzbtomedia.CONFIG_FILE,)
super(lib.configobj.ConfigObj, self).__init__(*args, **kw) super(lib.configobj.ConfigObj, self).__init__(*args, **kw)
self.interpolation = False self.interpolation = False
@ -127,53 +85,55 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
#result.update({key: val}) #result.update({key: val})
return val return val
def migrate(self): @staticmethod
global config_new, config_old def migrate():
config_new = config_old = None global CFG_NEW, CFG_OLD
CFG_NEW = None
CFG_OLD = None
try: try:
# check for autoProcessMedia.cfg and create if it does not exist # check for autoProcessMedia.cfg and create if it does not exist
if not config(): if not os.path.isfile(nzbtomedia.CONFIG_FILE):
shutil.copyfile(self.SAMPLE_CONFIG_FILE, self.CONFIG_FILE) shutil.copyfile(nzbtomedia.CONFIG_SPEC_FILE, nzbtomedia.CONFIG_FILE)
config_old = config() CFG_OLD = config(nzbtomedia.CONFIG_FILE)
except: except:
pass pass
try: try:
# check for autoProcessMedia.cfg.sample and create if it does not exist # check for autoProcessMedia.cfg.spec and create if it does not exist
if not config(self.SAMPLE_CONFIG_FILE): if not os.path.isfile(nzbtomedia.CONFIG_SPEC_FILE):
shutil.copyfile(self.CONFIG_FILE, self.SAMPLE_CONFIG_FILE) shutil.copyfile(nzbtomedia.CONFIG_FILE, nzbtomedia.CONFIG_SPEC_FILE)
config_new = config(self.SAMPLE_CONFIG_FILE) CFG_NEW = config(nzbtomedia.CONFIG_SPEC_FILE)
except: except:
pass pass
# check for autoProcessMedia.cfg and autoProcessMedia.cfg.sample and if they don't exist return and fail # check for autoProcessMedia.cfg and autoProcessMedia.cfg.spec and if they don't exist return and fail
if not config() and not config(self.SAMPLE_CONFIG_FILE) or not config_new or not config_old: if not CFG_NEW or not CFG_OLD:
return False return False
subsections = {} subsections = {}
# gather all new-style and old-style sub-sections # gather all new-style and old-style sub-sections
for newsection, newitems in config_new.items(): for newsection, newitems in CFG_NEW.items():
if config_new[newsection].sections: if CFG_NEW[newsection].sections:
subsections.update({newsection: config_new[newsection].sections}) subsections.update({newsection: CFG_NEW[newsection].sections})
for section, items in config_old.items(): for section, items in CFG_OLD.items():
if config_old[section].sections: if CFG_OLD[section].sections:
subsections.update({section: config_old[section].sections}) subsections.update({section: CFG_OLD[section].sections})
for option, value in config_old[section].items(): for option, value in CFG_OLD[section].items():
if option in ["category", "cpsCategory", "sbCategory", "hpCategory", "mlCategory", "gzCategory"]: if option in ["category", "cpsCategory", "sbCategory", "hpCategory", "mlCategory", "gzCategory"]:
if not isinstance(value, list): if not isinstance(value, list):
value = [value] value = [value]
# add subsection # add subsection
subsections.update({section: value}) subsections.update({section: value})
config_old[section].pop(option) CFG_OLD[section].pop(option)
continue continue
def cleanup_values(values, section): def cleanup_values(values, section):
for option, value in values.iteritems(): for option, value in values.iteritems():
if section in ['CouchPotato']: if section in ['CouchPotato']:
if option == ['outputDirectory']: if option == ['outputDirectory']:
config_new['Torrent'][option] = os.path.split(os.path.normpath(value))[0] CFG_NEW['Torrent'][option] = os.path.split(os.path.normpath(value))[0]
values.pop(option) values.pop(option)
if section in ['CouchPotato', 'HeadPhones', 'Gamez']: if section in ['CouchPotato', 'HeadPhones', 'Gamez']:
if option in ['username', 'password']: if option in ['username', 'password']:
@ -188,11 +148,11 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
values['Torrent_NoLink'] = value values['Torrent_NoLink'] = value
values.pop(option) values.pop(option)
if option == "outputDirectory": # move this to new location format if option == "outputDirectory": # move this to new location format
config_new['Torrent'][option] = os.path.split(os.path.normpath(value))[0] CFG_NEW['Torrent'][option] = os.path.split(os.path.normpath(value))[0]
values.pop(option) values.pop(option)
if section in ["Torrent"]: if section in ["Torrent"]:
if option in ["compressedExtensions", "mediaExtensions", "metaExtensions", "minSampleSize"]: if option in ["compressedExtensions", "mediaExtensions", "metaExtensions", "minSampleSize"]:
config_new['Extensions'][option] = value CFG_NEW['Extensions'][option] = value
values.pop(option) values.pop(option)
if option == "useLink": # Sym links supported now as well. if option == "useLink": # Sym links supported now as well.
if isinstance(value, int): if isinstance(value, int):
@ -206,27 +166,27 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
def process_section(section, subsections=None): def process_section(section, subsections=None):
if subsections: if subsections:
for subsection in subsections: for subsection in subsections:
if subsection in config_old.sections: if subsection in CFG_OLD.sections:
values = config_old[subsection] values = CFG_OLD[subsection]
if subsection not in config_new[section].sections: if subsection not in CFG_NEW[section].sections:
config_new[section][subsection] = {} CFG_NEW[section][subsection] = {}
for option, value in values.items(): for option, value in values.items():
config_new[section][subsection][option] = value CFG_NEW[section][subsection][option] = value
elif subsection in config_old[section].sections: elif subsection in CFG_OLD[section].sections:
values = config_old[section][subsection] values = CFG_OLD[section][subsection]
if subsection not in config_new[section].sections: if subsection not in CFG_NEW[section].sections:
config_new[section][subsection] = {} CFG_NEW[section][subsection] = {}
for option, value in values.items(): for option, value in values.items():
config_new[section][subsection][option] = value CFG_NEW[section][subsection][option] = value
else: else:
values = config_old[section] values = CFG_OLD[section]
if section not in config_new.sections: if section not in CFG_NEW.sections:
config_new[section] = {} CFG_NEW[section] = {}
for option, value in values.items(): for option, value in values.items():
config_new[section][option] = value CFG_NEW[section][option] = value
# convert old-style categories to new-style sub-sections # convert old-style categories to new-style sub-sections
for section in config_old.keys(): for section in CFG_OLD.keys():
subsection = None subsection = None
if section in list(chain.from_iterable(subsections.values())): if section in list(chain.from_iterable(subsections.values())):
subsection = section subsection = section
@ -237,24 +197,28 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
subsection = subsections[section] subsection = subsections[section]
process_section(section, subsection) process_section(section, subsection)
#[[v.remove(c) for c in v if c in subsection] for k,v in subsections.items() if k == section] #[[v.remove(c) for c in v if c in subsection] for k,v in subsections.items() if k == section]
elif section in config_old.keys(): elif section in CFG_OLD.keys():
process_section(section, subsection) process_section(section, subsection)
# create a backup of our old config # create a backup of our old config
if os.path.isfile(self.CONFIG_FILE): if os.path.isfile(nzbtomedia.CONFIG_FILE):
cfgbak_name = self.CONFIG_FILE + ".old" cfgbak_name = nzbtomedia.CONFIG_FILE + ".old"
if os.path.isfile(cfgbak_name): # remove older backups if os.path.isfile(cfgbak_name): # remove older backups
os.unlink(cfgbak_name) os.unlink(cfgbak_name)
os.rename(self.CONFIG_FILE, cfgbak_name) os.rename(nzbtomedia.CONFIG_FILE, cfgbak_name)
# writing our configuration file to 'autoProcessMedia.cfg' # writing our configuration file to 'autoProcessMedia.cfg'
with open(self.CONFIG_FILE, 'wb') as configFile: with open(nzbtomedia.CONFIG_FILE, 'wb') as configFile:
config_new.write(configFile) CFG_NEW.write(configFile)
# reload config
nzbtomedia.CFG = CFG_NEW
return True return True
def addnzbget(self): @staticmethod
config_new = config() def addnzbget():
CFG_NEW = nzbtomedia.CFG
section = "CouchPotato" section = "CouchPotato"
envCatKey = 'NZBPO_CPSCATEGORY' envCatKey = 'NZBPO_CPSCATEGORY'
envKeys = ['ENABLED', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT', 'DELAY', 'METHOD', 'DELETE_FAILED', 'REMOTECPS', 'WAIT_FOR', 'TIMEPERGIB'] envKeys = ['ENABLED', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT', 'DELAY', 'METHOD', 'DELETE_FAILED', 'REMOTECPS', 'WAIT_FOR', 'TIMEPERGIB']
@ -265,10 +229,10 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
if os.environ[envCatKey] not in config_new[section].sections: if os.environ[envCatKey] not in CFG_NEW[section].sections:
config_new[section][os.environ[envCatKey]] = {} CFG_NEW[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value CFG_NEW[section][os.environ[envCatKey]][option] = value
config_new[section][os.environ[envCatKey]]['enabled'] = 1 CFG_NEW[section][os.environ[envCatKey]]['enabled'] = 1
section = "SickBeard" section = "SickBeard"
envCatKey = 'NZBPO_SBCATEGORY' envCatKey = 'NZBPO_SBCATEGORY'
@ -280,10 +244,10 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
if os.environ[envCatKey] not in config_new[section].sections: if os.environ[envCatKey] not in CFG_NEW[section].sections:
config_new[section][os.environ[envCatKey]] = {} CFG_NEW[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value CFG_NEW[section][os.environ[envCatKey]][option] = value
config_new[section][os.environ[envCatKey]]['enabled'] = 1 CFG_NEW[section][os.environ[envCatKey]]['enabled'] = 1
section = "HeadPhones" section = "HeadPhones"
envCatKey = 'NZBPO_HPCATEGORY' envCatKey = 'NZBPO_HPCATEGORY'
@ -295,10 +259,10 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
if os.environ[envCatKey] not in config_new[section].sections: if os.environ[envCatKey] not in CFG_NEW[section].sections:
config_new[section][os.environ[envCatKey]] = {} CFG_NEW[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value CFG_NEW[section][os.environ[envCatKey]][option] = value
config_new[section][os.environ[envCatKey]]['enabled'] = 1 CFG_NEW[section][os.environ[envCatKey]]['enabled'] = 1
section = "Mylar" section = "Mylar"
envCatKey = 'NZBPO_MYCATEGORY' envCatKey = 'NZBPO_MYCATEGORY'
@ -310,10 +274,10 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
if os.environ[envCatKey] not in config_new[section].sections: if os.environ[envCatKey] not in CFG_NEW[section].sections:
config_new[section][os.environ[envCatKey]] = {} CFG_NEW[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value CFG_NEW[section][os.environ[envCatKey]][option] = value
config_new[section][os.environ[envCatKey]]['enabled'] = 1 CFG_NEW[section][os.environ[envCatKey]]['enabled'] = 1
section = "Gamez" section = "Gamez"
envCatKey = 'NZBPO_GZCATEGORY' envCatKey = 'NZBPO_GZCATEGORY'
@ -325,10 +289,10 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
if os.environ[envCatKey] not in config_new[section].sections: if os.environ[envCatKey] not in CFG_NEW[section].sections:
config_new[section][os.environ[envCatKey]] = {} CFG_NEW[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value CFG_NEW[section][os.environ[envCatKey]][option] = value
config_new[section][os.environ[envCatKey]]['enabled'] = 1 CFG_NEW[section][os.environ[envCatKey]]['enabled'] = 1
section = "NzbDrone" section = "NzbDrone"
envCatKey = 'NZBPO_NDCATEGORY' envCatKey = 'NZBPO_NDCATEGORY'
@ -340,10 +304,10 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
if os.environ[envCatKey] not in config_new[section].sections: if os.environ[envCatKey] not in CFG_NEW[section].sections:
config_new[section][os.environ[envCatKey]] = {} CFG_NEW[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value CFG_NEW[section][os.environ[envCatKey]][option] = value
config_new[section][os.environ[envCatKey]]['enabled'] = 1 CFG_NEW[section][os.environ[envCatKey]]['enabled'] = 1
section = "Extensions" section = "Extensions"
envKeys = ['COMPRESSEDEXTENSIONS', 'MEDIAEXTENSIONS', 'METAEXTENSIONS'] envKeys = ['COMPRESSEDEXTENSIONS', 'MEDIAEXTENSIONS', 'METAEXTENSIONS']
@ -353,7 +317,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
config_new[section][option] = value CFG_NEW[section][option] = value
section = "Transcoder" section = "Transcoder"
envKeys = ['TRANSCODE', 'DUPLICATE', 'IGNOREEXTENSIONS', 'OUTPUTVIDEOEXTENSION', 'OUTPUTVIDEOCODEC', 'OUTPUTVIDEOPRESET', 'OUTPUTVIDEOFRAMERATE', 'OUTPUTVIDEOBITRATE', 'OUTPUTAUDIOCODEC', 'OUTPUTAUDIOBITRATE', 'OUTPUTSUBTITLECODEC'] envKeys = ['TRANSCODE', 'DUPLICATE', 'IGNOREEXTENSIONS', 'OUTPUTVIDEOEXTENSION', 'OUTPUTVIDEOCODEC', 'OUTPUTVIDEOPRESET', 'OUTPUTVIDEOFRAMERATE', 'OUTPUTVIDEOBITRATE', 'OUTPUTAUDIOCODEC', 'OUTPUTAUDIOBITRATE', 'OUTPUTSUBTITLECODEC']
@ -363,7 +327,7 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
config_new[section][option] = value CFG_NEW[section][option] = value
section = "WakeOnLan" section = "WakeOnLan"
envKeys = ['WAKE', 'HOST', 'PORT', 'MAC'] envKeys = ['WAKE', 'HOST', 'PORT', 'MAC']
@ -373,18 +337,21 @@ class ConfigObj(lib.configobj.ConfigObj, Section):
if os.environ.has_key(key): if os.environ.has_key(key):
option = cfgKeys[index] option = cfgKeys[index]
value = os.environ[key] value = os.environ[key]
config_new[section][option] = value CFG_NEW[section][option] = value
# create a backup of our old config # create a backup of our old config
if os.path.isfile(self.CONFIG_FILE): if os.path.isfile(nzbtomedia.CONFIG_FILE):
cfgbak_name = self.CONFIG_FILE + ".old" cfgbak_name = nzbtomedia.CONFIG_FILE + ".old"
if os.path.isfile(cfgbak_name): # remove older backups if os.path.isfile(cfgbak_name): # remove older backups
os.unlink(cfgbak_name) os.unlink(cfgbak_name)
os.rename(self.CONFIG_FILE, cfgbak_name) os.rename(nzbtomedia.CONFIG_FILE, cfgbak_name)
# writing our configuration file to 'autoProcessMedia.cfg' # writing our configuration file to 'autoProcessMedia.cfg'
with open(self.CONFIG_FILE, 'wb') as configFile: with open(nzbtomedia.CONFIG_FILE, 'wb') as configFile:
config_new.write(configFile) CFG_NEW.write(configFile)
# reload config
nzbtomedia.CFG = CFG_NEW
lib.configobj.Section = Section lib.configobj.Section = Section
lib.configobj.ConfigObj = ConfigObj lib.configobj.ConfigObj = ConfigObj

View file

@ -15,13 +15,13 @@ def process_exception(exception, name, dirname):
exception(filename, parentDir) exception(filename, parentDir)
def process_qoq(filename, dirname): def process_qoq(filename, dirname):
Logger.debug("Reversing the file name for a QoQ release %s", filename) logger.debug("Reversing the file name for a QoQ release %s", filename)
head, fileExtension = os.path.splitext(os.path.basename(filename)) head, fileExtension = os.path.splitext(os.path.basename(filename))
newname = head[::-1] newname = head[::-1]
newfile = newname + fileExtension newfile = newname + fileExtension
newfilePath = os.path.join(dirname, newfile) newfilePath = os.path.join(dirname, newfile)
os.rename(filename, newfilePath) os.rename(filename, newfilePath)
Logger.debug("New file name is %s", newfile) logger.debug("New file name is %s", newfile)
# dict for custom groups # dict for custom groups
# we can add more to this list # we can add more to this list

View file

@ -5,14 +5,10 @@ import struct
import shutil import shutil
import sys import sys
import time import time
import logging import nzbtomedia
import logging.config
import logging.handlers
from nzbtomedia.linktastic import linktastic from nzbtomedia.linktastic import linktastic
from nzbtomedia.nzbToMediaConfig import config from nzbtomedia import logger
Logger = logging.getLogger()
def getDirectorySize(directory): def getDirectorySize(directory):
dir_size = 0 dir_size = 0
@ -28,28 +24,24 @@ def safeName(name):
safename = re.sub(r"[\/\\\:\*\?\"\<\>\|]", "", name) #make this name safe for use in directories for windows etc. safename = re.sub(r"[\/\\\:\*\?\"\<\>\|]", "", name) #make this name safe for use in directories for windows etc.
return safename return safename
def nzbtomedia_configure_logging(logfile=None):
if not logfile:
logfile = config.LOG_FILE
logging.config.fileConfig(config.LOG_CONFIG)
fileHandler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=1048576, backupCount=1, encoding='utf-8', delay=True)
fileHandler.formatter = logging.Formatter('%(asctime)s|%(levelname)-7.7s %(message)s', '%H:%M:%S')
fileHandler.level = logging.DEBUG
logging.getLogger().addHandler(fileHandler)
def create_destination(outputDestination): def create_destination(outputDestination):
if os.path.exists(outputDestination): if os.path.exists(outputDestination):
return return
try: try:
Logger.info("CREATE DESTINATION: Creating destination folder: %s", outputDestination) logger.info("CREATE DESTINATION: Creating destination folder: %s", outputDestination)
os.makedirs(outputDestination) os.makedirs(outputDestination)
except: except:
Logger.exception("CREATE DESTINATION: Not possible to create destination folder. Exiting") logger.error("CREATE DESTINATION: Not possible to create destination folder. Exiting")
sys.exit(-1) sys.exit(-1)
def makeDir(path):
if not os.path.isdir(path):
try:
os.makedirs( path)
except OSError:
return False
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
@ -61,10 +53,10 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories):
try: try:
inputCategory = list(set(pathlist) & set(categories))[-1] # assume last match is most relevant category. inputCategory = list(set(pathlist) & set(categories))[-1] # assume last match is most relevant category.
Logger.debug("SEARCH: Found Category: %s in directory structure", inputCategory) logger.debug("SEARCH: Found Category: %s in directory structure", inputCategory)
except IndexError: except IndexError:
inputCategory = "" inputCategory = ""
Logger.debug("SEARCH: Could not find a category in the directory structure") logger.debug("SEARCH: Could not find a category in the directory structure")
if not os.path.isdir(inputDirectory) and os.path.isfile(inputDirectory): # If the input directory is a file if not os.path.isdir(inputDirectory) and os.path.isfile(inputDirectory): # If the input directory is a file
single = True single = True
@ -72,18 +64,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
imdbid = [item for item in pathlist if '.cp(tt' in item] # This looks for the .cp(tt imdb id in the path. imdbid = [item for item in pathlist if '.cp(tt' in item] # This looks for the .cp(tt imdb id in the path.
@ -96,14 +88,14 @@ 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
if inputName and not tordir: if inputName and not tordir:
if inputName in pathlist or safeName(inputName) in pathlist: if inputName in pathlist or safeName(inputName) in pathlist:
Logger.info("SEARCH: Found torrent directory %s in the directory structure", inputName) logger.info("SEARCH: Found torrent directory %s in the directory structure", inputName)
tordir = True tordir = True
else: else:
root = 1 root = 1
@ -111,8 +103,8 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories):
root = 2 root = 2
if root > 0: if root > 0:
Logger.info("SEARCH: Could not find a unique directory for this download. Assume a common directory.") logger.info("SEARCH: Could not find a unique directory for this download. Assume a common directory.")
Logger.info("SEARCH: We will try and determine which files to process, individually") logger.info("SEARCH: We will try and determine which files to process, individually")
return inputDirectory, inputName, inputCategory, root, single return inputDirectory, inputName, inputCategory, root, single
@ -132,47 +124,47 @@ def is_sample(filePath, inputName, minSampleSize, SampleIDs):
def copy_link(filePath, targetDirectory, useLink, outputDestination): def copy_link(filePath, targetDirectory, useLink, outputDestination):
if os.path.isfile(targetDirectory): if os.path.isfile(targetDirectory):
Logger.info("COPYLINK: target file already exists. Nothing to be done") logger.info("COPYLINK: target file already exists. Nothing to be done")
return True return True
create_destination(outputDestination) create_destination(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.exception("COPYLINK") logger.error("COPYLINK")
if os.path.isfile(targetDirectory): if os.path.isfile(targetDirectory):
Logger.warn("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.warn("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.exception("COPYLINK") logger.error("COPYLINK")
if os.path.isfile(targetDirectory): if os.path.isfile(targetDirectory):
Logger.warn("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
@ -182,12 +174,12 @@ def flatten(outputDestination):
try: try:
shutil.move(source, target) shutil.move(source, target)
except: except:
Logger.exception("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):
return return
@ -202,7 +194,7 @@ def removeEmptyFolders(path):
# If folder empty, delete it # If folder empty, delete it
files = os.listdir(path) files = os.listdir(path)
if len(files) == 0: if len(files) == 0:
Logger.debug("REMOVER: Removing empty folder: %s", path) logger.debug("REMOVER: Removing empty folder: %s", path)
os.rmdir(path) os.rmdir(path)
def iterate_media_files(dirname): def iterate_media_files(dirname):
@ -248,49 +240,49 @@ def TestCon(host, port):
return "Down" return "Down"
def WakeUp(): def WakeUp():
if not config(): if not nzbtomedia.CFG:
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
return return
wake = int(config()["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", config.CONFIG_FILE) logger.info(("Loading WakeOnLan config from %s", nzbtomedia.CONFIG_FILE))
host = config()["WakeOnLan"]["host"] host = nzbtomedia.CFG["WakeOnLan"]["host"]
port = int(config()["WakeOnLan"]["port"]) port = int(nzbtomedia.CFG["WakeOnLan"]["port"])
mac = config()["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):
if not config(): if not nzbtomedia.CFG:
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
return nzbName, dirName return nzbName, dirName
ascii_convert = int(config()["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
@ -380,21 +372,21 @@ def get_dirnames(section, subsections=None):
dirNames = [] dirNames = []
if subsections is None: if subsections is None:
subsections = config.get_subsections(section).values() subsections = nzbtomedia.get_subsections(section).values()
if not isinstance(subsections, list): if not isinstance(subsections, list):
subsections = [subsections] subsections = [subsections]
for subsection in subsections: for subsection in subsections:
try: try:
watch_dir = config()[section][subsection]["watch_dir"] watch_dir = nzbtomedia.CFG[section][subsection]["watch_dir"]
if not os.path.exists(watch_dir): if not os.path.exists(watch_dir):
watch_dir = None watch_dir = None
except: except:
watch_dir = None watch_dir = None
try: try:
outputDirectory = os.path.join(config()["Torrent"]["outputDirectory"], subsection) outputDirectory = os.path.join(nzbtomedia.CFG["Torrent"]["outputDirectory"], subsection)
if not os.path.exists(outputDirectory): if not os.path.exists(outputDirectory):
outputDirectory = None outputDirectory = None
except: except:
@ -404,22 +396,22 @@ def get_dirnames(section, subsections=None):
dirNames.extend([os.path.join(watch_dir, o) for o in os.listdir(watch_dir) if dirNames.extend([os.path.join(watch_dir, o) for o in os.listdir(watch_dir) if
os.path.isdir(os.path.join(watch_dir, o))]) os.path.isdir(os.path.join(watch_dir, o))])
if not dirNames: if not dirNames:
Logger.warn("%s:%s has no directories identified to scan inside %s", section, subsection, watch_dir) logger.warning("%s:%s has no directories identified to scan inside %s", section, subsection, watch_dir)
if outputDirectory: if outputDirectory:
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.warn("%s:%s has no directories identified to scan inside %s", section, subsection, outputDirectory) logger.warning("%s:%s has no directories identified to scan inside %s", section, subsection, outputDirectory)
if watch_dir is None and outputDirectory is None: if watch_dir is None and outputDirectory is None:
Logger.warn("%s:%s has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.", section, subsection) logger.warning("%s:%s has no watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.", section, subsection)
return dirNames return dirNames
def delete(dirName): def delete(dirName):
Logger.info("Deleting failed files and folder %s", dirName) logger.info("Deleting failed files and folder %s", dirName)
try: try:
shutil.rmtree(dirName, True) shutil.rmtree(dirName, True)
except: except:
Logger.exception("Unable to delete folder %s", dirName) logger.error("Unable to delete folder %s", dirName)

243
nzbtomedia/versionCheck.py Normal file
View file

@ -0,0 +1,243 @@
import os
import shutil
import urllib
import tarfile
import stat
import traceback
import gh_api as github
import nzbtomedia
from nzbtomedia import logger
class CheckVersion():
"""
Version check class meant to run as a thread object with the SB scheduler.
"""
def __init__(self):
self.updater = SourceUpdateManager()
def run(self):
self.check_for_new_version()
def check_for_new_version(self, force=False):
"""
Checks the internet for a newer version.
returns: bool, True for new version or False for no new version.
force: if true the VERSION_NOTIFY setting will be ignored and a check will be forced
"""
logger.info("Checking if nzbToMedia needs an update")
if not self.updater.need_update():
NEWEST_VERSION_STRING = None
logger.info("No update needed")
if force:
logger.info("No update needed")
return False
if not self.updater._cur_commit_hash:
logger.info("Unknown current version number, don't know if we should update or not")
elif self.updater._num_commits_behind > 0:
logger.info("There is a newer version available, (you're " + str(self.updater._num_commits_behind) + " commit(s) behind")
return True
def update(self):
if self.updater.need_update():
return self.updater.update()
class UpdateManager():
def get_github_repo_user(self):
return 'clinton-hall'
def get_github_repo(self):
return 'nzbToMedia'
# def get_update_url(self):
# return nzbtomedia.WEB_ROOT + "/home/update/?pid=" + str(nzbtomedia.PID)
class SourceUpdateManager(UpdateManager):
def __init__(self):
self.github_repo_user = self.get_github_repo_user()
self.github_repo = self.get_github_repo()
self.branch = 'master'
self._cur_commit_hash = None
self._newest_commit_hash = None
self._num_commits_behind = 0
def _find_installed_version(self):
version_file = os.path.join(nzbtomedia.PROGRAM_DIR, u'version.txt')
if not os.path.isfile(version_file):
self._cur_commit_hash = None
return
try:
with open(version_file, 'r') as fp:
self._cur_commit_hash = fp.read().strip(' \n\r')
except EnvironmentError, e:
logger.debug("Unable to open 'version.txt': " + str(e))
if not self._cur_commit_hash:
self._cur_commit_hash = None
def need_update(self):
self._find_installed_version()
try:
self._check_github_for_update()
except Exception, e:
logger.error("Unable to contact github, can't check for update: " + repr(e))
return False
if not self._cur_commit_hash or self._num_commits_behind > 0:
return True
return False
def _check_github_for_update(self):
"""
Uses pygithub to ask github if there is a newer version that the provided
commit hash. If there is a newer version it sets Sick Beard's version text.
commit_hash: hash that we're checking against
"""
self._num_commits_behind = 0
self._newest_commit_hash = None
gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch)
# try to get newest commit hash and commits behind directly by comparing branch and current commit
if self._cur_commit_hash:
branch_compared = gh.compare(base=self.branch, head=self._cur_commit_hash)
if 'base_commit' in branch_compared:
self._newest_commit_hash = branch_compared['base_commit']['sha']
if 'behind_by' in branch_compared:
self._num_commits_behind = int(branch_compared['behind_by'])
# fall back and iterate over last 100 (items per page in gh_api) commits
if not self._newest_commit_hash:
for curCommit in gh.commits():
if not self._newest_commit_hash:
self._newest_commit_hash = curCommit['sha']
if not self._cur_commit_hash:
break
if curCommit['sha'] == self._cur_commit_hash:
break
# when _cur_commit_hash doesn't match anything _num_commits_behind == 100
self._num_commits_behind += 1
logger.debug("cur_commit = " + str(self._cur_commit_hash) + ", newest_commit = " + str(self._newest_commit_hash)
+ ", num_commits_behind = " + str(self._num_commits_behind))
def set_newest_text(self):
# if we're up to date then don't set this
nzbtomedia.NEWEST_VERSION_STRING = None
if not self._cur_commit_hash:
logger.info("Unknown current version number, don't know if we should update or not")
elif self._num_commits_behind > 0:
logger.info("There is a newer version available, (you're " + str(self._num_commits_behind) + " commit(s) behind")
def update(self):
"""
Downloads the latest source tarball from github and installs it over the existing version.
"""
base_url = 'https://github.com/' + self.github_repo_user + '/' + self.github_repo
tar_download_url = base_url + '/tarball/' + self.branch
version_path = os.path.join(nzbtomedia.PROGRAM_DIR, u'version.txt')
try:
# prepare the update dir
sb_update_dir = os.path.join(nzbtomedia.PROGRAM_DIR, u'sb-update')
if os.path.isdir(sb_update_dir):
logger.info("Clearing out update folder " + sb_update_dir + " before extracting")
shutil.rmtree(sb_update_dir)
logger.info("Creating update folder " + sb_update_dir + " before extracting")
os.makedirs(sb_update_dir)
# retrieve file
logger.info("Downloading update from " + repr(tar_download_url))
tar_download_path = os.path.join(sb_update_dir, u'sb-update.tar')
urllib.urlretrieve(tar_download_url, tar_download_path)
if not str(os.path.isfile, tar_download_path):
logger.error("Unable to retrieve new version from " + tar_download_url + ", can't update")
return False
if not str(tarfile.is_tarfile, tar_download_path):
logger.error("Retrieved version from " + tar_download_url + " is corrupt, can't update")
return False
# extract to sb-update dir
logger.info("Extracting file " + tar_download_path)
tar = tarfile.open(tar_download_path)
tar.extractall(sb_update_dir)
tar.close()
# delete .tar.gz
logger.info("Deleting file " + tar_download_path)
os.remove(tar_download_path)
# find update dir name
update_dir_contents = [x for x in os.listdir(sb_update_dir) if
os.path.isdir(os.path.join(sb_update_dir, x))]
if len(update_dir_contents) != 1:
logger.error("Invalid update data, update failed: " + str(update_dir_contents))
return False
content_dir = os.path.join(sb_update_dir, update_dir_contents[0])
# walk temp folder and move files to main folder
logger.info("Moving files from " + content_dir + " to " + nzbtomedia.PROGRAM_DIR)
for dirname, dirnames, filenames in os.walk(content_dir): # @UnusedVariable
dirname = dirname[len(content_dir) + 1:]
for curfile in filenames:
old_path = os.path.join(content_dir, dirname, curfile)
new_path = os.path.join(nzbtomedia.PROGRAM_DIR, dirname, curfile)
#Avoid DLL access problem on WIN32/64
#These files needing to be updated manually
#or find a way to kill the access from memory
if curfile in ('unrar.dll', 'unrar64.dll'):
try:
os.chmod(new_path, stat.S_IWRITE)
os.remove(new_path)
os.renames(old_path, new_path)
except Exception, e:
logger.debug("Unable to update " + new_path + ': ' + str(e))
os.remove(old_path) # Trash the updated file without moving in new path
continue
if os.path.isfile(new_path):
os.remove(new_path)
os.renames(old_path, new_path)
# update version.txt with commit hash
try:
with open(version_path, 'w') as ver_file:
ver_file.write(self._newest_commit_hash)
except EnvironmentError, e:
logger.error("Unable to write version file, update not complete: " + str(e))
return False
except Exception, e:
logger.error("Error while trying to update: " + str(e))
logger.debug("Traceback: " + traceback.format_exc())
return False
return True

View file

@ -1,21 +1,28 @@
from nzbtomedia.nzbToMediaConfig import config import nzbtomedia
from nzbtomedia.versionCheck import CheckVersion
from nzbtomedia import logger
print config().findsection('tv').isenabled() # Initialize the config
nzbtomedia.initialize()
test = CheckVersion().check_for_new_version()
print nzbtomedia.CFG.findsection('tv')
print print
print config().sections print nzbtomedia.CFG.sections
print print
sections = ("CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez") sections = ("CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez")
print config()[sections].subsections print nzbtomedia.CFG[sections].subsections
print config()['SickBeard'].subsections print nzbtomedia.CFG['SickBeard'].subsections
print print
print config()[sections].sections print nzbtomedia.CFG[sections].sections
print config()['SickBeard'].sections print nzbtomedia.CFG['SickBeard'].sections
print print
print config()['SickBeard','NzbDrone'] print nzbtomedia.CFG['SickBeard','NzbDrone']
print config()['SickBeard'] print nzbtomedia.CFG['SickBeard']
print print
print config()['SickBeard','NzbDrone','CouchPotato'].issubsection('tv', True) print nzbtomedia.CFG['SickBeard','NzbDrone','CouchPotato'].issubsection('tv', True)
print config()['SickBeard'].issubsection('tv', True) print nzbtomedia.CFG['SickBeard'].issubsection('tv', True)
print print
print config()['SickBeard','NzbDrone'].isenabled('tv') print nzbtomedia.CFG['SickBeard','NzbDrone'].isenabled('tv')
print config()['SickBeard'].isenabled('tv') print nzbtomedia.CFG['SickBeard'].isenabled('tv')