Fixed a bunch of issues that where present in TorrentToMedia and our config class including the migration code.

Added in manual run for TorrentToMedia.

All autoProcessing scripts now auto-detect the correct section based on sub-section.

NzbDrone support is 90% done but is not functional ... YET!

Lots more I'm sure but I wanted this released for those that where having issues.
This commit is contained in:
echel0n 2014-04-07 01:42:55 -07:00
parent 0ce4bb601d
commit 7d4ccf53cc
17 changed files with 715 additions and 305 deletions

View file

@ -20,7 +20,7 @@ from nzbtomedia.extractor import extractor
from nzbtomedia.nzbToMediaAutoFork import autoFork
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaUtil import category_search, safeName, is_sample, copy_link, WakeUp, parse_args, flatten, \
nzbtomedia_configure_logging
nzbtomedia_configure_logging, get_dirnames
from nzbtomedia.synchronousdeluge.client import DelugeClient
from nzbtomedia.utorrent.client import UTorrentClient
from nzbtomedia.transmissionrpc.client import Client as TransmissionClient
@ -48,19 +48,16 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
Logger.debug("MAIN: Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory)
if inputCategory in sections["SickBeard"]:
fork, fork_params = autoFork("SickBeard", inputCategory)
Torrent_NoLink = int(config()["SickBeard"][inputCategory]["Torrent_NoLink"]) # 0
if fork in config.SICKBEARD_TORRENT and Torrent_NoLink == 1:
Logger.info("MAIN: Calling SickBeard's %s branch to post-process: %s",fork ,inputName)
result = autoProcessTV().processEpisode(inputDirectory, inputName, 0)
if config.issubsection(inputCategory,["SickBeard","NzbDrone"]):
Logger.info("MAIN: Calling autoProcessTV to post-process: %s",inputName)
result = autoProcessTV().processEpisode(inputDirectory, inputName, 0, clientAgent=clientAgent, inputCategory=inputCategory)
if result != 0:
Logger.info("MAIN: A problem was reported in the autoProcess* script.")
Logger.info("MAIN: A problem was reported in the autoProcessTV script.")
Logger.info("MAIN: All done.")
sys.exit()
outputDestination = ""
for section, category in sections.items():
for category in categories:
if category == inputCategory:
if os.path.basename(inputDirectory) == inputName and os.path.isdir(inputDirectory):
Logger.info("MAIN: Download is a directory")
@ -72,6 +69,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
break
else:
continue
if outputDestination == "":
if inputCategory == "":
inputCategory = "UNCAT"
@ -83,7 +81,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
outputDestination = os.path.normpath(os.path.join(outputDirectory, inputCategory, os.path.splitext(safeName(inputName))[0]))
Logger.info("MAIN: Output directory set to: %s", outputDestination)
processOnly = list(chain.from_iterable(sections.values()))
processOnly = list(chain.from_iterable(subsections.values()))
if not "NONE" in user_script_categories: # if None, we only process the 5 listed.
if "ALL" in user_script_categories: # All defined categories
processOnly = categories
@ -130,14 +128,14 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
Logger.debug("MAIN: Scanning files in directory: %s", inputDirectory)
noFlatten.extend(list(chain.from_iterable(config.get_sections(["HeadPhones"]).values()))) # Make sure we preserve folder structure for HeadPhones.
if config.issubsection(inputCategory, "HeadPhones"):
noFlatten.extend(list(chain.from_iterable(config()[section].sections))) # Make sure we preserve folder structure for HeadPhones.
outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards.
now = datetime.datetime.now()
for dirpath, dirnames, filenames in os.walk(inputDirectory):
Logger.debug("MAIN: Found %s files in %s", str(len(filenames)), dirpath)
for file in filenames:
filePath = os.path.join(dirpath, file)
fileName, fileExtension = os.path.splitext(file)
if inputCategory in noFlatten:
@ -172,7 +170,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
continue # This file has not been recently moved or created, skip it
if fileExtension in mediaContainer: # If the file is a video file
if is_sample(filePath, inputName, minSampleSize, SampleIDs) and not inputCategory in config.get_sections(["HeadPhones"]).values(): # Ignore samples
if is_sample(filePath, inputName, minSampleSize, SampleIDs) and not config.issubsection(inputCategory, ["HeadPhones"]): # Ignore samples
Logger.info("MAIN: Ignoring sample file: %s ", filePath)
continue
else:
@ -208,7 +206,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
except:
Logger.exception("MAIN: Extraction failed for: %s", file)
continue
elif not inputCategory in list(chain.from_iterable(config.get_sections(['CouchPotato','SickBeard']).values())): #process all for non-video categories.
elif not config.issubsection(inputCategory,['CouchPotato','SickBeard','NzbDrone']): #process all for non-video categories.
Logger.info("MAIN: Found file %s for category %s", filePath, inputCategory)
copy_link(filePath, targetDirectory, useLink, outputDestination)
copy_list.append([filePath, os.path.join(outputDestination, file)])
@ -221,8 +219,8 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
if not inputCategory in noFlatten: #don't flatten hp in case multi cd albums, and we need to copy this back later.
flatten(outputDestination)
# Now check if movie files exist in destination:
if inputCategory in list(chain.from_iterable(config.get_sections(['CouchPotato','SickBeard']).values())):
# Now check if video files exist in destination:
if config.issubsection(inputCategory,["SickBeard","NzbDrone"]):
for dirpath, dirnames, filenames in os.walk(outputDestination):
for file in filenames:
filePath = os.path.join(dirpath, file)
@ -242,12 +240,12 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
else:
Logger.debug("MAIN: Found %s media files in output. %s were found in input", str(video2), str(video))
processCategories = list(chain.from_iterable(sections.values()))
processCategories = list(chain.from_iterable(subsections.values()))
if (inputCategory in user_script_categories and not "NONE" in user_script_categories) or ("ALL" in user_script_categories and not inputCategory in processCategories):
Logger.info("MAIN: Processing user script %s.", user_script)
result = external_script(outputDestination,inputName,inputCategory)
elif status == int(0) or (inputCategory in list(chain.from_iterable(config.get_sections(['HeadPhones','Mylar','Gamez']).values()))): # if movies linked/extracted or for other categories.
elif status == int(0) or (config.issubsection(inputCategory,['HeadPhones','Mylar','Gamez'])): # if movies linked/extracted or for other categories.
Logger.debug("MAIN: Calling autoProcess script for successful download.")
status = int(0) # hp, my, gz don't support failed.
else:
@ -255,21 +253,24 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
sys.exit(-1)
result = 0
if inputCategory in sections['CouchPotato'].values():
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
if config.issubsection(inputCategory,['CouchPotato']):
Logger.info("MAIN: Calling CouchPotato:" + inputCategory + " to post-process: %s", inputName)
download_id = inputHash
result = autoProcessMovie().process(outputDestination, inputName, status, clientAgent, download_id, inputCategory)
elif inputCategory in sections['SickBeard'].values():
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
elif config.issubsection(inputCategory,['SickBeard']):
Logger.info("MAIN: Calling Sick-Beard:" + inputCategory + " to post-process: %s", inputName)
result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
elif inputCategory in sections['HeadPhones'].values():
Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName)
elif config.issubsection(inputCategory,['NzbDrone']):
Logger.info("MAIN: Calling NzbDrone:" + inputCategory + " to post-process: %s", inputName)
result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
elif config.issubsection(inputCategory,['HeadPhones']):
Logger.info("MAIN: Calling HeadPhones:" + inputCategory + " to post-process: %s", inputName)
result = autoProcessMusic().process(inputDirectory, inputName, status, clientAgent, inputCategory)
elif inputCategory in sections['Mylar'].values():
Logger.info("MAIN: Calling Mylar to post-process: %s", inputName)
elif config.issubsection(inputCategory,['Mylar']):
Logger.info("MAIN: Calling Mylar:" + inputCategory + " to post-process: %s", inputName)
result = autoProcessComics().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
elif inputCategory in sections['Gamez'].values():
Logger.info("MAIN: Calling Gamez to post-process: %s", inputName)
elif config.issubsection(inputCategory,['Gamez']):
Logger.info("MAIN: Calling Gamez:" + inputCategory + " to post-process: %s", inputName)
result = autoProcessGames().process(outputDestination, inputName, status, clientAgent, inputCategory)
if result == 1:
@ -434,8 +435,8 @@ if __name__ == "__main__":
minSampleSize = int(config()["Extensions"]["minSampleSize"]) # 200 (in MB)
SampleIDs = (config()["Extensions"]["SampleIDs"]) # sample,-s.
sections = config.get_sections(["CouchPotato", "SickBeard", "HeadPhones", "Mylar", "Gamez"])
categories += list(chain.from_iterable(sections.values()))
subsections = config.get_subsections(["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"])
categories += list(chain.from_iterable(subsections.values()))
user_script_categories = config()["UserScript"]["user_script_categories"] # NONE
if not "NONE" in user_script_categories:
@ -460,4 +461,13 @@ if __name__ == "__main__":
Logger.exception("MAIN: There was a problem loading variables")
sys.exit(-1)
# check if this is a manual run
if inputDirectory is None:
for section, subsection in subsections.iteritems():
for category in subsection:
dirNames = get_dirnames(section, category)
Logger.info("MAIN: TorrentToMedia running %s:%s as a manual run...", section, category)
for dirName in dirNames:
main(dirName, os.path.basename(dirName), category, inputHash, inputID)
else:
main(inputDirectory, inputName, inputCategory, inputHash, inputID)

View file

@ -5,6 +5,7 @@
#### autoProcessing for Movies
#### movie - category that gets called for post-processing with CPS
[[movie]]
enabled = 0
apikey =
host = localhost
port = 5050
@ -24,6 +25,7 @@
#### autoProcessing for TV Series
#### tv - category that gets called for post-processing with SB
[[tv]]
enabled = 0
host = localhost
port = 8081
username =
@ -40,10 +42,30 @@
Torrent_NoLink = 0
process_method =
[NzbDrone]
#### autoProcessing for TV Series
#### ndCategory - category that gets called for post-processing with NzbDrone
[[tv]]
enabled = 0
host = localhost
port = 8989
username =
password =
###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
web_root =
ssl = 0
delay = 0
TimePerGiB = 60
watch_dir =
delete_failed = 0
nzbExtractionBy = Downloader
Torrent_NoLink = 0
[HeadPhones]
#### autoProcessing for Music
#### music - category that gets called for post-processing with HP
[[music]]
enabled = 0
apikey =
host = localhost
port = 8181
@ -58,6 +80,7 @@
#### autoProcessing for Comics
#### comics - category that gets called for post-processing with Mylar
[[comics]]
enabled = 0
host = localhost
port= 8090
username=
@ -71,6 +94,7 @@
#### autoProcessing for Games
#### games - category that gets called for post-processing with Gamez
[[games]]
enabled = 0
apikey =
host = localhost
port = 8085
@ -173,3 +197,28 @@
# enter the full path to a text file containing passwords to be used for extraction attempts.
# In the passwords file, every password should be on a new line
PassWordFile =
# Logging configuration
[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

23
logging.cfg.sample Normal file
View file

@ -0,0 +1,23 @@
[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

@ -147,9 +147,6 @@ if config.migrate():
else:
sys.exit(-1)
# setup sections and categories
sections = config.get_sections(["CouchPotato"])
WakeUp()
# NZBGet V11+
@ -235,16 +232,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
else:
result = 0
Logger.warn("MAIN: Invalid number of arguments received from client.")
Logger.info("MAIN: Running autoProcessMovie as a manual run...")
# init sub-sections
subsections = config.get_subsections(["CouchPotato"])
for section, categories in sections.items():
for category in categories:
Logger.warn("MAIN: Invalid number of arguments received from client.")
for section, subsection in subsections.items():
for category in subsection:
dirNames = get_dirnames(section, category)
for dirName in dirNames:
Logger.info("MAIN: Calling " + section + ":" + category + " to post-process: %s", dirName)
results = autoProcessMovie().process(dirName, dirName, 0, inputCategory=category)
if results != 0:result = results
Logger.info("MAIN: nzbToCouchPotato running %s:%s as a manual run...", section, subsection)
results = autoProcessMovie(dirName, inputName=os.path.basename(dirName), status=0, clientAgent="manual",
inputCategory=category)
if results != 0:
result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, subsection)
if result == 0:
Logger.info("MAIN: The autoProcessMovie script completed successfully.")

View file

@ -83,7 +83,7 @@ else:
sys.exit(-1)
# gamez category
sections = config.get_sections(['Gamez'])
sections = config.get_subsections(['Gamez'])
WakeUp()
@ -162,16 +162,19 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
else:
result = 0
Logger.warn("MAIN: Invalid number of arguments received from client. Exiting")
Logger.info("MAIN: Running autoProcessGames as a manual run...")
# init sub-sections
subsections = config.get_subsections(["Gamez"])
for section, categories in sections.items():
for category in categories:
Logger.warn("MAIN: Invalid number of arguments received from client.")
for section, subsection in subsections.items():
for category in subsection:
dirNames = get_dirnames(section, category)
for dirName in dirNames:
Logger.info("MAIN: Calling " + section + ":" + category + " to post-process: %s", dirName)
results = autoProcessGames().process(dirName, dirName, 0, inputCategory=category)
if results != 0:result = results
Logger.info("MAIN: nzbToGamez running %s:%s as a manual run...", section, category)
results = autoProcessGames(dirName, inputName=os.path.basename(dirName), status=0, clientAgent = "manual", inputCategory=category)
if results != 0:
result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, category)
if result == 0:
Logger.info("MAIN: The autoProcessGames script completed successfully.")

View file

@ -95,9 +95,6 @@ if config.migrate():
else:
sys.exit(-1)
# headphones category
sections = config.get_sections(["HeadPhones"])
WakeUp()
# NZBGet V11+
@ -175,16 +172,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
else:
result = 0
Logger.warn("MAIN: Invalid number of arguments received from client.")
Logger.info("MAIN: Running autoProcessMusic as a manual run...")
# init sub-sections
subsections = config.get_subsections(["HeadPhones"])
for section, categories in sections.items():
for category in categories:
Logger.warn("MAIN: Invalid number of arguments received from client.")
for section, subsection in subsections.items():
for category in subsection:
dirNames = get_dirnames(section, category)
for dirName in dirNames:
Logger.info("MAIN: Calling " + section + ":" + category + " to post-process: %s", dirName)
results = autoProcessMusic().process(dirName, dirName, 0, inputCategory=category)
if results != 0:result = results
Logger.info("MAIN: nzbToHeadPhones running %s:%s as a manual run...", section, subsection)
results = autoProcessMusic(dirName, inputName=os.path.basename(dirName), status=0, clientAgent="manual",
inputCategory=category)
if results != 0:
result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, subsection)
if result == 0:
Logger.info("MAIN: The autoProcessMusic script completed successfully.")

View file

@ -9,7 +9,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
##############################################################################
### NZBGET POST-PROCESSING SCRIPT ###
# Post-Process to CouchPotato, SickBeard, Mylar, Gamez, HeadPhones.
# Post-Process to CouchPotato, SickBeard, NzbDrone, Mylar, Gamez, HeadPhones.
#
# This script sends the download to your automated media management servers.
#
@ -133,6 +133,35 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
# set this to move, copy, hardlin, symlink as appropriate if you want to over-ride SB defaults. Leave blank to use SB default.
#sbprocess_method=
## NzbDrone
# NzbDrone script category.
#
# category that gets called for post-processing with NzbDrone.
#ndCategory=tv
# NzbDrone host.
#ndHost=localhost
# NzbDrone port.
#ndPort=8989
# NzbDrone API key.
#ndAPIKey=
# NzbDrone uses SSL (0, 1).
#
# Set to 1 if using SSL, else set to 0.
#ndSSL=0
# NzbDrone web root.
#
# set this if using a reverse proxy.
#ndWebRoot=
# Prefer NzbDrone if categories clash (0, 1).
#ndPrefer=0
## HeadPhones
# HeadPhones script category.
@ -287,58 +316,24 @@ from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_
# post-processing
def process(nzbDir, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None):
if inputCategory in sections["CouchPotato"]:
if isinstance(nzbDir, list):
for dirName in nzbDir:
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
result = autoProcessMovie().process(dirName, dirName, status, clientAgent, download_id, inputCategory)
if result != 0:
return result
else:
if section in ["CouchPotato"]:
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
return autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory)
elif inputCategory in sections["SickBeard"]:
if isinstance(nzbDir, list):
for dirName in nzbDir:
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
result = autoProcessTV().processEpisode(dirName, dirName, status, clientAgent, inputCategory)
if result !=0:
return result
else:
elif section in ["SickBeard", "NzbDrone"]:
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
return autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
elif inputCategory in sections["HeadPhones"]:
if isinstance(nzbDir, list):
for dirName in nzbDir:
Logger.info("MAIN: Calling Headphones to post-process: %s", dirName)
result = autoProcessMusic().process(dirName, dirName, status, clientAgent, inputCategory)
if result != 0:
return result
else:
elif section in ["HeadPhones"]:
Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName)
return autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory)
elif inputCategory in sections["Mylar"]:
if isinstance(nzbDir, list):
for dirName in nzbDir:
Logger.info("MAIN: Calling Mylar to post-process: %s", dirName)
result = autoProcessComics().processEpisode(dirName, dirName, status, clientAgent, inputCategory)
if result != 0:
return result
else:
elif section in ["Mylar"]:
Logger.info("MAIN: Calling Mylar to post-process: %s", inputName)
return autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
elif inputCategory in sections["Gamez"]:
if isinstance(nzbDir, list):
for dirName in nzbDir:
Logger.info("MAIN: Calling Gamez to post-process: %s", dirName)
result = autoProcessGames().process(dirName, dirName, status, clientAgent, inputCategory)
if result != 0:
return result
else:
elif section in ["Gamez"]:
Logger.info("MAIN: Calling Gamez to post-process: %s", inputName)
return autoProcessGames().process(nzbDir, inputName, status, clientAgent, inputCategory)
else:
Logger.warning("MAIN: The download category %s does not match any category defined in autoProcessMedia.cfg. Exiting.", inputCategory)
Logger.warning("MAIN: We could not find the section %s with a download category of %s in your autoProcessMedia.cfg. Exiting.", section, inputCategory)
return -1
########################################################################################################################
@ -360,9 +355,6 @@ else:
print("Unable to find " + config.CONFIG_FILE + " or " + config.SAMPLE_CONFIG_FILE)
sys.exit(-1)
# setup sections and categories
sections = config.get_sections(["CouchPotato","SickBeard","HeadPhones","Mylar","Gamez"])
WakeUp()
# Post-Processing Result
@ -450,15 +442,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
else:
result = 0
# init sub-sections
subsections = config.get_subsections(["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"])
Logger.warn("MAIN: Invalid number of arguments received from client.")
for section, categories in sections.items():
for category in categories:
for section, subsection in subsections.items():
for category in subsection:
dirNames = get_dirnames(section, category)
Logger.info("MAIN: Running " + section + ":" + category + " as a manual run...")
results = process(dirNames, inputName=dirNames, status=0, inputCategory=category, clientAgent = "manual")
for dirName in dirNames:
Logger.info("MAIN: nzbToMedia running %s:%s as a manual run...", section, subsection)
results = process(dirName, inputName=os.path.basename(dirName), status=0, clientAgent="manual",
inputCategory=category)
if results != 0:
result = results
Logger.info("MAIN: A problem was reported when trying to manually run " + section + ":" + category + ".")
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, subsection)
if result == 0:
Logger.info("MAIN: The nzbToMedia script completed successfully.")

View file

@ -87,9 +87,6 @@ if config.migrate():
else:
sys.exit(-1)
# mylar category
sections = config.get_sections(["Mylar"])
WakeUp()
# NZBGet V11+
@ -167,16 +164,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
else:
result = 0
Logger.warn("MAIN: Invalid number of arguments received from client.")
Logger.info("MAIN: Running autoProcessComics as a manual run...")
# init sub-sections
subsections = config.get_subsections(["Mylar"])
for section, categories in sections.items():
for category in categories:
Logger.warn("MAIN: Invalid number of arguments received from client.")
for section, subsection in subsections.items():
for category in subsection:
dirNames = get_dirnames(section, category)
for dirName in dirNames:
Logger.info("MAIN: Calling " + section + ":" + category + " to post-process: %s", dirName)
results = autoProcessComics().processEpisode(dirName, dirName, 0, inputCategory=category)
if results != 0:result = results
Logger.info("MAIN: nzbToMylar running %s:%s as a manual run...", section, subsection)
results = autoProcessComics(dirName, inputName=os.path.basename(dirName), status=0, clientAgent="manual",
inputCategory=category)
if results != 0:
result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, subsection)
if result == 0:
Logger.info("MAIN: The autoProcessComics script completed successfully.")

221
nzbToNzbDrone.py Executable file
View file

@ -0,0 +1,221 @@
#!/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 ###
# Post-Process to NzbDrone.
#
# This script sends the download to your automated media management servers.
#
# NOTE: This script requires Python to be installed on your system.
##############################################################################
### OPTIONS ###
## NzbDrone
# NzbDrone script category.
#
# category that gets called for post-processing with NzbDrone.
#ndCategory=tv
# NzbDrone host.
#ndHost=localhost
# NzbDrone port.
#ndPort=8989
# NzbDrone API key.
#ndAPIKey=
# NzbDrone uses SSL (0, 1).
#
# Set to 1 if using SSL, else set to 0.
#ndSSL=0
# NzbDrone web root.
#
# set this if using a reverse proxy.
#ndWebRoot=
## Extensions
# Media Extensions
#
# This is a list of media extensions that are used to verify that the download does contain valid media.
#mediaExtensions=.mkv,.avi,.divx,.xvid,.mov,.wmv,.mp4,.mpg,.mpeg,.vob,.iso
## Transcoder
# Transcode (0, 1).
#
# set to 1 to transcode, otherwise set to 0.
#transcode=0
# create a duplicate, or replace the original (0, 1).
#
# set to 1 to cretae a new file or 0 to replace the original
#duplicate=1
# ignore extensions
#
# list of extensions that won't be transcoded.
#ignoreExtensions=.avi,.mkv
# ffmpeg output settings.
#outputVideoExtension=.mp4
#outputVideoCodec=libx264
#outputVideoPreset=medium
#outputVideoFramerate=24
#outputVideoBitrate=800k
#outputAudioCodec=libmp3lame
#outputAudioBitrate=128k
#outputSubtitleCodec=
## WakeOnLan
# use WOL (0, 1).
#
# set to 1 to send WOL broadcast to the mac and test the server (e.g. xbmc) on the host and port specified.
#wolwake=0
# WOL MAC
#
# enter the mac address of the system to be woken.
#wolmac=00:01:2e:2D:64:e1
# Set the Host and Port of a server to verify system has woken.
#wolhost=192.168.1.37
#wolport=80
### NZBGET POST-PROCESSING SCRIPT ###
##############################################################################
import logging
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
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("nzbToNzbDrone %s", config.NZBTOMEDIA_VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
WakeUp()
# NZBGet V11+
# 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':
Logger.info("MAIN: Script triggered from NZBGet (11.0 or later).")
# Check nzbget.conf options
status = 0
if os.environ['NZBOP_UNPACK'] != 'yes':
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
# Check par status
if os.environ['NZBPP_PARSTATUS'] == '3':
Logger.warning("MAIN: Par-check successful, but Par-repair disabled, exiting")
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
sys.exit(config.NZBGET_POSTPROCESS_NONE)
if os.environ['NZBPP_PARSTATUS'] == '1' or os.environ['NZBPP_PARSTATUS'] == '4':
Logger.warning("MAIN: Par-repair failed, setting status \"failed\"")
status = 1
# Check unpack status
if os.environ['NZBPP_UNPACKSTATUS'] == '1':
Logger.warning("MAIN: Unpack failed, setting status \"failed\"")
status = 1
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
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.info("MAIN: Please check your Par-check/repair settings for future downloads.")
status = 1
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.info("MAIN: Please check your Par-check/repair settings for future downloads.")
# Check if destination directory exists (important for reprocessing of history items)
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'])
status = 1
# All checks done, now launching the script.
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessTV...")
clientAgent = "nzbget"
result = autoProcessTV().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], status, clientAgent, os.environ['NZBPP_CATEGORY'])
# SABnzbd Pre 0.7.17
elif len(sys.argv) == config.SABNZB_NO_OF_ARGUMENTS:
# SABnzbd argv:
# 1 The final directory of the job (full path)
# 2 The original name of the NZB file
# 3 Clean version of the job name (no path info and ".nzb" removed)
# 4 Indexer's report number (if supported)
# 5 User-defined category
# 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
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessTV...")
clientAgent = "sabnzbd"
result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
# SABnzbd 0.7.17+
elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
# SABnzbd argv:
# 1 The final directory of the job (full path)
# 2 The original name of the NZB file
# 3 Clean version of the job name (no path info and ".nzb" removed)
# 4 Indexer's report number (if supported)
# 5 User-defined category
# 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
# 8 Failure URL
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessTV...")
clientAgent = "sabnzbd"
result = autoProcessTV().processEpisode(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent, sys.argv[5])
else:
result = 0
# init sub-sections
subsections = config.get_subsections(["CouchPotato", "SickBeard", "NzbDrone", "HeadPhones", "Mylar", "Gamez"])
Logger.warn("MAIN: Invalid number of arguments received from client.")
for section, subsection in subsections.items():
for category in subsection:
dirNames = get_dirnames(section, category)
for dirName in dirNames:
Logger.info("MAIN: nzbToNzbDrone running %s:%s as a manual run...", section, subsection)
results = autoProcessTV(dirName, inputName=os.path.basename(dirName), status=0, clientAgent="manual",
inputCategory=category)
if results != 0:
result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, subsection)
if result == 0:
Logger.info("MAIN: The autoProcessTV script completed successfully.")
if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS)
else:
Logger.info("MAIN: A problem was reported in the autoProcessTV script.")
if os.environ.has_key('NZBOP_SCRIPTDIR'): # return code for nzbget v11
sys.exit(config.NZBGET_POSTPROCESS_ERROR)

View file

@ -149,9 +149,6 @@ if config.migrate():
else:
sys.exit(-1)
# sickbeard category
sections = config.get_sections(["SickBeard"])
WakeUp()
# NZBGet V11+
@ -232,16 +229,20 @@ elif len(sys.argv) >= config.SABNZB_0717_NO_OF_ARGUMENTS:
else:
result = 0
Logger.debug("MAIN: Invalid number of arguments received from client.")
Logger.info("MAIN: Running autoProcessTV as a manual run...")
# init sub-sections
subsections = config.get_subsections(["SickBeard", "NzbDrone"])
for section, categories in sections.items():
for category in categories:
Logger.warn("MAIN: Invalid number of arguments received from client.")
for section, subsection in subsections.items():
for category in subsection:
dirNames = get_dirnames(section, category)
for dirName in dirNames:
Logger.info("MAIN: Calling " + section + ":" + category + " to post-process: %s", dirName)
results = autoProcessTV().processEpisode(dirName, dirName, 0, inputCategory=category)
if results != 0:result = results
Logger.info("MAIN: nzbTo%s running %s:%s as a manual run...", section, section, subsection)
results = autoProcessTV(dirName, inputName=os.path.basename(dirName), status=0, clientAgent="manual",
inputCategory=category)
if results != 0:
result = results
Logger.info("MAIN: A problem was reported when trying to manually run %s:%s.", section, subsection)
if result == 0:
Logger.info("MAIN: The autoProcessTV script completed successfully.")

View file

@ -14,11 +14,22 @@ class autoProcessComics:
Logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section
section = [x for x in config.issubsection(inputCategory) if config()[x][inputCategory]['enabled'] == 1]
if len(section) > 1:
Logger.error(
"MAIN: You can't have multiple sub-sections with the same name enabled, fix your autoProcessMedia.cfg file.")
return 1
elif len(section) == 0:
Logger.error(
"MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory)
return 1
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
Logger.info("Loading config from %s", config.CONFIG_FILE)
section = "Mylar"
host = config()[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"]
username = config()[section][inputCategory]["username"]

View file

@ -13,13 +13,24 @@ class autoProcessGames:
Logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section
section = [x for x in config.issubsection(inputCategory) if config()[x][inputCategory]['enabled'] == 1]
if len(section) > 1:
Logger.error(
"MAIN: You can't have multiple sub-sections with the same name enabled, fix your autoProcessMedia.cfg file.")
return 1
elif len(section) == 0:
Logger.error(
"MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory)
return 1
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(status)
section = "Gamez"
host = config()[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"]
apikey = config()[section][inputCategory]["apikey"]

View file

@ -165,12 +165,22 @@ class autoProcessMovie:
Logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section
section = [x for x in config.issubsection(inputCategory) if config()[x][inputCategory]['enabled'] == 1]
if len(section) > 1:
Logger.error(
"MAIN: You can't have multiple sub-sections with the same name enabled, fix your autoProcessMedia.cfg file.")
return 1
elif len(section) == 0:
Logger.error(
"MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory)
return 1
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(status)
section = "CouchPotato"
host = config()[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"]
apikey = config()[section][inputCategory]["apikey"]
@ -178,6 +188,7 @@ class autoProcessMovie:
method = config()[section][inputCategory]["method"]
delete_failed = int(config()[section][inputCategory]["delete_failed"])
wait_for = int(config()[section][inputCategory]["wait_for"])
try:
TimePerGiB = int(config()[section][inputCategory]["TimePerGiB"])
except:

View file

@ -14,13 +14,23 @@ class autoProcessMusic:
Logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section
section = [x for x in config.issubsection(inputCategory) if config()[x][inputCategory]['enabled'] == 1]
if len(section) > 1:
Logger.error(
"MAIN: You can't have multiple sub-sections with the same name enabled, fix your autoProcessMedia.cfg file.")
return 1
elif len(section) == 0:
Logger.error(
"MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory)
return 1
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(status)
section = "HeadPhones"
host = config()[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"]
apikey = config()[section][inputCategory]["apikey"]

View file

@ -14,18 +14,34 @@ from nzbtomedia.nzbToMediaUtil import convert_to_ascii, is_sample, flatten, getD
Logger = logging.getLogger()
class autoProcessTV:
def processEpisode(self, dirName, nzbName=None, failed=False, clientAgent = "manual", inputCategory=None):
def processEpisode(self, dirName, nzbName=None, failed=False, clientAgent = "manual", section=None, inputCategory=None):
if dirName is None:
Logger.error("No directory was given!")
return 1 # failure
# auto-detect correct section
section = [x for x in config.issubsection(inputCategory) if config()[x][inputCategory]['enabled'] == 1]
if len(section) > 1:
Logger.error(
"MAIN: You can't have multiple sub-sections with the same name enabled, fix your autoProcessMedia.cfg file.")
return 1
elif len(section) == 0:
Logger.error(
"MAIN: We were unable to find a processor for category %s that was enabled, please check your autoProcessMedia.cfg file.", inputCategory)
return 1
fork, fork_params = autoFork(section, inputCategory)
Torrent_NoLink = int(config()[section][inputCategory]["Torrent_NoLink"]) # 0
if not fork in config.SICKBEARD_TORRENT and not Torrent_NoLink == 1:
if clientAgent in ['utorrent', 'transmission', 'deluge']:
return 1
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(failed)
section = "SickBeard"
host = config()[section][inputCategory]["host"]
port = config()[section][inputCategory]["port"]
username = config()[section][inputCategory]["username"]
@ -90,9 +106,6 @@ class autoProcessTV:
if os.path.isdir(SpecificPath):
dirName = SpecificPath
# auto-detect fork type
fork, params = autoFork(section, inputCategory)
if fork not in config.SICKBEARD_TORRENT or (clientAgent in ['nzbget','sabnzbd'] and nzbExtractionBy != "Destination"):
if nzbName:
process_all_exceptions(nzbName.lower(), dirName)

View file

@ -1,7 +1,8 @@
import logging
import os
import shutil
from itertools import chain
from lib import configobj
from itertools import chain
class config(object):
# constants for nzbtomedia
@ -37,140 +38,174 @@ class config(object):
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")
def __new__(cls, *config_file):
try:
# load config
if not config_file:
return configobj.ConfigObj(cls.CONFIG_FILE)
return configobj.ConfigObj(cls.CONFIG_FILE, interpolation=False)
else:
return configobj.ConfigObj(*config_file)
return configobj.ConfigObj(*config_file, interpolation=False)
except Exception, e:
return
@staticmethod
def get_sections(section):
sections = {}
def issubsection(subsection, sections=None):
if not sections:
sections = config.__get_sections(subsection)
if not isinstance(sections, list):
sections = [sections]
results = set()
for section in sections:
if config()[section].has_key(subsection):
results.add(section)
return results if results.issubset(sections) else False
@staticmethod
def __get_sections(subsections):
# check and return categories if section does exist
if not isinstance(section, list):
section = [section]
if not isinstance(subsections, list):
subsections = [subsections]
for x in section:
if config().has_key(x):
sections.update({x: config()[x].sections})
return sections
to_return = []
for subsection in subsections:
for section in config().sections:
if config()[section].has_key(subsection):
to_return.append(section)
return to_return
@staticmethod
def get_subsections(sections):
# check and return categories if section does exist
if not isinstance(sections, list):
sections = [sections]
to_return = {}
for section in sections:
if section in config().sections:
for subsection in config()[section].sections:
if not isinstance(subsection, list):
subsection = [subsection]
to_return.update({section: subsection})
return to_return
@staticmethod
def migrate():
categories = {}
confignew = None
configold = None
global config_new, config_old
config_new = config_old = None
try:
# check for autoProcessMedia.cfg and create if it does not exist
if not config(config.CONFIG_FILE):
shutil.copyfile(config.SAMPLE_CONFIG_FILE, config.CONFIG_FILE)
configold = config(config.CONFIG_FILE)
except:pass
config_old = config(config.CONFIG_FILE)
except:
pass
try:
# check for autoProcessMedia.cfg.sample and create if it does not exist
if not config(config.SAMPLE_CONFIG_FILE):
shutil.copyfile(config.CONFIG_FILE, config.SAMPLE_CONFIG_FILE)
confignew = config(config.SAMPLE_CONFIG_FILE)
except:pass
config_new = config(config.SAMPLE_CONFIG_FILE)
except:
pass
# check for autoProcessMedia.cfg and autoProcessMedia.cfg.sample and if they don't exist return and fail
if not config() and not config(config.SAMPLE_CONFIG_FILE) or not confignew or not configold:
if not config() and not config(config.SAMPLE_CONFIG_FILE) or not config_new or not config_old:
return False
for section in configold.sections:
for option, value in configold[section].items():
if section == "CouchPotato":
if option == "category": # change this old format
option = "cpsCategory"
if section == "SickBeard":
if option == "category": # change this old format
option = "sbCategory"
if option in ["cpsCategory","sbCategory","hpCategory","mlCategory","gzCategory"]:
subsections = {}
# gather all new-style and old-style sub-sections
for newsection, newitems in config_new.iteritems():
if config_new[newsection].sections:
subsections.update({newsection: config_new[newsection].sections})
for section, items in config_old.iteritems():
if config_old[section].sections:
subsections.update({section: config_old[section].sections})
for option, value in config_old[section].items():
if option in ["category", "cpsCategory", "sbCategory", "hpCategory", "mlCategory", "gzCategory"]:
if not isinstance(value, list):
value = [value]
categories.update({section: value})
# add subsection
subsections.update({section: value})
config_old[section].pop(option)
continue
try:
for section in configold.sections:
subsection = None
if section in list(chain.from_iterable(categories.values())):
subsection = section
section = ''.join([k for k, v in categories.iteritems() if subsection in v])
elif section in categories.keys():
subsection = categories[section][0]
# create subsection if it does not exist
if subsection and subsection not in confignew[section].sections:
confignew[section][subsection] = {}
for option, value in configold[section].items():
if section == "CouchPotato":
if option == "outputDirectory": # move this to new location format
value = os.path.split(os.path.normpath(value))[0]
confignew['Torrent'][option] = value
continue
if option in ["username", "password"]: # these are no-longer needed.
continue
if option in ["category","cpsCategory"]:
continue
if section == "SickBeard":
def cleanup_values(values, section):
for option, value in values.iteritems():
if section in ['CouchPotato']:
if option == ['outputDirectory']:
config_new['Torrent'][option] = os.path.split(os.path.normpath(value))[0]
values.pop(option)
if section in ['CouchPotato', 'HeadPhones', 'Gamez']:
if option in ['username', 'password']:
values.pop(option)
if section in ["SickBeard", "NzbDrone"]:
if option == "wait_for": # remove old format
continue
values.pop(option)
if option == "failed_fork": # change this old format
option = "fork"
value = "auto"
values['failed'] = 'auto'
values.pop(option)
if option == "Torrent_ForceLink":
continue
values['Torrent_NoLink'] = value
values.pop(option)
if option == "outputDirectory": # move this to new location format
value = os.path.split(os.path.normpath(value))[0]
confignew['Torrent'][option] = value
continue
if option in ["category", "sbCategory"]:
continue
if section == "HeadPhones":
if option in ["username", "password" ]:
continue
if option == "hpCategory":
continue
if section == "Mylar":
if option in "mlCategory":
continue
if section == "Gamez":
if option in ["username", "password"]: # these are no-longer needed.
continue
if option == "gzCategory":
continue
if section == "Torrent":
config_new['Torrent'][option] = os.path.split(os.path.normpath(value))[0]
values.pop(option)
if section in ["Torrent"]:
if option in ["compressedExtensions", "mediaExtensions", "metaExtensions", "minSampleSize"]:
section = "Extensions" # these were moved
config_new['Extensions'][option] = value
values.pop(option)
if option == "useLink": # Sym links supported now as well.
if isinstance(value, int):
num_value = int(value)
if num_value == 1:
value = "hard"
value = 'hard'
else:
value = "no"
value = 'no'
return values
if subsection:
confignew[section][subsection][option] = value
def process_section(section, subsections=None):
if subsections:
for subsection in subsections:
if subsection in config_old.sections:
values = config_old[subsection]
if subsection not in config_new[section].sections:
config_new[section][subsection] = {}
for option, value in values.items():
config_new[section][subsection][option] = value
elif subsection in config_old[section].sections:
values = config_old[section][subsection]
if subsection not in config_new[section].sections:
config_new[section][subsection] = {}
for option, value in values.items():
config_new[section][subsection][option] = value
else:
confignew[section][option] = value
except:pass
values = config_old[section]
if section not in config_new.sections:
config_new[section] = {}
for option, value in values.items():
config_new[section][option] = value
# convert old-style categories to new-style sub-sections
for section in config_old.keys():
subsection = None
if section in list(chain.from_iterable(subsections.values())):
subsection = section
section = ''.join([k for k,v in subsections.iteritems() if subsection in v])
process_section(section, subsection)
#[[v.remove(c) for c in v if c in subsection] for k, v in subsections.items() if k == section]
elif section in subsections.keys():
subsection = subsections[section]
process_section(section, subsection)
#[[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():
process_section(section, subsection)
# create a backup of our old config
if os.path.isfile(config.CONFIG_FILE):
@ -181,13 +216,13 @@ class config(object):
# writing our configuration file to 'autoProcessMedia.cfg'
with open(config.CONFIG_FILE, 'wb') as configFile:
confignew.write(configFile)
config_new.write(configFile)
return True
@staticmethod
def addnzbget():
confignew = config()
config_new = config()
section = "CouchPotato"
envCatKey = 'NZBPO_CPSCATEGORY'
envKeys = ['APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT', 'DELAY', 'METHOD', 'DELETE_FAILED', 'REMOTECPS', 'WAIT_FOR', 'TIMEPERGIB']
@ -198,9 +233,9 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
if os.environ[envCatKey] not in confignew[section].sections:
confignew[section][os.environ[envCatKey]] = {}
confignew[section][os.environ[envCatKey]][option] = value
if os.environ[envCatKey] not in config_new[section].sections:
config_new[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value
section = "SickBeard"
envCatKey = 'NZBPO_SBCATEGORY'
@ -212,9 +247,9 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
if os.environ[envCatKey] not in confignew[section].sections:
confignew[section][os.environ[envCatKey]] = {}
confignew[section][os.environ[envCatKey]][option] = value
if os.environ[envCatKey] not in config_new[section].sections:
config_new[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value
section = "HeadPhones"
envCatKey = 'NZBPO_HPCATEGORY'
@ -226,9 +261,9 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
if os.environ[envCatKey] not in confignew[section].sections:
confignew[section][os.environ[envCatKey]] = {}
confignew[section][os.environ[envCatKey]][option] = value
if os.environ[envCatKey] not in config_new[section].sections:
config_new[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value
section = "Mylar"
envCatKey = 'NZBPO_MYCATEGORY'
@ -240,9 +275,9 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
if os.environ[envCatKey] not in confignew[section].sections:
confignew[section][os.environ[envCatKey]] = {}
confignew[section][os.environ[envCatKey]][option] = value
if os.environ[envCatKey] not in config_new[section].sections:
config_new[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value
section = "Gamez"
envCatKey = 'NZBPO_GZCATEGORY'
@ -254,9 +289,9 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
if os.environ[envCatKey] not in confignew[section].sections:
confignew[section][os.environ[envCatKey]] = {}
confignew[section][os.environ[envCatKey]][option] = value
if os.environ[envCatKey] not in config_new[section].sections:
config_new[section][os.environ[envCatKey]] = {}
config_new[section][os.environ[envCatKey]][option] = value
section = "Extensions"
envKeys = ['COMPRESSEDEXTENSIONS', 'MEDIAEXTENSIONS', 'METAEXTENSIONS']
@ -266,7 +301,7 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
confignew[section][option] = value
config_new[section][option] = value
section = "Transcoder"
envKeys = ['TRANSCODE', 'DUPLICATE', 'IGNOREEXTENSIONS', 'OUTPUTVIDEOEXTENSION', 'OUTPUTVIDEOCODEC', 'OUTPUTVIDEOPRESET', 'OUTPUTVIDEOFRAMERATE', 'OUTPUTVIDEOBITRATE', 'OUTPUTAUDIOCODEC', 'OUTPUTAUDIOBITRATE', 'OUTPUTSUBTITLECODEC']
@ -276,7 +311,7 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
confignew[section][option] = value
config_new[section][option] = value
section = "WakeOnLan"
envKeys = ['WAKE', 'HOST', 'PORT', 'MAC']
@ -286,7 +321,7 @@ class config(object):
if os.environ.has_key(key):
option = cfgKeys[index]
value = os.environ[key]
confignew[section][option] = value
config_new[section][option] = value
# create a backup of our old config
if os.path.isfile(config.CONFIG_FILE):
@ -297,4 +332,4 @@ class config(object):
# writing our configuration file to 'autoProcessMedia.cfg'
with open(config.CONFIG_FILE, 'wb') as configFile:
confignew.write(configFile)
config_new.write(configFile)

View file

@ -51,6 +51,9 @@ def create_destination(outputDestination):
sys.exit(-1)
def category_search(inputDirectory, inputName, inputCategory, root, categories):
if inputDirectory is None:
return inputDirectory, inputName, inputCategory, root
if not os.path.isdir(inputDirectory) and os.path.isfile(inputDirectory): # If the input directory is a file, assume single file downlaod and split dir/name.
inputDirectory,inputName = os.path.split(os.path.normpath(inputDirectory))
@ -327,14 +330,13 @@ def TestCon(host, port):
def WakeUp():
if not config():
Logger.error("You need an autoProcessMedia.config() file - did you rename and edit the .sample?")
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
return
wake = int(config()["WakeOnLan"]["wake"])
if wake == 0: # just return if we don't need to wake anything.
return
Logger.info("Loading WakeOnLan config from %s", config.CONFIG_FILE)
config()["WakeOnLan"]["host"]
host = config()["WakeOnLan"]["host"]
port = int(config()["WakeOnLan"]["port"])
mac = config()["WakeOnLan"]["mac"]
@ -376,6 +378,7 @@ def convert_to_ascii(nzbName, dirName):
return nzbName, dirName
def parse_other(args):
return os.path.normpath(args[1]), '', '', '', ''
def parse_rtorrent(args):
@ -449,40 +452,49 @@ def parse_args(clientAgent):
'transmission': parse_transmission,
}
try:
return clients[clientAgent](sys.argv)
except:return None, None, None, None, None
def get_dirnames(section, inputCategory):
def get_dirnames(section, subsections=None):
dirNames = []
if subsections is None:
subsections = config.get_subsections(section).values()
if not isinstance(subsections, list):
subsections = [subsections]
for subsection in subsections:
try:
watch_dir = config()[section][inputCategory]["watch_dir"]
watch_dir = config()[section][subsection]["watch_dir"]
if not os.path.exists(watch_dir):
watch_dir = ""
watch_dir = None
except:
watch_dir = ""
watch_dir = None
try:
outputDirectory = os.path.join(config()["Torrent"]["outputDirectory"], inputCategory)
if not os.path.exists(watch_dir):
outputDirectory = ""
outputDirectory = os.path.join(config()["Torrent"]["outputDirectory"], subsection)
if not os.path.exists(outputDirectory):
outputDirectory = None
except:
outputDirectory = ""
outputDirectory = None
if watch_dir != "":
if watch_dir:
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))])
if not dirNames:
Logger.warn("No Directories identified to Scan inside " + watch_dir)
Logger.warn("%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
os.path.isdir(os.path.join(outputDirectory, o))])
if not dirNames:
Logger.warn("No Directories identified to Scan inside " + outputDirectory)
Logger.warn("%s:%s has no directories identified to scan inside %s", section, subsection, outputDirectory)
if watch_dir == "" and outputDirectory == "":
Logger.warn("No watch_dir or outputDirectory setup to be Scanned, go fix you autoProcessMedia.cfg file.")
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)
return dirNames