mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2025-07-14 01:02:55 -07:00
Major overhaul of nzbToMedia code base plus a whole restrucure
This commit is contained in:
parent
e7751b96c5
commit
85d8739512
67 changed files with 1687 additions and 1734 deletions
19
DeleteSamples.py
Executable file → Normal file
19
DeleteSamples.py
Executable file → Normal file
|
@ -29,9 +29,9 @@
|
||||||
|
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
|
||||||
|
|
||||||
def is_sample(filePath, inputName, maxSampleSize, SampleIDs):
|
def is_sample(filePath, inputName, maxSampleSize, SampleIDs):
|
||||||
|
@ -53,25 +53,18 @@ def is_sample(filePath, inputName, maxSampleSize, SampleIDs):
|
||||||
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':
|
||||||
print "Script triggered from NZBGet (11.0 or later)."
|
print "Script triggered from NZBGet (11.0 or later)."
|
||||||
|
|
||||||
# NZBGet argv: all passed as environment variables.
|
|
||||||
# Exit codes used by NZBGet
|
|
||||||
POSTPROCESS_PARCHECK=92
|
|
||||||
POSTPROCESS_SUCCESS=93
|
|
||||||
POSTPROCESS_ERROR=94
|
|
||||||
POSTPROCESS_NONE=95
|
|
||||||
|
|
||||||
# Check nzbget.conf options
|
# Check nzbget.conf options
|
||||||
status = 0
|
status = 0
|
||||||
|
|
||||||
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(POSTPROCESS_ERROR)
|
sys.exit(config.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(POSTPROCESS_NONE)
|
sys.exit(config.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\"."
|
||||||
|
@ -102,7 +95,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(POSTPROCESS_NONE)
|
sys.exit(config.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(',')
|
||||||
|
@ -119,8 +112,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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
||||||
sys.exit(POSTPROCESS_SUCCESS)
|
sys.exit(config.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)."
|
||||||
|
|
24
ResetDateTime.py
Executable file → Normal file
24
ResetDateTime.py
Executable file → Normal file
|
@ -13,33 +13,27 @@
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# 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
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
|
||||||
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':
|
||||||
print "Script triggered from NZBGet (11.0 or later)."
|
print "Script triggered from NZBGet (11.0 or later)."
|
||||||
|
|
||||||
# NZBGet argv: all passed as environment variables.
|
|
||||||
# Exit codes used by NZBGet
|
|
||||||
POSTPROCESS_PARCHECK=92
|
|
||||||
POSTPROCESS_SUCCESS=93
|
|
||||||
POSTPROCESS_ERROR=94
|
|
||||||
POSTPROCESS_NONE=95
|
|
||||||
|
|
||||||
# Check nzbget.conf options
|
# Check nzbget.conf options
|
||||||
status = 0
|
status = 0
|
||||||
|
|
||||||
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(POSTPROCESS_ERROR)
|
sys.exit(config.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(POSTPROCESS_NONE)
|
sys.exit(config.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\"."
|
||||||
|
@ -70,7 +64,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(POSTPROCESS_NONE)
|
sys.exit(config.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):
|
||||||
|
@ -82,8 +76,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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
||||||
sys.exit(POSTPROCESS_SUCCESS)
|
sys.exit(config.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)."
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
#System imports
|
|
||||||
import logging
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
from subprocess import Popen
|
from subprocess import Popen
|
||||||
|
from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics
|
||||||
# Custom imports
|
from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames
|
||||||
import autoProcess.migratecfg as migratecfg
|
from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie
|
||||||
import extractor.extractor as extractor
|
from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic
|
||||||
import autoProcess.autoProcessComics as autoProcessComics
|
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
|
||||||
import autoProcess.autoProcessGames as autoProcessGames
|
from nzbtomedia.extractor import extractor
|
||||||
import autoProcess.autoProcessMusic as autoProcessMusic
|
from nzbtomedia.migratecfg import migratecfg
|
||||||
import autoProcess.autoProcessMovie as autoProcessMovie
|
from nzbtomedia.nzbToMediaAutoFork import autoFork
|
||||||
import autoProcess.autoProcessTV as autoProcessTV
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
from autoProcess.nzbToMediaEnv import *
|
from nzbtomedia.nzbToMediaUtil import category_search, safeName, is_sample, copy_link, WakeUp, parse_args, flatten, \
|
||||||
from autoProcess.nzbToMediaUtil import *
|
nzbtomedia_configure_logging
|
||||||
from autoProcess.autoSickBeardFork import autoFork
|
from nzbtomedia.synchronousdeluge.client import DelugeClient
|
||||||
from utorrent.client import UTorrentClient
|
from nzbtomedia.utorrent.client import UTorrentClient
|
||||||
from transmissionrpc.client import Client as TransmissionClient
|
from nzbtomedia.transmissionrpc.client import Client as TransmissionClient
|
||||||
from synchronousdeluge.client import DelugeClient
|
|
||||||
|
|
||||||
def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
|
|
||||||
|
@ -31,6 +32,14 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
extractionSuccess = False
|
extractionSuccess = False
|
||||||
copy_list = []
|
copy_list = []
|
||||||
useLink = useLink_in
|
useLink = useLink_in
|
||||||
|
file = None
|
||||||
|
|
||||||
|
delugeClient = ""
|
||||||
|
utorrentClass = ""
|
||||||
|
TransmissionClass = ""
|
||||||
|
|
||||||
|
# init autoFork
|
||||||
|
fork, fork_params = autoFork(inputCategory)
|
||||||
|
|
||||||
Logger.debug("MAIN: Received Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory)
|
Logger.debug("MAIN: Received Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory)
|
||||||
|
|
||||||
|
@ -38,12 +47,11 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
|
|
||||||
Logger.debug("MAIN: Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory)
|
Logger.debug("MAIN: Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory)
|
||||||
|
|
||||||
sbFork, sbParams = autoFork()
|
if inputCategory in sbCategory:
|
||||||
|
if fork in config.SICKBEARD_TORRENT and Torrent_ForceLink != 1:
|
||||||
if inputCategory in sbCategory and sbFork in SICKBEARD_TORRENT and Torrent_ForceLink != 1:
|
Logger.info("MAIN: Calling SickBeard's %s branch to post-process: %s",fork ,inputName)
|
||||||
Logger.info("MAIN: Calling SickBeard's %s branch to post-process: %s",sbFork ,inputName)
|
result = autoProcessTV().processEpisode(inputDirectory, inputName, 0)
|
||||||
result = autoProcessTV.processEpisode(inputDirectory, inputName, int(0))
|
if result != 0:
|
||||||
if result == 1:
|
|
||||||
Logger.info("MAIN: A problem was reported in the autoProcess* script.")
|
Logger.info("MAIN: A problem was reported in the autoProcess* script.")
|
||||||
Logger.info("MAIN: All done.")
|
Logger.info("MAIN: All done.")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
@ -91,14 +99,14 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
utorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD)
|
utorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD)
|
||||||
except:
|
except:
|
||||||
Logger.exception("MAIN: Failed to connect to uTorrent")
|
Logger.exception("MAIN: Failed to connect to uTorrent")
|
||||||
utorrentClass = ""
|
|
||||||
if clientAgent == 'transmission':
|
if clientAgent == 'transmission':
|
||||||
try:
|
try:
|
||||||
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, TransmissionHost, TransmissionPort)
|
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, TransmissionHost, TransmissionPort)
|
||||||
TransmissionClass = TransmissionClient(TransmissionHost, TransmissionPort, TransmissionUSR, TransmissionPWD)
|
TransmissionClass = TransmissionClient(TransmissionHost, TransmissionPort, TransmissionUSR, TransmissionPWD)
|
||||||
except:
|
except:
|
||||||
Logger.exception("MAIN: Failed to connect to Transmission")
|
Logger.exception("MAIN: Failed to connect to Transmission")
|
||||||
TransmissionClass = ""
|
|
||||||
if clientAgent == 'deluge':
|
if clientAgent == 'deluge':
|
||||||
try:
|
try:
|
||||||
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, DelugeHost, DelugePort)
|
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, DelugeHost, DelugePort)
|
||||||
|
@ -106,7 +114,6 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
delugeClient.connect(host = DelugeHost, port = DelugePort, username = DelugeUSR, password = DelugePWD)
|
delugeClient.connect(host = DelugeHost, port = DelugePort, username = DelugeUSR, password = DelugePWD)
|
||||||
except:
|
except:
|
||||||
Logger.exception("MAIN: Failed to connect to deluge")
|
Logger.exception("MAIN: Failed to connect to deluge")
|
||||||
delugeClient = ""
|
|
||||||
|
|
||||||
# if we are using links with uTorrent it means we need to pause it in order to access the files
|
# if we are using links with uTorrent it means we need to pause it in order to access the files
|
||||||
Logger.debug("MAIN: Stoping torrent %s in %s while processing", inputName, clientAgent)
|
Logger.debug("MAIN: Stoping torrent %s in %s while processing", inputName, clientAgent)
|
||||||
|
@ -116,7 +123,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
TransmissionClass.stop_torrent(inputID)
|
TransmissionClass.stop_torrent(inputID)
|
||||||
if clientAgent == 'deluge' and delugeClient != "":
|
if clientAgent == 'deluge' and delugeClient != "":
|
||||||
delugeClient.core.pause_torrent([inputID])
|
delugeClient.core.pause_torrent([inputID])
|
||||||
time.sleep(5) # Give Torrent client some time to catch up with the change
|
datetime.time.sleep(5) # Give Torrent client some time to catch up with the change
|
||||||
|
|
||||||
Logger.debug("MAIN: Scanning files in directory: %s", inputDirectory)
|
Logger.debug("MAIN: Scanning files in directory: %s", inputDirectory)
|
||||||
|
|
||||||
|
@ -125,7 +132,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
if useLink in ['sym','move']: # These don't work for HeadPhones.
|
if useLink in ['sym','move']: # These don't work for HeadPhones.
|
||||||
useLink = 'no' # default to copy.
|
useLink = 'no' # default to copy.
|
||||||
|
|
||||||
if inputCategory in sbCategory and sbFork in SICKBEARD_TORRENT: # Don't flatten when sending to SICKBEARD_TORRENT
|
if inputCategory in sbCategory and fork in config.SICKBEARD_TORRENT: # Don't flatten when sending to SICKBEARD_TORRENT
|
||||||
noFlatten.extend(sbCategory)
|
noFlatten.extend(sbCategory)
|
||||||
|
|
||||||
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.
|
||||||
|
@ -167,7 +174,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
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 inputCategory in sbCategory and sbFork in SICKBEARD_TORRENT: # We want to link every file.
|
if inputCategory in sbCategory and fork in config.SICKBEARD_TORRENT: # We want to link every file.
|
||||||
Logger.info("MAIN: Found file %s in %s", fileExtension, filePath)
|
Logger.info("MAIN: Found file %s in %s", fileExtension, filePath)
|
||||||
try:
|
try:
|
||||||
copy_link(filePath, targetDirectory, useLink, outputDestination)
|
copy_link(filePath, targetDirectory, useLink, outputDestination)
|
||||||
|
@ -237,7 +244,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
flatten(outputDestination)
|
flatten(outputDestination)
|
||||||
|
|
||||||
# Now check if movie files exist in destination:
|
# Now check if movie files exist in destination:
|
||||||
if inputCategory in cpsCategory + sbCategory and not (inputCategory in sbCategory and sbFork in SICKBEARD_TORRENT):
|
if inputCategory in cpsCategory + sbCategory and not (inputCategory in sbCategory and fork in config.SICKBEARD_TORRENT):
|
||||||
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)
|
||||||
|
@ -257,7 +264,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
else:
|
else:
|
||||||
Logger.debug("MAIN: Found %s media files in output. %s were found in input", str(video2), str(video))
|
Logger.debug("MAIN: Found %s media files in output. %s were found in input", str(video2), str(video))
|
||||||
|
|
||||||
if inputCategory in sbCategory and sbFork in SICKBEARD_TORRENT:
|
if inputCategory in sbCategory and fork in config.SICKBEARD_TORRENT:
|
||||||
if len(copy_list) > 0:
|
if len(copy_list) > 0:
|
||||||
Logger.debug("MAIN: Found and linked %s files", str(len(copy_list)))
|
Logger.debug("MAIN: Found and linked %s files", str(len(copy_list)))
|
||||||
status = int(0)
|
status = int(0)
|
||||||
|
@ -274,22 +281,23 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
Logger.error("MAIN: Something failed! Please check logs. Exiting")
|
Logger.error("MAIN: Something failed! Please check logs. Exiting")
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
result = 0
|
||||||
if inputCategory in cpsCategory:
|
if inputCategory in cpsCategory:
|
||||||
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
|
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
|
||||||
download_id = inputHash
|
download_id = inputHash
|
||||||
result = autoProcessMovie.process(outputDestination, inputName, status, clientAgent, download_id, inputCategory)
|
result = autoProcessMovie().process(outputDestination, inputName, status, clientAgent, download_id, inputCategory)
|
||||||
elif inputCategory in sbCategory:
|
elif inputCategory in sbCategory:
|
||||||
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
|
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
|
||||||
result = autoProcessTV.processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
|
result = autoProcessTV().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
|
||||||
elif inputCategory in hpCategory:
|
elif inputCategory in hpCategory:
|
||||||
Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName)
|
Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName)
|
||||||
result = autoProcessMusic.process(inputDirectory, inputName, status, inputCategory)
|
result = autoProcessMusic().process(inputDirectory, inputName, status, clientAgent, inputCategory)
|
||||||
elif inputCategory in mlCategory:
|
elif inputCategory in mlCategory:
|
||||||
Logger.info("MAIN: Calling Mylar to post-process: %s", inputName)
|
Logger.info("MAIN: Calling Mylar to post-process: %s", inputName)
|
||||||
result = autoProcessComics.processEpisode(outputDestination, inputName, status, inputCategory)
|
result = autoProcessComics().processEpisode(outputDestination, inputName, status, clientAgent, inputCategory)
|
||||||
elif inputCategory in gzCategory:
|
elif inputCategory in gzCategory:
|
||||||
Logger.info("MAIN: Calling Gamez to post-process: %s", inputName)
|
Logger.info("MAIN: Calling Gamez to post-process: %s", inputName)
|
||||||
result = autoProcessGames.process(outputDestination, inputName, status, inputCategory)
|
result = autoProcessGames().process(outputDestination, inputName, status, 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.info("MAIN: A problem was reported in the autoProcess* script. If torrent was paused we will resume seeding")
|
||||||
|
@ -334,7 +342,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
|
||||||
TransmissionClass.start_torrent(inputID)
|
TransmissionClass.start_torrent(inputID)
|
||||||
if clientAgent == 'deluge' and delugeClient != "":
|
if clientAgent == 'deluge' and delugeClient != "":
|
||||||
delugeClient.core.resume_torrent([inputID])
|
delugeClient.core.resume_torrent([inputID])
|
||||||
time.sleep(5)
|
datetime.time.sleep(5)
|
||||||
#cleanup
|
#cleanup
|
||||||
if inputCategory in processCategories and result == 0 and os.path.isdir(outputDestination):
|
if inputCategory in processCategories and result == 0 and os.path.isdir(outputDestination):
|
||||||
num_files_new = int(0)
|
num_files_new = int(0)
|
||||||
|
@ -411,11 +419,10 @@ def external_script(outputDestination,torrentName,torrentLabel):
|
||||||
result = int(1)
|
result = int(1)
|
||||||
final_result = final_result + result
|
final_result = final_result + result
|
||||||
|
|
||||||
time.sleep(user_delay)
|
datetime.time.sleep(user_delay)
|
||||||
num_files_new = int(0)
|
num_files_new = int(0)
|
||||||
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)
|
||||||
|
|
||||||
|
@ -430,26 +437,19 @@ def external_script(outputDestination,torrentName,torrentLabel):
|
||||||
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.
|
||||||
#check to migrate old cfg before trying to load.
|
if migratecfg().migrate():
|
||||||
if os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample")):
|
nzbtomedia_configure_logging(config.LOG_FILE)
|
||||||
migratecfg.migrate()
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
|
||||||
Logger = logging.getLogger(__name__)
|
Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
Logger.info("====================") # Seperate old from new log
|
Logger.info("====================") # Seperate old from new log
|
||||||
Logger.info("TorrentToMedia %s", VERSION)
|
Logger.info("TorrentToMedia %s", config.NZBTOMEDIA_VERSION)
|
||||||
|
|
||||||
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
|
else:
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
WakeUp()
|
WakeUp()
|
||||||
|
|
||||||
if not config():
|
|
||||||
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
# CONFIG FILE
|
|
||||||
Logger.info("MAIN: Loading config from %s", CONFIG_FILE)
|
|
||||||
# EXAMPLE VALUES:
|
# EXAMPLE VALUES:
|
||||||
clientAgent = config().get("Torrent", "clientAgent") # utorrent | deluge | transmission | rtorrent | other
|
clientAgent = config().get("Torrent", "clientAgent") # utorrent | deluge | transmission | rtorrent | other
|
||||||
useLink_in = config().get("Torrent", "useLink") # no | hard | sym
|
useLink_in = config().get("Torrent", "useLink") # no | hard | sym
|
||||||
|
@ -480,9 +480,10 @@ if __name__ == "__main__":
|
||||||
minSampleSize = int(config().get("Extensions", "minSampleSize")) # 200 (in MB)
|
minSampleSize = int(config().get("Extensions", "minSampleSize")) # 200 (in MB)
|
||||||
SampleIDs = (config().get("Extensions", "SampleIDs")).split(',') # sample,-s.
|
SampleIDs = (config().get("Extensions", "SampleIDs")).split(',') # sample,-s.
|
||||||
|
|
||||||
|
Torrent_ForceLink = int(config().get("SickBeard", "Torrent_ForceLink")) # 1
|
||||||
|
|
||||||
cpsCategory = (config().get("CouchPotato", "cpsCategory")).split(',') # movie
|
cpsCategory = (config().get("CouchPotato", "cpsCategory")).split(',') # movie
|
||||||
sbCategory = (config().get("SickBeard", "sbCategory")).split(',') # tv
|
sbCategory = (config().get("SickBeard", "sbCategory")).split(',') # tv
|
||||||
Torrent_ForceLink = int(config().get("SickBeard", "Torrent_ForceLink")) # 1
|
|
||||||
hpCategory = (config().get("HeadPhones", "hpCategory")).split(',') # music
|
hpCategory = (config().get("HeadPhones", "hpCategory")).split(',') # music
|
||||||
mlCategory = (config().get("Mylar", "mlCategory")).split(',') # comics
|
mlCategory = (config().get("Mylar", "mlCategory")).split(',') # comics
|
||||||
gzCategory = (config().get("Gamez", "gzCategory")).split(',') # games
|
gzCategory = (config().get("Gamez", "gzCategory")).split(',') # games
|
||||||
|
@ -509,10 +510,10 @@ if __name__ == "__main__":
|
||||||
Logger.debug("arg %s is: %s", n, arg)
|
Logger.debug("arg %s is: %s", n, arg)
|
||||||
n = n+1
|
n = n+1
|
||||||
|
|
||||||
try:
|
if not len(sys.argv) > 1:
|
||||||
inputDirectory, inputName, inputCategory, inputHash, inputID = parse_args(clientAgent)
|
|
||||||
except:
|
|
||||||
Logger.exception("MAIN: There was a problem loading variables")
|
Logger.exception("MAIN: There was a problem loading variables")
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# process torrent
|
||||||
|
inputDirectory, inputName, inputCategory, inputHash, inputID = parse_args(clientAgent)
|
||||||
main(inputDirectory, inputName, inputCategory, inputHash, inputID)
|
main(inputDirectory, inputName, inputCategory, inputHash, inputID)
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
import sys
|
|
||||||
import logging
|
|
||||||
import errno
|
|
||||||
from subprocess import call
|
|
||||||
|
|
||||||
from nzbToMediaConfig import *
|
|
||||||
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
|
||||||
|
|
||||||
def Transcode_directory(dirName):
|
|
||||||
|
|
||||||
if os.name == 'nt':
|
|
||||||
ffmpeg = os.path.join(os.path.dirname(sys.argv[0]), 'ffmpeg\\bin\\ffmpeg.exe') # note, will need to package in this dir.
|
|
||||||
useNiceness = False
|
|
||||||
if not os.path.isfile(ffmpeg): # problem
|
|
||||||
Logger.error("ffmpeg not found. ffmpeg needs to be located at: %s", ffmpeg)
|
|
||||||
Logger.info("Cannot transcode files in folder %s", dirName)
|
|
||||||
return 1 # failure
|
|
||||||
else:
|
|
||||||
if call(['which', 'ffmpeg']) != 0:
|
|
||||||
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.
|
|
||||||
Logger.error("Failed to install ffmpeg. Please install manually")
|
|
||||||
Logger.info("Cannot transcode files in folder %s", dirName)
|
|
||||||
return 1 # failure
|
|
||||||
else:
|
|
||||||
ffmpeg = 'ffmpeg'
|
|
||||||
else:
|
|
||||||
ffmpeg = 'ffmpeg'
|
|
||||||
useNiceness = True
|
|
||||||
|
|
||||||
Logger.info("Loading config from %s", CONFIG_FILE)
|
|
||||||
|
|
||||||
if not config():
|
|
||||||
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
mediaContainer = (config().get("Extensions", "mediaExtensions")).split(',')
|
|
||||||
duplicate = int(config().get("Transcoder", "duplicate"))
|
|
||||||
ignoreExtensions = (config().get("Transcoder", "ignoreExtensions")).split(',')
|
|
||||||
outputVideoExtension = config().get("Transcoder", "outputVideoExtension").strip()
|
|
||||||
outputVideoCodec = config().get("Transcoder", "outputVideoCodec").strip()
|
|
||||||
outputVideoPreset = config().get("Transcoder", "outputVideoPreset").strip()
|
|
||||||
outputVideoFramerate = config().get("Transcoder", "outputVideoFramerate").strip()
|
|
||||||
outputVideoBitrate = config().get("Transcoder", "outputVideoBitrate").strip()
|
|
||||||
outputAudioCodec = config().get("Transcoder", "outputAudioCodec").strip()
|
|
||||||
outputAudioBitrate = config().get("Transcoder", "outputAudioBitrate").strip()
|
|
||||||
outputSubtitleCodec = config().get("Transcoder", "outputSubtitleCodec").strip()
|
|
||||||
outputFastStart = int(config().get("Transcoder", "outputFastStart"))
|
|
||||||
outputQualityPercent = int(config().get("Transcoder", "outputQualityPercent"))
|
|
||||||
if useNiceness:
|
|
||||||
niceness = int(config().get("Transcoder", "niceness"))
|
|
||||||
|
|
||||||
map(lambda ext: ext.strip(), mediaContainer)
|
|
||||||
map(lambda ext: ext.strip(), ignoreExtensions)
|
|
||||||
|
|
||||||
Logger.info("Checking for files to be transcoded")
|
|
||||||
final_result = 0 # initialize as successful
|
|
||||||
for dirpath, dirnames, filenames in os.walk(dirName):
|
|
||||||
for file in filenames:
|
|
||||||
filePath = os.path.join(dirpath, file)
|
|
||||||
name, ext = os.path.splitext(filePath)
|
|
||||||
if ext in mediaContainer: # If the file is a video file
|
|
||||||
if ext in ignoreExtensions:
|
|
||||||
Logger.info("No need to transcode video type %s", ext)
|
|
||||||
continue
|
|
||||||
if ext == outputVideoExtension: # we need to change the name to prevent overwriting itself.
|
|
||||||
outputVideoExtension = '-transcoded' + outputVideoExtension # adds '-transcoded.ext'
|
|
||||||
newfilePath = os.path.normpath(name + outputVideoExtension)
|
|
||||||
|
|
||||||
command = [ffmpeg, '-loglevel', 'warning', '-i', filePath, '-map', '0'] # -map 0 takes all input streams
|
|
||||||
|
|
||||||
if useNiceness:
|
|
||||||
command = ['nice', '-%d' % niceness] + command
|
|
||||||
|
|
||||||
if len(outputVideoCodec) > 0:
|
|
||||||
command.append('-c:v')
|
|
||||||
command.append(outputVideoCodec)
|
|
||||||
if outputVideoCodec == 'libx264' and outputVideoPreset:
|
|
||||||
command.append('-preset')
|
|
||||||
command.append(outputVideoPreset)
|
|
||||||
else:
|
|
||||||
command.append('-c:v')
|
|
||||||
command.append('copy')
|
|
||||||
if len(outputVideoFramerate) > 0:
|
|
||||||
command.append('-r')
|
|
||||||
command.append(str(outputVideoFramerate))
|
|
||||||
if len(outputVideoBitrate) > 0:
|
|
||||||
command.append('-b:v')
|
|
||||||
command.append(str(outputVideoBitrate))
|
|
||||||
if len(outputAudioCodec) > 0:
|
|
||||||
command.append('-c:a')
|
|
||||||
command.append(outputAudioCodec)
|
|
||||||
if outputAudioCodec == 'aac': # Allow users to use the experimental AAC codec that's built into recent versions of ffmpeg
|
|
||||||
command.append('-strict')
|
|
||||||
command.append('-2')
|
|
||||||
else:
|
|
||||||
command.append('-c:a')
|
|
||||||
command.append('copy')
|
|
||||||
if len(outputAudioBitrate) > 0:
|
|
||||||
command.append('-b:a')
|
|
||||||
command.append(str(outputAudioBitrate))
|
|
||||||
if outputFastStart > 0:
|
|
||||||
command.append('-movflags')
|
|
||||||
command.append('+faststart')
|
|
||||||
if outputQualityPercent > 0:
|
|
||||||
command.append('-q:a')
|
|
||||||
command.append(str(outputQualityPercent))
|
|
||||||
if len(outputSubtitleCodec) > 0: # Not every subtitle codec can be used for every video container format!
|
|
||||||
command.append('-c:s')
|
|
||||||
command.append(outputSubtitleCodec) # http://en.wikibooks.org/wiki/FFMPEG_An_Intermediate_Guide/subtitle_options
|
|
||||||
else:
|
|
||||||
command.append('-sn') # Don't copy the subtitles over
|
|
||||||
command.append(newfilePath)
|
|
||||||
|
|
||||||
try: # Try to remove the file that we're transcoding to just in case. (ffmpeg will return an error if it already exists for some reason)
|
|
||||||
os.remove(newfilePath)
|
|
||||||
except OSError, e:
|
|
||||||
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)
|
|
||||||
except Exception, e:
|
|
||||||
Logger.debug("Error when removing transcoding target: %s", e)
|
|
||||||
|
|
||||||
Logger.info("Transcoding video: %s", file)
|
|
||||||
cmd = ""
|
|
||||||
for item in command:
|
|
||||||
cmd = cmd + " " + item
|
|
||||||
Logger.debug("calling command:%s", cmd)
|
|
||||||
result = 1 # set result to failed in case call fails.
|
|
||||||
try:
|
|
||||||
result = call(command)
|
|
||||||
except:
|
|
||||||
Logger.exception("Transcoding of video %s has failed", filePath)
|
|
||||||
if result == 0:
|
|
||||||
Logger.info("Transcoding of video %s to %s succeeded", filePath, newfilePath)
|
|
||||||
if duplicate == 0: # we get rid of the original file
|
|
||||||
os.unlink(filePath)
|
|
||||||
else:
|
|
||||||
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.
|
|
||||||
final_result = final_result + result
|
|
||||||
return final_result
|
|
|
@ -1,96 +0,0 @@
|
||||||
import urllib
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from nzbToMediaEnv import *
|
|
||||||
from nzbToMediaUtil import *
|
|
||||||
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
|
||||||
socket.setdefaulttimeout(int(TimeOut)) #initialize socket timeout.
|
|
||||||
|
|
||||||
class AuthURLOpener(urllib.FancyURLopener):
|
|
||||||
def __init__(self, user, pw):
|
|
||||||
self.username = user
|
|
||||||
self.password = pw
|
|
||||||
self.numTries = 0
|
|
||||||
urllib.FancyURLopener.__init__(self)
|
|
||||||
|
|
||||||
def prompt_user_passwd(self, host, realm):
|
|
||||||
if self.numTries == 0:
|
|
||||||
self.numTries = 1
|
|
||||||
return (self.username, self.password)
|
|
||||||
else:
|
|
||||||
return ('', '')
|
|
||||||
|
|
||||||
def openit(self, url):
|
|
||||||
self.numTries = 0
|
|
||||||
return urllib.FancyURLopener.open(self, url)
|
|
||||||
|
|
||||||
|
|
||||||
def processEpisode(dirName, nzbName=None, status=0, inputCategory=None):
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Logger.info("Loading config from %s", CONFIG_FILE)
|
|
||||||
|
|
||||||
if not config():
|
|
||||||
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
section = "Mylar"
|
|
||||||
if inputCategory != None and config().has_section(inputCategory):
|
|
||||||
section = inputCategory
|
|
||||||
host = config().get(section, "host")
|
|
||||||
port = config().get(section, "port")
|
|
||||||
username = config().get(section, "username")
|
|
||||||
password = config().get(section, "password")
|
|
||||||
try:
|
|
||||||
ssl = int(config().get(section, "ssl"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
ssl = 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
web_root = config().get(section, "web_root")
|
|
||||||
except config.NoOptionError:
|
|
||||||
web_root = ""
|
|
||||||
|
|
||||||
try:
|
|
||||||
watch_dir = config().get(section, "watch_dir")
|
|
||||||
except config.NoOptionError:
|
|
||||||
watch_dir = ""
|
|
||||||
params = {}
|
|
||||||
|
|
||||||
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
|
||||||
|
|
||||||
if dirName == "Manual Run" and watch_dir != "":
|
|
||||||
dirName = watch_dir
|
|
||||||
|
|
||||||
params['nzb_folder'] = dirName
|
|
||||||
if nzbName != None:
|
|
||||||
params['nzb_name'] = nzbName
|
|
||||||
|
|
||||||
myOpener = AuthURLOpener(username, password)
|
|
||||||
|
|
||||||
if ssl:
|
|
||||||
protocol = "https://"
|
|
||||||
else:
|
|
||||||
protocol = "http://"
|
|
||||||
|
|
||||||
url = protocol + host + ":" + port + web_root + "/post_process?" + urllib.urlencode(params)
|
|
||||||
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = myOpener.openit(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
result = urlObj.readlines()
|
|
||||||
for line in result:
|
|
||||||
Logger.info("%s", line)
|
|
||||||
|
|
||||||
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
|
|
|
@ -1,75 +0,0 @@
|
||||||
import urllib
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from nzbToMediaEnv import *
|
|
||||||
from nzbToMediaUtil import *
|
|
||||||
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
|
||||||
socket.setdefaulttimeout(int(TimeOut)) #initialize socket timeout.
|
|
||||||
|
|
||||||
def process(dirName, nzbName=None, status=0, inputCategory=None):
|
|
||||||
|
|
||||||
status = int(status)
|
|
||||||
|
|
||||||
|
|
||||||
Logger.info("Loading config from %s", CONFIG_FILE)
|
|
||||||
|
|
||||||
if not config():
|
|
||||||
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
section = "Gamez"
|
|
||||||
if inputCategory != None and config().has_section(inputCategory):
|
|
||||||
section = inputCategory
|
|
||||||
|
|
||||||
host = config().get(section, "host")
|
|
||||||
port = config().get(section, "port")
|
|
||||||
apikey = config().get(section, "apikey")
|
|
||||||
|
|
||||||
try:
|
|
||||||
ssl = int(config().get(section, "ssl"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
ssl = 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
web_root = config().get(section, "web_root")
|
|
||||||
except config.NoOptionError:
|
|
||||||
web_root = ""
|
|
||||||
|
|
||||||
if ssl:
|
|
||||||
protocol = "https://"
|
|
||||||
else:
|
|
||||||
protocol = "http://"
|
|
||||||
|
|
||||||
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
|
||||||
|
|
||||||
baseURL = protocol + host + ":" + port + web_root + "/api?api_key=" + apikey + "&mode="
|
|
||||||
|
|
||||||
fields = nzbName.split("-")
|
|
||||||
gamezID = fields[0].replace("[","").replace("]","").replace(" ","")
|
|
||||||
downloadStatus = 'Wanted'
|
|
||||||
if status == 0:
|
|
||||||
downloadStatus = 'Downloaded'
|
|
||||||
|
|
||||||
url = baseURL + "UPDATEREQUESTEDSTATUS&db_id=" + gamezID + "&status=" + downloadStatus
|
|
||||||
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = urllib.urlopen(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
result = json.load(urlObj)
|
|
||||||
Logger.info("Gamez returned %s", result)
|
|
||||||
if result['success']:
|
|
||||||
Logger.info("Status for %s has been set to %s in Gamez", gamezID, downloadStatus)
|
|
||||||
return 0 # Success
|
|
||||||
else:
|
|
||||||
Logger.error("Status for %s has NOT been updated in Gamez", gamezID)
|
|
||||||
return 1 # failure
|
|
|
@ -1,325 +0,0 @@
|
||||||
import urllib
|
|
||||||
import datetime
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import Transcoder
|
|
||||||
from nzbToMediaEnv import *
|
|
||||||
from nzbToMediaUtil import *
|
|
||||||
from nzbToMediaSceneExceptions import process_all_exceptions
|
|
||||||
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
|
||||||
socket.setdefaulttimeout(int(TimeOut)) #initialize socket timeout.
|
|
||||||
|
|
||||||
def get_imdb(nzbName, dirName):
|
|
||||||
|
|
||||||
imdbid = ""
|
|
||||||
|
|
||||||
a = nzbName.find('.cp(') + 4 #search for .cptt( in nzbName
|
|
||||||
b = nzbName[a:].find(')') + a
|
|
||||||
if a > 3: # a == 3 if not exist
|
|
||||||
imdbid = nzbName[a:b]
|
|
||||||
|
|
||||||
if imdbid:
|
|
||||||
Logger.info("Found movie id %s in name", imdbid)
|
|
||||||
return imdbid
|
|
||||||
|
|
||||||
a = dirName.find('.cp(') + 4 #search for .cptt( in dirname
|
|
||||||
b = dirName[a:].find(')') + a
|
|
||||||
if a > 3: # a == 3 if not exist
|
|
||||||
imdbid = dirName[a:b]
|
|
||||||
|
|
||||||
if imdbid:
|
|
||||||
Logger.info("Found movie id %s in directory", imdbid)
|
|
||||||
return imdbid
|
|
||||||
|
|
||||||
else:
|
|
||||||
Logger.debug("Could not find an imdb id in directory or name")
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def get_movie_info(baseURL, imdbid, download_id):
|
|
||||||
|
|
||||||
movie_id = ""
|
|
||||||
movie_status = None
|
|
||||||
release_status = None
|
|
||||||
if not imdbid and not download_id:
|
|
||||||
return movie_id, imdbid, download_id, movie_status, release_status
|
|
||||||
|
|
||||||
releaselist = []
|
|
||||||
movieid = []
|
|
||||||
moviestatus = []
|
|
||||||
library = []
|
|
||||||
release = []
|
|
||||||
offset = int(0)
|
|
||||||
while True:
|
|
||||||
url = baseURL + "media.list/?status=active&release_status=snatched&limit_offset=50," + str(offset)
|
|
||||||
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = urllib.urlopen(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
break
|
|
||||||
|
|
||||||
movieid2 = []
|
|
||||||
library2 = []
|
|
||||||
release2 = []
|
|
||||||
moviestatus2 = []
|
|
||||||
try:
|
|
||||||
result = json.load(urlObj)
|
|
||||||
movieid2 = [item["_id"] for item in result["movies"]]
|
|
||||||
for item in result["movies"]:
|
|
||||||
if "identifier" in item:
|
|
||||||
library2.append(item["identifier"])
|
|
||||||
else:
|
|
||||||
library2.append(item["identifiers"]["imdb"])
|
|
||||||
release2 = [item["releases"] for item in result["movies"]]
|
|
||||||
moviestatus2 = [item["status"] for item in result["movies"]]
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to parse json data for movies")
|
|
||||||
break
|
|
||||||
|
|
||||||
movieid.extend(movieid2)
|
|
||||||
moviestatus.extend(moviestatus2)
|
|
||||||
library.extend(library2)
|
|
||||||
release.extend(release2)
|
|
||||||
if len(movieid2) < int(50): # finished parsing list of movies. Time to break.
|
|
||||||
break
|
|
||||||
offset = offset + 50
|
|
||||||
|
|
||||||
result = None # reset
|
|
||||||
for index in range(len(movieid)):
|
|
||||||
releaselist1 = [item for item in release[index] if item["status"] == "snatched" and "download_info" in item]
|
|
||||||
if download_id:
|
|
||||||
releaselist = [item for item in releaselist1 if item["download_info"]["id"].lower() == download_id.lower()]
|
|
||||||
else:
|
|
||||||
releaselist = releaselist1
|
|
||||||
|
|
||||||
if imdbid and library[index] == imdbid:
|
|
||||||
movie_id = str(movieid[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)
|
|
||||||
if not download_id and len(releaselist) == 1:
|
|
||||||
download_id = releaselist[0]["download_info"]["id"]
|
|
||||||
|
|
||||||
elif not imdbid and download_id and len(releaselist) > 0:
|
|
||||||
movie_id = str(movieid[index])
|
|
||||||
movie_status = str(moviestatus[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)
|
|
||||||
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if len(releaselist) == 1:
|
|
||||||
release_status = releaselist[0]["status"]
|
|
||||||
Logger.debug("Found a single release with download_id: %s. Release status is: %s", download_id, release_status)
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
if not movie_id:
|
|
||||||
Logger.exception("Could not parse database results to determine imdbid or movie id")
|
|
||||||
|
|
||||||
return movie_id, imdbid, download_id, movie_status, release_status
|
|
||||||
|
|
||||||
def get_status(baseURL, movie_id, download_id):
|
|
||||||
result = None
|
|
||||||
movie_status = None
|
|
||||||
release_status = None
|
|
||||||
if not movie_id:
|
|
||||||
return movie_status, release_status
|
|
||||||
|
|
||||||
Logger.debug("Looking for status of movie: %s", movie_id)
|
|
||||||
url = baseURL + "media.get/?id=" + str(movie_id)
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = urllib.urlopen(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
return None, None
|
|
||||||
try:
|
|
||||||
result = json.load(urlObj)
|
|
||||||
movie_status = str(result["media"]["status"])
|
|
||||||
Logger.debug("This movie is marked as status %s in CouchPotatoServer", movie_status)
|
|
||||||
except:
|
|
||||||
Logger.exception("Could not find a status for this movie")
|
|
||||||
|
|
||||||
try:
|
|
||||||
if len(result["media"]["releases"]) == 1 and result["media"]["releases"][0]["status"] == "done":
|
|
||||||
release_status = result["media"]["releases"][0]["status"]
|
|
||||||
else:
|
|
||||||
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:
|
|
||||||
release_status = release_status_list[0]
|
|
||||||
Logger.debug("This release is marked as status %s in CouchPotatoServer", release_status)
|
|
||||||
except: # index out of range/doesn't exist?
|
|
||||||
Logger.exception("Could not find a status for this release")
|
|
||||||
|
|
||||||
return movie_status, release_status
|
|
||||||
|
|
||||||
def process(dirName, nzbName=None, status=0, clientAgent = "manual", download_id = "", inputCategory=None):
|
|
||||||
|
|
||||||
status = int(status)
|
|
||||||
|
|
||||||
Logger.info("Loading config from %s", CONFIG_FILE)
|
|
||||||
|
|
||||||
if not config():
|
|
||||||
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
section = "CouchPotato"
|
|
||||||
if inputCategory != None and config().has_section(inputCategory):
|
|
||||||
section = inputCategory
|
|
||||||
|
|
||||||
host = config().get(section, "host")
|
|
||||||
port = config().get(section, "port")
|
|
||||||
apikey = config().get(section, "apikey")
|
|
||||||
delay = float(config().get(section, "delay"))
|
|
||||||
method = config().get(section, "method")
|
|
||||||
delete_failed = int(config().get(section, "delete_failed"))
|
|
||||||
wait_for = int(config().get(section, "wait_for"))
|
|
||||||
try:
|
|
||||||
TimePerGiB = int(config().get(section, "TimePerGiB"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
|
|
||||||
try:
|
|
||||||
ssl = int(config().get(section, "ssl"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
ssl = 0
|
|
||||||
try:
|
|
||||||
web_root = config().get(section, "web_root")
|
|
||||||
except config.NoOptionError:
|
|
||||||
web_root = ""
|
|
||||||
try:
|
|
||||||
transcode = int(config().get("Transcoder", "transcode"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
transcode = 0
|
|
||||||
try:
|
|
||||||
remoteCPS = int(config().get(section, "remoteCPS"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
remoteCPS = 0
|
|
||||||
|
|
||||||
nzbName = str(nzbName) # make sure it is a string
|
|
||||||
|
|
||||||
imdbid = get_imdb(nzbName, dirName)
|
|
||||||
|
|
||||||
if ssl:
|
|
||||||
protocol = "https://"
|
|
||||||
else:
|
|
||||||
protocol = "http://"
|
|
||||||
# don't delay when we are calling this script manually.
|
|
||||||
if nzbName == "Manual Run":
|
|
||||||
delay = 0
|
|
||||||
|
|
||||||
baseURL = protocol + host + ":" + port + web_root + "/api/" + apikey + "/"
|
|
||||||
|
|
||||||
movie_id, imdbid, download_id, initial_status, initial_release_status = get_movie_info(baseURL, imdbid, download_id) # get the CPS database movie id for this movie.
|
|
||||||
|
|
||||||
process_all_exceptions(nzbName.lower(), dirName)
|
|
||||||
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
|
||||||
|
|
||||||
if status == 0:
|
|
||||||
if transcode == 1:
|
|
||||||
result = Transcoder.Transcode_directory(dirName)
|
|
||||||
if result == 0:
|
|
||||||
Logger.debug("Transcoding succeeded for files in %s", dirName)
|
|
||||||
else:
|
|
||||||
Logger.warning("Transcoding failed for files in %s", dirName)
|
|
||||||
|
|
||||||
if method == "manage":
|
|
||||||
command = "manage.update"
|
|
||||||
else:
|
|
||||||
command = "renamer.scan"
|
|
||||||
if clientAgent != "manual" and download_id != None:
|
|
||||||
if remoteCPS == 1:
|
|
||||||
command = command + "/?downloader=" + clientAgent + "&download_id=" + download_id
|
|
||||||
else:
|
|
||||||
command = command + "/?media_folder=" + urllib.quote(dirName) + "&downloader=" + clientAgent + "&download_id=" + download_id
|
|
||||||
|
|
||||||
dirSize = getDirectorySize(dirName) # get total directory size to calculate needed processing time.
|
|
||||||
TimeOut2 = int(TimePerGiB) * dirSize # Couchpotato needs to complete all moving and renaming before returning the status.
|
|
||||||
TimeOut2 += 60 # Add an extra minute for over-head/processing/metadata.
|
|
||||||
socket.setdefaulttimeout(int(TimeOut2)) #initialize socket timeout. We may now be able to remove the delays from the wait_for section below? If true, this should exit on first loop.
|
|
||||||
|
|
||||||
url = baseURL + command
|
|
||||||
|
|
||||||
Logger.info("Waiting for %s seconds to allow CPS to process newly extracted files", str(delay))
|
|
||||||
|
|
||||||
time.sleep(delay)
|
|
||||||
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = urllib.urlopen(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
result = json.load(urlObj)
|
|
||||||
Logger.info("CouchPotatoServer returned %s", result)
|
|
||||||
if result['success']:
|
|
||||||
Logger.info("%s scan started on CouchPotatoServer for %s", method, nzbName)
|
|
||||||
else:
|
|
||||||
Logger.error("%s scan has NOT started on CouchPotatoServer for %s. Exiting", method, nzbName)
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
else:
|
|
||||||
Logger.info("Download of %s has failed.", nzbName)
|
|
||||||
Logger.info("Trying to re-cue the next highest ranked release")
|
|
||||||
|
|
||||||
if not movie_id:
|
|
||||||
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.error("Exiting autoProcessMovie script")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
url = baseURL + "movie.searcher.try_next/?media_id=" + movie_id
|
|
||||||
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = urllib.urlopen(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
result = urlObj.readlines()
|
|
||||||
for line in result:
|
|
||||||
Logger.info("%s", line)
|
|
||||||
|
|
||||||
Logger.info("Movie %s set to try the next best release on CouchPotatoServer", movie_id)
|
|
||||||
if delete_failed and not dirName in ['sys.argv[0]','/','']:
|
|
||||||
Logger.info("Deleting failed files and folder %s", dirName)
|
|
||||||
try:
|
|
||||||
shutil.rmtree(dirName)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to delete folder %s", dirName)
|
|
||||||
return 0 # success
|
|
||||||
|
|
||||||
if nzbName == "Manual Run":
|
|
||||||
return 0 # success
|
|
||||||
if not download_id:
|
|
||||||
return 1 # just to be sure TorrentToMedia doesn't start deleting files as we havent verified changed status.
|
|
||||||
|
|
||||||
# we will now check to see if CPS has finished renaming before returning to TorrentToMedia and unpausing.
|
|
||||||
socket.setdefaulttimeout(int(TimeOut)) #initialize socket timeout.
|
|
||||||
|
|
||||||
release_status = None
|
|
||||||
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?
|
|
||||||
while (datetime.datetime.now() - start) < datetime.timedelta(minutes=wait_for): # only wait 2 (default) minutes, then return.
|
|
||||||
movie_status, release_status = 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.
|
|
||||||
Logger.info("SUCCESS: This movie is now marked as status %s in CouchPotatoServer", movie_status)
|
|
||||||
return 0 # success
|
|
||||||
time.sleep(pause_for) # Just stop this looping infinitely and hogging resources for 2 minutes ;)
|
|
||||||
else:
|
|
||||||
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)
|
|
||||||
return 0 # success
|
|
||||||
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)
|
|
||||||
return 1 # failure
|
|
|
@ -1,103 +0,0 @@
|
||||||
import urllib
|
|
||||||
import datetime
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from nzbToMediaEnv import *
|
|
||||||
from nzbToMediaUtil import *
|
|
||||||
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
|
||||||
|
|
||||||
def process(dirName, nzbName=None, status=0, clientAgent="manual", inputCategory=None):
|
|
||||||
|
|
||||||
status = int(status)
|
|
||||||
|
|
||||||
Logger.info("Loading config from %s", CONFIG_FILE)
|
|
||||||
|
|
||||||
if not config():
|
|
||||||
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
section = "HeadPhones"
|
|
||||||
if inputCategory != None and config().has_section(inputCategory):
|
|
||||||
section = inputCategory
|
|
||||||
|
|
||||||
host = config().get(section, "host")
|
|
||||||
port = config().get(section, "port")
|
|
||||||
apikey = config().get(section, "apikey")
|
|
||||||
delay = float(config().get(section, "delay"))
|
|
||||||
|
|
||||||
try:
|
|
||||||
ssl = int(config().get(section, "ssl"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
ssl = 0
|
|
||||||
try:
|
|
||||||
web_root = config().get(section, "web_root")
|
|
||||||
except config.NoOptionError:
|
|
||||||
web_root = ""
|
|
||||||
try:
|
|
||||||
TimePerGiB = int(config().get(section, "TimePerGiB"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
|
|
||||||
if ssl:
|
|
||||||
protocol = "https://"
|
|
||||||
else:
|
|
||||||
protocol = "http://"
|
|
||||||
# don't delay when we are calling this script manually.
|
|
||||||
if clientAgent == "manual":
|
|
||||||
delay = 0
|
|
||||||
|
|
||||||
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
|
||||||
|
|
||||||
dirSize = getDirectorySize(dirName) # get total directory size to calculate needed processing time.
|
|
||||||
TimeOut = int(TimePerGiB) * dirSize # HeadPhones needs to complete all moving/transcoding and renaming before returning the status.
|
|
||||||
TimeOut += 60 # Add an extra minute for over-head/processing/metadata.
|
|
||||||
socket.setdefaulttimeout(int(TimeOut)) #initialize socket timeout.
|
|
||||||
|
|
||||||
params = {}
|
|
||||||
params['apikey'] = apikey
|
|
||||||
params['cmd'] = "forceProcess"
|
|
||||||
params['dir'] = dirName
|
|
||||||
|
|
||||||
baseURL = protocol + host + ":" + port + web_root + "/api?" + urllib.urlencode(params)
|
|
||||||
|
|
||||||
if status == 0:
|
|
||||||
|
|
||||||
url = baseURL
|
|
||||||
|
|
||||||
Logger.info("Waiting for %s seconds to allow HeadPhones to process newly extracted files", str(delay))
|
|
||||||
|
|
||||||
time.sleep(delay)
|
|
||||||
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = urllib.urlopen(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
result = urlObj.readlines()
|
|
||||||
Logger.info("HeadPhones returned %s", result)
|
|
||||||
if result[0] == "OK":
|
|
||||||
Logger.info("Post-processing started on HeadPhones for %s", nzbName)
|
|
||||||
else:
|
|
||||||
Logger.error("Post-processing has NOT started on HeadPhones for %s. Exiting", nzbName)
|
|
||||||
return 1 # failure
|
|
||||||
else:
|
|
||||||
Logger.info("The download failed. Nothing to process")
|
|
||||||
return 0 # Success (as far as this script is concerned)
|
|
||||||
|
|
||||||
if nzbName == "Manual Run":
|
|
||||||
return 0 # success
|
|
||||||
|
|
||||||
# we will now wait 1 minutes for this album to be processed before returning to TorrentToMedia and unpausing.
|
|
||||||
## Hopefully we can use a "getHistory" check in here to confirm processing complete...
|
|
||||||
start = datetime.datetime.now() # set time for timeout
|
|
||||||
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 ;)
|
|
||||||
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.warning("The album does not appear to have changed status after 2 minutes. Please check HeadPhones Logs")
|
|
||||||
# return 1 # failure
|
|
||||||
return 0 # success for now.
|
|
|
@ -1,216 +0,0 @@
|
||||||
import urllib
|
|
||||||
import logging
|
|
||||||
import copy
|
|
||||||
|
|
||||||
import Transcoder
|
|
||||||
from nzbToMediaSceneExceptions import process_all_exceptions
|
|
||||||
from autoProcess.autoSickBeardFork import autoFork
|
|
||||||
from nzbToMediaEnv import *
|
|
||||||
from nzbToMediaUtil import *
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
|
||||||
|
|
||||||
class AuthURLOpener(urllib.FancyURLopener):
|
|
||||||
def __init__(self, user, pw):
|
|
||||||
self.username = user
|
|
||||||
self.password = pw
|
|
||||||
self.numTries = 0
|
|
||||||
urllib.FancyURLopener.__init__(self)
|
|
||||||
|
|
||||||
def prompt_user_passwd(self, host, realm):
|
|
||||||
if self.numTries == 0:
|
|
||||||
self.numTries = 1
|
|
||||||
return (self.username, self.password)
|
|
||||||
else:
|
|
||||||
return ('', '')
|
|
||||||
|
|
||||||
def openit(self, url):
|
|
||||||
self.numTries = 0
|
|
||||||
try:
|
|
||||||
return urllib.FancyURLopener.open(self, url)
|
|
||||||
except:
|
|
||||||
raise IOError("Unable to open URL")
|
|
||||||
|
|
||||||
def delete(dirName):
|
|
||||||
Logger.info("Deleting failed files and folder %s", dirName)
|
|
||||||
try:
|
|
||||||
shutil.rmtree(dirName, True)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to delete folder %s", dirName)
|
|
||||||
|
|
||||||
|
|
||||||
def processEpisode(dirName, nzbName=None, failed=False, clientAgent = "manual", inputCategory=None):
|
|
||||||
|
|
||||||
status = int(failed)
|
|
||||||
|
|
||||||
Logger.info("Loading config from %s", CONFIG_FILE)
|
|
||||||
|
|
||||||
if not config():
|
|
||||||
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
section = "SickBeard"
|
|
||||||
if inputCategory != None and config().has_section(inputCategory):
|
|
||||||
section = inputCategory
|
|
||||||
|
|
||||||
host = config().get(section, "host")
|
|
||||||
port = config().get(section, "port")
|
|
||||||
username = config().get(section, "username")
|
|
||||||
password = config().get(section, "password")
|
|
||||||
|
|
||||||
try:
|
|
||||||
ssl = int(config().get(section, "ssl"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
ssl = 0
|
|
||||||
try:
|
|
||||||
web_root = config().get(section, "web_root")
|
|
||||||
except config.NoOptionError:
|
|
||||||
web_root = ""
|
|
||||||
try:
|
|
||||||
watch_dir = config().get(section, "watch_dir")
|
|
||||||
except config.NoOptionError:
|
|
||||||
watch_dir = ""
|
|
||||||
try:
|
|
||||||
transcode = int(config().get("Transcoder", "transcode"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
transcode = 0
|
|
||||||
try:
|
|
||||||
delete_failed = int(config().get(section, "delete_failed"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
delete_failed = 0
|
|
||||||
try:
|
|
||||||
delay = float(config().get(section, "delay"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
delay = 0
|
|
||||||
try:
|
|
||||||
TimePerGiB = int(config().get(section, "TimePerGiB"))
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
|
|
||||||
try:
|
|
||||||
SampleIDs = (config().get("Extensions", "SampleIDs")).split(',')
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
SampleIDs = ['sample','-s.']
|
|
||||||
try:
|
|
||||||
nzbExtractionBy = config().get(section, "nzbExtractionBy")
|
|
||||||
except (config.NoOptionError, ValueError):
|
|
||||||
nzbExtractionBy = "Downloader"
|
|
||||||
try:
|
|
||||||
process_method = config().get(section, "process_method")
|
|
||||||
except config.NoOptionError:
|
|
||||||
process_method = None
|
|
||||||
|
|
||||||
mediaContainer = (config().get("Extensions", "mediaExtensions")).split(',')
|
|
||||||
minSampleSize = int(config().get("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.
|
|
||||||
dirName = os.path.split(os.path.normpath(dirName))[0]
|
|
||||||
|
|
||||||
SpecificPath = os.path.join(dirName, str(nzbName))
|
|
||||||
cleanName = os.path.splitext(SpecificPath)
|
|
||||||
if cleanName[1] == ".nzb":
|
|
||||||
SpecificPath = cleanName[0]
|
|
||||||
if os.path.isdir(SpecificPath):
|
|
||||||
dirName = SpecificPath
|
|
||||||
|
|
||||||
# auto-detect fork type
|
|
||||||
fork, params = autoFork()
|
|
||||||
|
|
||||||
if fork not in SICKBEARD_TORRENT or (clientAgent in ['nzbget','sabnzbd'] and nzbExtractionBy != "Destination"):
|
|
||||||
if nzbName:
|
|
||||||
process_all_exceptions(nzbName.lower(), dirName)
|
|
||||||
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
|
||||||
|
|
||||||
# Now check if tv files exist in destination. Eventually extraction may be done here if nzbExtractionBy == TorrentToMedia
|
|
||||||
video = int(0)
|
|
||||||
for dirpath, dirnames, filenames in os.walk(dirName):
|
|
||||||
for file in filenames:
|
|
||||||
filePath = os.path.join(dirpath, file)
|
|
||||||
fileExtension = os.path.splitext(file)[1]
|
|
||||||
if fileExtension in mediaContainer: # If the file is a video file
|
|
||||||
if is_sample(filePath, nzbName, minSampleSize, SampleIDs):
|
|
||||||
Logger.debug("Removing sample file: %s", filePath)
|
|
||||||
os.unlink(filePath) # remove samples
|
|
||||||
else:
|
|
||||||
video = video + 1
|
|
||||||
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)
|
|
||||||
elif clientAgent == "manual":
|
|
||||||
Logger.warning("No media files found in directory %s to manually process.", dirName)
|
|
||||||
return 0 # Success (as far as this script is concerned)
|
|
||||||
else:
|
|
||||||
Logger.warning("No media files found in directory %s. Processing this as a failed download", dirName)
|
|
||||||
status = int(1)
|
|
||||||
failed = True
|
|
||||||
|
|
||||||
dirSize = getDirectorySize(dirName) # get total directory size to calculate needed processing time.
|
|
||||||
TimeOut = int(TimePerGiB) * dirSize # SickBeard needs to complete all moving and renaming before returning the log sequence via url.
|
|
||||||
TimeOut += 60 # Add an extra minute for over-head/processing/metadata.
|
|
||||||
socket.setdefaulttimeout(int(TimeOut)) #initialize socket timeout.
|
|
||||||
|
|
||||||
# configure SB params to pass
|
|
||||||
params['quiet'] = 1
|
|
||||||
if nzbName is not None:
|
|
||||||
params['nzbName'] = nzbName
|
|
||||||
|
|
||||||
for param in copy.copy(params):
|
|
||||||
if param == "failed":
|
|
||||||
params[param] = failed
|
|
||||||
|
|
||||||
if param in ["dirName", "dir"]:
|
|
||||||
params[param] = dirName
|
|
||||||
|
|
||||||
if param == "process_method":
|
|
||||||
if process_method:
|
|
||||||
params[param] = process_method
|
|
||||||
else:
|
|
||||||
del params[param]
|
|
||||||
|
|
||||||
# delete any unused params so we don't pass them to SB by mistake
|
|
||||||
[params.pop(k) for k,v in params.items() if v is None]
|
|
||||||
|
|
||||||
if status == 0:
|
|
||||||
Logger.info("The download succeeded. Sending process request to SickBeard's %s branch", fork)
|
|
||||||
elif fork in SICKBEARD_FAILED:
|
|
||||||
Logger.info("The download failed. Sending 'failed' process request to SickBeard's %s branch", fork)
|
|
||||||
else:
|
|
||||||
Logger.info("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]','/','']:
|
|
||||||
Logger.info("Deleting directory: %s", dirName)
|
|
||||||
delete(dirName)
|
|
||||||
return 0 # Success (as far as this script is concerned)
|
|
||||||
|
|
||||||
if status == 0 and transcode == 1: # only transcode successful downlaods
|
|
||||||
result = Transcoder.Transcode_directory(dirName)
|
|
||||||
if result == 0:
|
|
||||||
Logger.debug("Transcoding succeeded for files in %s", dirName)
|
|
||||||
else:
|
|
||||||
Logger.warning("Transcoding failed for files in %s", dirName)
|
|
||||||
|
|
||||||
myOpener = AuthURLOpener(username, password)
|
|
||||||
|
|
||||||
if ssl:
|
|
||||||
protocol = "https://"
|
|
||||||
else:
|
|
||||||
protocol = "http://"
|
|
||||||
|
|
||||||
url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(params)
|
|
||||||
|
|
||||||
if clientAgent == "manual":delay = 0
|
|
||||||
Logger.info("Waiting for %s seconds to allow SB to process newly extracted files", str(delay))
|
|
||||||
|
|
||||||
time.sleep(delay)
|
|
||||||
|
|
||||||
Logger.debug("Opening URL: %s", url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
urlObj = myOpener.openit(url)
|
|
||||||
except:
|
|
||||||
Logger.exception("Unable to open URL")
|
|
||||||
return 1 # failure
|
|
||||||
|
|
||||||
result = urlObj.readlines()
|
|
||||||
for line in result:
|
|
||||||
Logger.info("%s", line.rstrip())
|
|
||||||
if status != 0 and delete_failed and not dirName in ['sys.argv[0]','/','']:
|
|
||||||
delete(dirName)
|
|
||||||
return 0 # Success
|
|
|
@ -1,227 +0,0 @@
|
||||||
from nzbToMediaConfig import *
|
|
||||||
|
|
||||||
def migrate():
|
|
||||||
categories = []
|
|
||||||
confignew = config(SAMPLE_CONFIG_FILE)
|
|
||||||
configold = config(CONFIG_FILE)
|
|
||||||
|
|
||||||
section = "CouchPotato"
|
|
||||||
for option, value in configold.items(section) or config(MOVIE_CONFIG_FILE).items(section):
|
|
||||||
if option == "category": # change this old format
|
|
||||||
option = "cpsCategory"
|
|
||||||
if option == "outputDirectory": # move this to new location format
|
|
||||||
value = os.path.split(os.path.normpath(value))[0]
|
|
||||||
confignew.set("Torrent", option, value)
|
|
||||||
continue
|
|
||||||
if option in ["username", "password" ]: # these are no-longer needed.
|
|
||||||
continue
|
|
||||||
if option == "cpsCategory":
|
|
||||||
categories.extend(value.split(','))
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
section = "SickBeard"
|
|
||||||
for option, value in configold.items(section) or config(TV_CONFIG_FILE).items(section):
|
|
||||||
if option == "category": # change this old format
|
|
||||||
option = "sbCategory"
|
|
||||||
if option == "wait_for": # remove old format
|
|
||||||
continue
|
|
||||||
if option == "failed_fork": # change this old format
|
|
||||||
option = "fork"
|
|
||||||
if value not in ["default", "failed", "failed-torrent", "auto"]:
|
|
||||||
value = "auto"
|
|
||||||
if option == "fork" and value not in ["default", "failed", "failed-torrent", "auto"]:
|
|
||||||
value = "auto"
|
|
||||||
if option == "outputDirectory": # move this to new location format
|
|
||||||
value = os.path.split(os.path.normpath(value))[0]
|
|
||||||
confignew.set("Torrent", option, value)
|
|
||||||
continue
|
|
||||||
if option == "sbCategory":
|
|
||||||
categories.extend(value.split(','))
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
for section in configold.sections():
|
|
||||||
try:
|
|
||||||
for option, value in configold.items(section):
|
|
||||||
if section == "HeadPhones":
|
|
||||||
if option in ["username", "password" ]:
|
|
||||||
continue
|
|
||||||
if option == "hpCategory":
|
|
||||||
categories.extend(value.split(','))
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "Mylar":
|
|
||||||
if option in "mlCategory":
|
|
||||||
categories.extend(value.split(','))
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "Gamez":
|
|
||||||
if option in ["username", "password" ]: # these are no-longer needed.
|
|
||||||
continue
|
|
||||||
if option == "gzCategory":
|
|
||||||
categories.extend(value.split(','))
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "Torrent":
|
|
||||||
if option in ["compressedExtensions", "mediaExtensions", "metaExtensions", "minSampleSize"]:
|
|
||||||
section = "Extensions" # these were moved
|
|
||||||
if option == "useLink": # Sym links supported now as well.
|
|
||||||
if isinstance(value, int):
|
|
||||||
num_value = int(value)
|
|
||||||
if num_value == 1:
|
|
||||||
value = "hard"
|
|
||||||
else:
|
|
||||||
value = "no"
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "Extensions":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "Transcoder":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "WakeOnLan":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "UserScript":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "ASCII":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "passwords":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "loggers":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "handlers":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "formatters":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "logger_root":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "handler_console":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
if section == "formatter_generic":
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
except config.InterpolationMissingOptionError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
for section in categories:
|
|
||||||
try:
|
|
||||||
if configold.items(section):
|
|
||||||
confignew.add_section(section)
|
|
||||||
|
|
||||||
for option, value in configold.items(section):
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
except config.NoSectionError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# create a backup of our old config
|
|
||||||
if os.path.isfile(CONFIG_FILE):
|
|
||||||
cfgbak_name = CONFIG_FILE + ".old"
|
|
||||||
if os.path.isfile(cfgbak_name): # remove older backups
|
|
||||||
os.unlink(cfgbak_name)
|
|
||||||
os.rename(CONFIG_FILE, cfgbak_name)
|
|
||||||
|
|
||||||
# writing our configuration file to 'autoProcessMedia.cfg'
|
|
||||||
with open(CONFIG_FILE, 'wb') as configFile:
|
|
||||||
confignew.write(configFile)
|
|
||||||
|
|
||||||
def addnzbget():
|
|
||||||
confignew = config()
|
|
||||||
section = "CouchPotato"
|
|
||||||
envKeys = ['CATEGORY', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT', 'DELAY', 'METHOD', 'DELETE_FAILED', 'REMOTECPS', 'WAIT_FOR', 'TIMEPERGIB']
|
|
||||||
cfgKeys = ['cpsCategory', 'apikey', 'host', 'port', 'ssl', 'web_root', 'delay', 'method', 'delete_failed', 'remoteCPS', 'wait_for', 'TimePerGiB']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_CPS' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
|
|
||||||
section = "SickBeard"
|
|
||||||
envKeys = ['CATEGORY', 'HOST', 'PORT', 'USERNAME', 'PASSWORD', 'SSL', 'WEB_ROOT', 'WATCH_DIR', 'FORK', 'DELETE_FAILED', 'DELAY', 'TIMEPERGIB', 'PROCESS_METHOD']
|
|
||||||
cfgKeys = ['sbCategory', 'host', 'port', 'username', 'password', 'ssl', 'web_root', 'watch_dir', 'fork', 'delete_failed', 'delay', 'TimePerGiB', 'process_method']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_SB' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
section = "HeadPhones"
|
|
||||||
envKeys = ['CATEGORY', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT', 'DELAY', 'TIMEPERGIB']
|
|
||||||
cfgKeys = ['hpCategory', 'apikey', 'host', 'port', 'ssl', 'web_root', 'delay', 'TimePerGiB']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_HP' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
section = "Mylar"
|
|
||||||
envKeys = ['CATEGORY', 'HOST', 'PORT', 'USERNAME', 'PASSWORD', 'SSL', 'WEB_ROOT']
|
|
||||||
cfgKeys = ['mlCategory', 'host', 'port', 'username', 'password', 'ssl', 'web_root']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_MY' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
section = "Gamez"
|
|
||||||
envKeys = ['CATEGORY', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT']
|
|
||||||
cfgKeys = ['gzCategory', 'apikey', 'host', 'port', 'ssl', 'web_root']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_GZ' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
section = "Extensions"
|
|
||||||
envKeys = ['COMPRESSEDEXTENSIONS', 'MEDIAEXTENSIONS', 'METAEXTENSIONS']
|
|
||||||
cfgKeys = ['compressedExtensions', 'mediaExtensions', 'metaExtensions']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
section = "Transcoder"
|
|
||||||
envKeys = ['TRANSCODE', 'DUPLICATE', 'IGNOREEXTENSIONS', 'OUTPUTVIDEOEXTENSION', 'OUTPUTVIDEOCODEC', 'OUTPUTVIDEOPRESET', 'OUTPUTVIDEOFRAMERATE', 'OUTPUTVIDEOBITRATE', 'OUTPUTAUDIOCODEC', 'OUTPUTAUDIOBITRATE', 'OUTPUTSUBTITLECODEC']
|
|
||||||
cfgKeys = ['transcode', 'duplicate', 'ignoreExtensions', 'outputVideoExtension', 'outputVideoCodec', 'outputVideoPreset', 'outputVideoFramerate', 'outputVideoBitrate', 'outputAudioCodec', 'outputAudioBitrate', 'outputSubtitleCodec']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
section = "WakeOnLan"
|
|
||||||
envKeys = ['WAKE', 'HOST', 'PORT', 'MAC']
|
|
||||||
cfgKeys = ['wake', 'host', 'port', 'mac']
|
|
||||||
for index in range(len(envKeys)):
|
|
||||||
key = 'NZBPO_WOL' + envKeys[index]
|
|
||||||
if os.environ.has_key(key):
|
|
||||||
option = cfgKeys[index]
|
|
||||||
value = os.environ[key]
|
|
||||||
confignew.set(section, option, value)
|
|
||||||
|
|
||||||
# create a backup of our old config
|
|
||||||
if os.path.isfile(CONFIG_FILE):
|
|
||||||
cfgbak_name = CONFIG_FILE + ".old"
|
|
||||||
if os.path.isfile(cfgbak_name): # remove older backups
|
|
||||||
os.unlink(cfgbak_name)
|
|
||||||
os.rename(CONFIG_FILE, cfgbak_name)
|
|
||||||
|
|
||||||
# writing our configuration file to 'autoProcessMedia.cfg'
|
|
||||||
with open(CONFIG_FILE, 'wb') as configFile:
|
|
||||||
confignew.write(configFile)
|
|
|
@ -1,24 +0,0 @@
|
||||||
# Make things easy and less error prone by centralising all common values
|
|
||||||
|
|
||||||
# Global Constants
|
|
||||||
VERSION = 'V9.3'
|
|
||||||
TimeOut = 60
|
|
||||||
|
|
||||||
# Constants pertinant to SabNzb
|
|
||||||
SABNZB_NO_OF_ARGUMENTS = 8
|
|
||||||
SABNZB_0717_NO_OF_ARGUMENTS = 9
|
|
||||||
|
|
||||||
# Constants pertaining to SickBeard Branches:
|
|
||||||
fork_default = "default"
|
|
||||||
fork_failed = "failed"
|
|
||||||
fork_failed_torrent = "failed-torrent"
|
|
||||||
|
|
||||||
forks = {}
|
|
||||||
|
|
||||||
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]
|
|
||||||
|
|
|
@ -13,13 +13,13 @@ ssl = 0
|
||||||
web_root =
|
web_root =
|
||||||
delay = 65
|
delay = 65
|
||||||
TimePerGiB = 60
|
TimePerGiB = 60
|
||||||
|
watch_dir =
|
||||||
method = renamer
|
method = renamer
|
||||||
delete_failed = 0
|
delete_failed = 0
|
||||||
wait_for = 2
|
wait_for = 2
|
||||||
#### Set to 1 if CouchPotatoServer is running on a different server to your NZB client
|
#### Set to 1 if CouchPotatoServer is running on a different server to your NZB client
|
||||||
remoteCPS = 0
|
remoteCPS = 0
|
||||||
|
|
||||||
|
|
||||||
[SickBeard]
|
[SickBeard]
|
||||||
#### autoProcessing for TV Series
|
#### autoProcessing for TV Series
|
||||||
#### sbCategory - category that gets called for post-processing with SB
|
#### sbCategory - category that gets called for post-processing with SB
|
||||||
|
@ -40,7 +40,6 @@ nzbExtractionBy = Downloader
|
||||||
Torrent_ForceLink = 1
|
Torrent_ForceLink = 1
|
||||||
process_method =
|
process_method =
|
||||||
|
|
||||||
|
|
||||||
[HeadPhones]
|
[HeadPhones]
|
||||||
#### autoProcessing for Music
|
#### autoProcessing for Music
|
||||||
#### hpCategory - category that gets called for post-processing with HP
|
#### hpCategory - category that gets called for post-processing with HP
|
||||||
|
@ -53,7 +52,7 @@ ssl = 0
|
||||||
web_root =
|
web_root =
|
||||||
delay = 65
|
delay = 65
|
||||||
TimePerGiB = 60
|
TimePerGiB = 60
|
||||||
|
watch_dir =
|
||||||
|
|
||||||
[Mylar]
|
[Mylar]
|
||||||
#### autoProcessing for Comics
|
#### autoProcessing for Comics
|
||||||
|
@ -68,7 +67,6 @@ web_root=
|
||||||
ssl=0
|
ssl=0
|
||||||
watch_dir =
|
watch_dir =
|
||||||
|
|
||||||
|
|
||||||
[Gamez]
|
[Gamez]
|
||||||
#### autoProcessing for Games
|
#### autoProcessing for Games
|
||||||
#### gzCategory - category that gets called for post-processing with Gamez
|
#### gzCategory - category that gets called for post-processing with Gamez
|
||||||
|
@ -79,7 +77,7 @@ port = 8085
|
||||||
###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
|
###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ######
|
||||||
ssl = 0
|
ssl = 0
|
||||||
web_root =
|
web_root =
|
||||||
|
watch_dir =
|
||||||
|
|
||||||
[Torrent]
|
[Torrent]
|
||||||
###### clientAgent - Supported clients: utorrent, transmission, deluge, rtorrent, other
|
###### clientAgent - Supported clients: utorrent, transmission, deluge, rtorrent, other
|
||||||
|
|
|
@ -121,25 +121,32 @@
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
# Exit codes used by NZBGet
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie
|
||||||
|
from nzbtomedia.migratecfg import migratecfg
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames
|
||||||
|
|
||||||
import autoProcess.migratecfg as migratecfg
|
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
|
||||||
import autoProcess.autoProcessMovie as autoProcessMovie
|
if migratecfg().migrate():
|
||||||
from autoProcess.nzbToMediaEnv import *
|
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
||||||
from autoProcess.nzbToMediaUtil import *
|
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
||||||
|
migratecfg().addnzbget()
|
||||||
|
|
||||||
#check to migrate old cfg before trying to load.
|
nzbtomedia_configure_logging(config.LOG_FILE)
|
||||||
if os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample")):
|
Logger = logging.getLogger(__name__)
|
||||||
migratecfg.migrate()
|
Logger.info("====================") # Seperate old from new log
|
||||||
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
Logger.info("nzbToCouchPotato %s", config.NZBTOMEDIA_VERSION)
|
||||||
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
|
||||||
migratecfg.addnzbget()
|
|
||||||
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
Logger = logging.getLogger(__name__)
|
else:
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
Logger.info("====================") # Seperate old from new log
|
# couchpotato category
|
||||||
Logger.info("nzbToCouchPotato %s", VERSION)
|
cpsCategory = (config().get("CouchPotato", "cpsCategory")).split(',') # movie
|
||||||
|
|
||||||
WakeUp()
|
WakeUp()
|
||||||
|
|
||||||
|
@ -150,24 +157,19 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
|
||||||
|
|
||||||
# NZBGet argv: all passed as environment variables.
|
# NZBGet argv: all passed as environment variables.
|
||||||
clientAgent = "nzbget"
|
clientAgent = "nzbget"
|
||||||
# Exit codes used by NZBGet
|
|
||||||
POSTPROCESS_PARCHECK=92
|
|
||||||
POSTPROCESS_SUCCESS=93
|
|
||||||
POSTPROCESS_ERROR=94
|
|
||||||
POSTPROCESS_NONE=95
|
|
||||||
|
|
||||||
# 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("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
||||||
sys.exit(POSTPROCESS_ERROR)
|
sys.exit(config.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("MAIN: Par-check successful, but Par-repair disabled, exiting")
|
||||||
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
||||||
sys.exit(POSTPROCESS_NONE)
|
sys.exit(config.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("MAIN: Par-repair failed, setting status \"failed\"")
|
||||||
|
@ -200,9 +202,9 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5
|
||||||
if os.environ.has_key('NZBPR_COUCHPOTATO'):
|
if os.environ.has_key('NZBPR_COUCHPOTATO'):
|
||||||
download_id = os.environ['NZBPR_COUCHPOTATO']
|
download_id = os.environ['NZBPR_COUCHPOTATO']
|
||||||
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessMovie...")
|
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessMovie...")
|
||||||
result = autoProcessMovie.process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status, clientAgent, download_id)
|
result = autoProcessMovie().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status, clientAgent, download_id)
|
||||||
# SABnzbd Pre 0.7.17
|
# SABnzbd Pre 0.7.17
|
||||||
elif len(sys.argv) == SABNZB_NO_OF_ARGUMENTS:
|
elif len(sys.argv) == config.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
|
||||||
|
@ -213,9 +215,9 @@ elif len(sys.argv) == SABNZB_NO_OF_ARGUMENTS:
|
||||||
# 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.info("MAIN: Script triggered from SABnzbd, starting autoProcessMovie...")
|
||||||
clientAgent = "sabnzbd"
|
clientAgent = "sabnzbd"
|
||||||
result = autoProcessMovie.process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent)
|
result = autoProcessMovie().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent)
|
||||||
# SABnzbd 0.7.17+
|
# SABnzbd 0.7.17+
|
||||||
elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
elif len(sys.argv) >= config.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
|
||||||
|
@ -227,18 +229,23 @@ elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
||||||
# 8 Failure URL
|
# 8 Failure URL
|
||||||
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessMovie...")
|
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessMovie...")
|
||||||
clientAgent = "sabnzbd"
|
clientAgent = "sabnzbd"
|
||||||
result = autoProcessMovie.process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent)
|
result = autoProcessMovie().process(sys.argv[1], sys.argv[2], sys.argv[7], clientAgent)
|
||||||
else:
|
else:
|
||||||
|
result = 0
|
||||||
|
|
||||||
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
||||||
Logger.info("MAIN: Running autoProcessMovie as a manual run...")
|
Logger.info("MAIN: Running autoProcessMovie as a manual run...")
|
||||||
clientAgent = "manual"
|
|
||||||
result = autoProcessMovie.process('Manual Run', 'Manual Run', 0, clientAgent)
|
for dirName in get_dirnames("CouchPotato", cpsCategory[0]):
|
||||||
|
Logger.info("MAIN: Calling CouchPotato to post-process: %s", dirName)
|
||||||
|
result = autoProcessMovie().process(dirName, dirName, 0)
|
||||||
|
if result != 0: break
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
Logger.info("MAIN: The autoProcessMovie script completed successfully.")
|
Logger.info("MAIN: The autoProcessMovie 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(POSTPROCESS_SUCCESS)
|
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS)
|
||||||
else:
|
else:
|
||||||
Logger.info("MAIN: A problem was reported in the autoProcessMovie script.")
|
Logger.info("MAIN: A problem was reported in the autoProcessMovie 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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
||||||
|
|
|
@ -57,25 +57,33 @@
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Exit codes used by NZBGet
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames
|
||||||
|
from nzbtomedia.migratecfg import migratecfg
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import WakeUp, nzbtomedia_configure_logging, get_dirnames
|
||||||
|
|
||||||
import autoProcess.migratecfg as migratecfg
|
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
|
||||||
import autoProcess.autoProcessGames as autoProcessGames
|
if migratecfg().migrate():
|
||||||
from autoProcess.nzbToMediaEnv import *
|
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
||||||
from autoProcess.nzbToMediaUtil import *
|
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
||||||
|
migratecfg().addnzbget()
|
||||||
|
|
||||||
#check to migrate old cfg before trying to load.
|
nzbtomedia_configure_logging(config.LOG_FILE)
|
||||||
if os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample")):
|
Logger = logging.getLogger(__name__)
|
||||||
migratecfg.migrate()
|
Logger.info("====================") # Seperate old from new log
|
||||||
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
Logger.info("nzbToGamez %s", config.NZBTOMEDIA_VERSION)
|
||||||
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
|
||||||
migratecfg.addnzbget()
|
|
||||||
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
Logger = logging.getLogger(__name__)
|
else:
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
Logger.info("====================") # Seperate old from new log
|
# gamez category
|
||||||
Logger.info("nzbToGamez %s", VERSION)
|
gzCategory = (config().get("Gamez", "gzCategory")).split(',') # gamez
|
||||||
|
|
||||||
WakeUp()
|
WakeUp()
|
||||||
|
|
||||||
|
@ -84,25 +92,18 @@ WakeUp()
|
||||||
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.info("MAIN: Script triggered from NZBGet (11.0 or later).")
|
||||||
|
|
||||||
# NZBGet argv: all passed as environment variables.
|
|
||||||
# Exit codes used by NZBGet
|
|
||||||
POSTPROCESS_PARCHECK=92
|
|
||||||
POSTPROCESS_SUCCESS=93
|
|
||||||
POSTPROCESS_ERROR=94
|
|
||||||
POSTPROCESS_NONE=95
|
|
||||||
|
|
||||||
# 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("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
||||||
sys.exit(POSTPROCESS_ERROR)
|
sys.exit(config.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("MAIN: Par-check successful, but Par-repair disabled, exiting")
|
||||||
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
||||||
sys.exit(POSTPROCESS_NONE)
|
sys.exit(config.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("MAIN: Par-repair failed, setting status \"failed\"")
|
||||||
|
@ -132,9 +133,9 @@ 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.
|
||||||
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessGames...")
|
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessGames...")
|
||||||
result = autoProcessGames.process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status)
|
result = autoProcessGames().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status)
|
||||||
# SABnzbd Pre 0.7.17
|
# SABnzbd Pre 0.7.17
|
||||||
elif len(sys.argv) == SABNZB_NO_OF_ARGUMENTS:
|
elif len(sys.argv) == config.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
|
||||||
|
@ -144,9 +145,9 @@ elif len(sys.argv) == SABNZB_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
|
||||||
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessGames...")
|
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessGames...")
|
||||||
result = autoProcessGames.process(sys.argv[1], sys.argv[3], sys.argv[7])
|
result = autoProcessGames().process(sys.argv[1], sys.argv[3], sys.argv[7])
|
||||||
# SABnzbd 0.7.17+
|
# SABnzbd 0.7.17+
|
||||||
elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
elif len(sys.argv) >= config.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
|
||||||
|
@ -157,16 +158,22 @@ elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
||||||
# 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.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessGames...")
|
||||||
result = autoProcessGames.process(sys.argv[1], sys.argv[3], sys.argv[7])
|
result = autoProcessGames().process(sys.argv[1], sys.argv[3], sys.argv[7])
|
||||||
else:
|
else:
|
||||||
|
result = 0
|
||||||
Logger.warn("MAIN: Invalid number of arguments received from client. Exiting")
|
Logger.warn("MAIN: Invalid number of arguments received from client. Exiting")
|
||||||
sys.exit(1)
|
Logger.info("MAIN: Running autoProcessGames as a manual run...")
|
||||||
|
|
||||||
|
for dirName in get_dirnames("Gamez", gzCategory[0]):
|
||||||
|
Logger.info("MAIN: Calling Gamez to post-process: %s", dirName)
|
||||||
|
result = autoProcessGames().process(dirName, dirName, 0)
|
||||||
|
if result != 0: break
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
Logger.info("MAIN: The autoProcessGames script completed successfully.")
|
Logger.info("MAIN: The autoProcessGames 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(POSTPROCESS_SUCCESS)
|
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS)
|
||||||
else:
|
else:
|
||||||
Logger.info("MAIN: A problem was reported in the autoProcessGames script.")
|
Logger.info("MAIN: A problem was reported in the autoProcessGames 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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
||||||
|
|
|
@ -67,33 +67,32 @@
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import autoProcess.migratecfg as migratecfg
|
|
||||||
import autoProcess.autoProcessMusic as autoProcessMusic
|
|
||||||
from autoProcess.nzbToMediaEnv import *
|
|
||||||
from autoProcess.nzbToMediaUtil import *
|
|
||||||
|
|
||||||
# NZBGet argv: all passed as environment variables.
|
# NZBGet argv: all passed as environment variables.
|
||||||
# Exit codes used by NZBGet
|
# Exit codes used by NZBGet
|
||||||
POSTPROCESS_PARCHECK = 92
|
import os
|
||||||
POSTPROCESS_SUCCESS = 93
|
import sys
|
||||||
POSTPROCESS_ERROR = 94
|
import logging
|
||||||
POSTPROCESS_NONE = 95
|
from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic
|
||||||
|
from nzbtomedia.migratecfg import migratecfg
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import get_dirnames, WakeUp, nzbtomedia_configure_logging
|
||||||
|
|
||||||
|
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
|
||||||
|
if migratecfg().migrate():
|
||||||
|
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
||||||
|
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
||||||
|
migratecfg().addnzbget()
|
||||||
|
|
||||||
#check to migrate old cfg before trying to load.
|
nzbtomedia_configure_logging(config.LOG_FILE)
|
||||||
if os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample")):
|
Logger = logging.getLogger(__name__)
|
||||||
migratecfg.migrate()
|
Logger.info("====================") # Seperate old from new log
|
||||||
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
Logger.info("nzbToHeadPhones %s", config.NZBTOMEDIA_VERSION)
|
||||||
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
|
||||||
migratecfg.addnzbget()
|
|
||||||
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
Logger = logging.getLogger(__name__)
|
else:
|
||||||
|
sys.exit(-1)
|
||||||
Logger.info("====================") # Seperate old from new log
|
# headphones category
|
||||||
Logger.info("nzbToHeadPhones %s", VERSION)
|
hpCategory = (config().get("HeadPhones", "hpCategory")).split(',') # music
|
||||||
|
|
||||||
WakeUp()
|
WakeUp()
|
||||||
|
|
||||||
|
@ -107,13 +106,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':
|
||||||
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
||||||
sys.exit(POSTPROCESS_ERROR)
|
sys.exit(config.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("MAIN: Par-check successful, but Par-repair disabled, exiting")
|
||||||
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
||||||
sys.exit(POSTPROCESS_NONE)
|
sys.exit(config.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("MAIN: Par-repair failed, setting status \"failed\"")
|
||||||
|
@ -143,9 +142,9 @@ 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.
|
||||||
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessMusic...")
|
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessMusic...")
|
||||||
result = autoProcessMusic.process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status)
|
result = autoProcessMusic().process(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status)
|
||||||
# SABnzbd Pre 0.7.17
|
# SABnzbd Pre 0.7.17
|
||||||
elif len(sys.argv) == SABNZB_NO_OF_ARGUMENTS:
|
elif len(sys.argv) == config.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,9 +154,9 @@ elif len(sys.argv) == SABNZB_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
|
||||||
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessMusic...")
|
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessMusic...")
|
||||||
result = autoProcessMusic.process(sys.argv[1], sys.argv[2], sys.argv[7])
|
result = autoProcessMusic().process(sys.argv[1], sys.argv[2], sys.argv[7])
|
||||||
# SABnzbd 0.7.17+
|
# SABnzbd 0.7.17+
|
||||||
elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
elif len(sys.argv) >= config.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
|
||||||
|
@ -168,24 +167,23 @@ elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
||||||
# 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.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessMusic...")
|
||||||
result = autoProcessMusic.process(sys.argv[1], sys.argv[2], sys.argv[7])
|
result = autoProcessMusic().process(sys.argv[1], sys.argv[2], sys.argv[7])
|
||||||
else:
|
else:
|
||||||
result = 0
|
result = 0
|
||||||
hpCategory = (config().get("HeadPhones", "hpCategory")).split(',') # music
|
|
||||||
dirNames = get_dirnames("SickBeard", hpCategory[0])
|
|
||||||
|
|
||||||
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
||||||
Logger.info("MAIN: Running autoProcessMusic as a manual run...")
|
Logger.info("MAIN: Running autoProcessMusic as a manual run...")
|
||||||
|
|
||||||
for dirName in dirNames:
|
for dirName in get_dirnames("HeadPhones", hpCategory[0]):
|
||||||
Logger.info("MAIN: Calling Headphones to post-process: %s", dirName)
|
Logger.info("MAIN: Calling Headphones to post-process: %s", dirName)
|
||||||
result = result = autoProcessMusic.process(dirName, dirName, 0)
|
result = result = autoProcessMusic().process(dirName, dirName, 0)
|
||||||
if result != 0: break
|
if result != 0: break
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
Logger.info("MAIN: The autoProcessMusic script completed successfully.")
|
Logger.info("MAIN: 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(POSTPROCESS_SUCCESS)
|
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS)
|
||||||
else:
|
else:
|
||||||
Logger.info("MAIN: A problem was reported in the autoProcessMusic script.")
|
Logger.info("MAIN: 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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
||||||
|
|
209
nzbToMedia.py
209
nzbToMedia.py
|
@ -73,7 +73,7 @@
|
||||||
# SickBeard script category.
|
# SickBeard script category.
|
||||||
#
|
#
|
||||||
# category that gets called for post-processing with SickBeard.
|
# category that gets called for post-processing with SickBeard.
|
||||||
#sbCategory=tv
|
#config().sbCategory=tv
|
||||||
|
|
||||||
# SickBeard host.
|
# SickBeard host.
|
||||||
#sbhost=localhost
|
#sbhost=localhost
|
||||||
|
@ -271,54 +271,101 @@
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import shutil
|
import os
|
||||||
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics
|
||||||
|
from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames
|
||||||
|
from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie
|
||||||
|
from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic
|
||||||
|
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
|
||||||
|
from nzbtomedia.migratecfg import migratecfg
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames
|
||||||
|
|
||||||
import autoProcess.autoProcessComics as autoProcessComics
|
# post-processing
|
||||||
import autoProcess.autoProcessGames as autoProcessGames
|
def process(nzbDir, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None):
|
||||||
import autoProcess.autoProcessMusic as autoProcessMusic
|
if inputCategory in cpsCategory:
|
||||||
import autoProcess.autoProcessMovie as autoProcessMovie
|
if isinstance(nzbDir, list):
|
||||||
import autoProcess.autoProcessTV as autoProcessTV
|
for dirName in nzbDir:
|
||||||
import autoProcess.migratecfg as migratecfg
|
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
|
||||||
from autoProcess.nzbToMediaEnv import *
|
result = autoProcessMovie().process(dirName, dirName, status, clientAgent, download_id, inputCategory)
|
||||||
from autoProcess.nzbToMediaUtil import *
|
if result != 0:
|
||||||
|
return result
|
||||||
# Exit codes used by NZBGet
|
else:
|
||||||
POSTPROCESS_PARCHECK = 92
|
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
|
||||||
POSTPROCESS_SUCCESS = 93
|
return autoProcessMovie().process(nzbDir, inputName, status, clientAgent, download_id, inputCategory)
|
||||||
POSTPROCESS_ERROR = 94
|
elif inputCategory in sbCategory:
|
||||||
POSTPROCESS_NONE = 95
|
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:
|
||||||
|
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
|
||||||
|
return autoProcessTV().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
|
||||||
|
elif inputCategory in hpCategory:
|
||||||
|
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:
|
||||||
|
Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName)
|
||||||
|
return autoProcessMusic().process(nzbDir, inputName, status, clientAgent, inputCategory)
|
||||||
|
elif inputCategory in mlCategory:
|
||||||
|
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:
|
||||||
|
Logger.info("MAIN: Calling Mylar to post-process: %s", inputName)
|
||||||
|
return autoProcessComics().processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
|
||||||
|
elif inputCategory in gzCategory:
|
||||||
|
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:
|
||||||
|
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)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
########################################################################################################################
|
||||||
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
|
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
|
||||||
if config(SAMPLE_CONFIG_FILE):
|
if migratecfg().migrate():
|
||||||
migratecfg.migrate()
|
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
||||||
elif config():
|
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
||||||
shutil.copyfile(CONFIG_FILE, SAMPLE_CONFIG_FILE)
|
migratecfg().addnzbget()
|
||||||
migratecfg.migrate()
|
|
||||||
|
|
||||||
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
nzbtomedia_configure_logging(config.LOG_FILE)
|
||||||
if config() and os.environ.has_key('NZBOP_SCRIPTDIR'):
|
Logger = logging.getLogger(__name__)
|
||||||
migratecfg.addnzbget()
|
Logger.info("====================") # Seperate old from new log
|
||||||
|
Logger.info("nzbToMedia %s", config.NZBTOMEDIA_VERSION)
|
||||||
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
Logger = logging.getLogger(__name__)
|
else:
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
Logger.info("====================") # Seperate old from new log
|
# setup categories
|
||||||
Logger.info("nzbToMedia %s", VERSION)
|
cpsCategory = (config().get("CouchPotato", "cpsCategory")).split(',') or []
|
||||||
|
sbCategory = (config().get("SickBeard", "sbCategory")).split(',') or []
|
||||||
|
hpCategory = (config().get("HeadPhones", "hpCategory")).split(',') or []
|
||||||
|
mlCategory = (config().get("Mylar", "mlCategory")).split(',') or []
|
||||||
|
gzCategory = (config().get("Gamez", "gzCategory")).split(',') or []
|
||||||
|
|
||||||
WakeUp()
|
WakeUp()
|
||||||
|
|
||||||
if not config():
|
# Post-Processing Result
|
||||||
Logger.error("MAIN: You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
result = 0
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
Logger.info("MAIN: Loading config from %s", CONFIG_FILE)
|
|
||||||
|
|
||||||
cpsCategory = (config().get("CouchPotato", "cpsCategory")).split(',') # movie
|
|
||||||
sbCategory = (config().get("SickBeard", "sbCategory")).split(',') # tv
|
|
||||||
hpCategory = (config().get("HeadPhones", "hpCategory")).split(',') # music
|
|
||||||
mlCategory = (config().get("Mylar", "mlCategory")).split(',') # comics
|
|
||||||
gzCategory = (config().get("Gamez", "gzCategory")).split(',') # games
|
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -333,13 +380,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':
|
||||||
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
||||||
sys.exit(POSTPROCESS_ERROR)
|
sys.exit(config.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("MAIN: Par-check successful, but Par-repair disabled, exiting")
|
||||||
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
||||||
sys.exit(POSTPROCESS_NONE)
|
sys.exit(config.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("MAIN: Par-repair failed, setting status \"failed\"")
|
||||||
|
@ -369,11 +416,11 @@ 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.
|
||||||
download_id = ""
|
download_id = ""
|
||||||
if os.environ.has_key('NZBPR_COUCHPOTATO'):
|
if os.environ.has_key('NZBPR_COUCHPOTATO'):download_id = os.environ['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'])
|
||||||
nzbDir, inputName, inputCategory = (os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBFILENAME'], os.environ['NZBPP_CATEGORY'])
|
if result != 0: Logger.info("MAIN: A problem was reported in the autoProcess* script.")
|
||||||
# SABnzbd Pre 0.7.17
|
# SABnzbd Pre 0.7.17
|
||||||
elif len(sys.argv) == SABNZB_NO_OF_ARGUMENTS:
|
elif len(sys.argv) == config.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
|
||||||
|
@ -383,10 +430,10 @@ elif len(sys.argv) == SABNZB_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
|
||||||
Logger.info("MAIN: Script triggered from SABnzbd")
|
Logger.info("MAIN: Script triggered from SABnzbd")
|
||||||
clientAgent = "sabnzbd"
|
result = process(sys.argv[1], inputName=sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='')
|
||||||
nzbDir, inputName, status, inputCategory, download_id = (sys.argv[1], sys.argv[2], sys.argv[7], sys.argv[5], '')
|
if result != 0: Logger.info("MAIN: A problem was reported in the autoProcess* script.")
|
||||||
# SABnzbd 0.7.17+
|
# SABnzbd 0.7.17+
|
||||||
elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
elif len(sys.argv) >= config.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
|
||||||
|
@ -397,61 +444,37 @@ elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
||||||
# 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.info("MAIN: Script triggered from SABnzbd 0.7.17+")
|
||||||
clientAgent = "sabnzbd"
|
result = process(sys.argv[1], inputName=sys.argv[2], status=sys.argv[7], inputCategory=sys.argv[5], clientAgent = "sabnzbd", download_id='')
|
||||||
nzbDir, inputName, status, inputCategory, download_id = (sys.argv[1], sys.argv[2], sys.argv[7], sys.argv[5], '')
|
if result != 0:Logger.info("MAIN: A problem was reported in the autoProcess* script.")
|
||||||
else: # only CPS and SB supports this manual run for now.
|
else:
|
||||||
clientAgent = "manual"
|
# only CPS and SB supports this manual run for now.
|
||||||
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
||||||
|
|
||||||
Logger.info("MAIN: Running autoProcessMovie as a manual run...")
|
Logger.info("MAIN: Running autoProcessMovie as a manual run...")
|
||||||
nzbDir, inputName, status, inputCategory, download_id = ('Manual Run', 'Manual Run', 0, cpsCategory[0], '')
|
if process(get_dirnames("CouchPotato", cpsCategory[0]), inputName=get_dirnames("CouchPotato", cpsCategory[0]), status=0, inputCategory=cpsCategory[0], clientAgent = "manual", download_id='') != 0:
|
||||||
|
Logger.info("MAIN: A problem was reported in the autoProcessMovie script.")
|
||||||
|
|
||||||
Logger.info("MAIN: Running autoProcessTV as a manual run...")
|
Logger.info("MAIN: Running autoProcessTV as a manual run...")
|
||||||
dirNames = get_dirnames("SickBeard", sbCategory[0])
|
if process(get_dirnames("SickBeard", sbCategory[0]), inputName=get_dirnames("SickBeard", sbCategory[0]), status=0, clientAgent = "manual", inputCategory=sbCategory[0]) != 0:
|
||||||
nzbDir, inputName, status, inputCategory, = (dirNames, dirNames, 0, sbCategory[0])
|
Logger.info("MAIN: A problem was reported in the autoProcessTV script.")
|
||||||
|
|
||||||
Logger.info("MAIN: Running autoProcessMusic as a manual run...")
|
Logger.info("MAIN: Running autoProcessMusic as a manual run...")
|
||||||
dirNames = get_dirnames("HeadPhones", hpCategory[0])
|
if process(get_dirnames("HeadPhones", hpCategory[0]), inputName=get_dirnames("HeadPhones", hpCategory[0]), status=0, clientAgent = "manual", inputCategory=hpCategory[0]) != 0:
|
||||||
nzbDir, inputName, status, inputCategory = (dirNames, dirNames, 0, sbCategory[0])
|
Logger.info("MAIN: A problem was reported in the autoProcessMusic script.")
|
||||||
|
|
||||||
if inputCategory in cpsCategory:
|
Logger.info("MAIN: Running autoProcessComics as a manual run...")
|
||||||
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
|
if process(get_dirnames("Mylar", mlCategory[0]), inputName=get_dirnames("Mylar", mlCategory[0]), status=0,clientAgent="manual", inputCategory=mlCategory[0]) != 0:
|
||||||
result = autoProcessMovie.process(nzbDir, inputName, status, clientAgent, download_id, inputCategory)
|
Logger.info("MAIN: A problem was reported in the autoProcessComics script.")
|
||||||
elif inputCategory in sbCategory:
|
|
||||||
result = 0
|
Logger.info("MAIN: Running autoProcessGames as a manual run...")
|
||||||
if isinstance(nzbDir, list):
|
if process(get_dirnames("Gamez", gzCategory[0]), inputName=get_dirnames("Gamez", gzCategory[0]), status=0,clientAgent="manual", inputCategory=gzCategory[0]) != 0:
|
||||||
for dirName in nzbDir:
|
Logger.info("MAIN: A problem was reported in the autoProcessGames script.")
|
||||||
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
|
|
||||||
result = autoProcessTV.processEpisode(dirName, dirName, status, clientAgent, inputCategory)
|
|
||||||
if result !=0:break
|
|
||||||
else:
|
|
||||||
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName)
|
|
||||||
result = autoProcessTV.processEpisode(nzbDir, inputName, status, clientAgent, inputCategory)
|
|
||||||
elif inputCategory in hpCategory:
|
|
||||||
result = 0
|
|
||||||
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: break
|
|
||||||
else:
|
|
||||||
Logger.info("MAIN: Calling HeadPhones to post-process: %s", inputName)
|
|
||||||
result = autoProcessMusic.process(nzbDir, inputName, status, clientAgent, inputCategory)
|
|
||||||
elif inputCategory in mlCategory:
|
|
||||||
Logger.info("MAIN: Calling Mylar to post-process: %s", inputName)
|
|
||||||
result = autoProcessComics.processEpisode(nzbDir, inputName, status, inputCategory)
|
|
||||||
elif inputCategory in gzCategory:
|
|
||||||
Logger.info("MAIN: Calling Gamez to post-process: %s", inputName)
|
|
||||||
result = autoProcessGames.process(nzbDir, inputName, status, inputCategory)
|
|
||||||
else:
|
|
||||||
Logger.warning("MAIN: The download category %s does not match any category defined in autoProcessMedia.cfg. Exiting.", inputCategory)
|
|
||||||
sys.exit(POSTPROCESS_ERROR)
|
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
Logger.info("MAIN: The autoProcess* script completed successfully.")
|
Logger.info("MAIN: 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(POSTPROCESS_SUCCESS)
|
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS)
|
||||||
else:
|
else:
|
||||||
Logger.info("MAIN: A problem was reported in the autoProcess* script.")
|
Logger.info("MAIN: 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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
|
@ -1,38 +0,0 @@
|
||||||
import os
|
|
||||||
import ConfigParser
|
|
||||||
|
|
||||||
# init paths
|
|
||||||
MY_FULLNAME = os.path.normpath(os.path.abspath(__file__))
|
|
||||||
MY_NAME = os.path.basename(MY_FULLNAME)
|
|
||||||
PROG_DIR = os.path.dirname(MY_FULLNAME)
|
|
||||||
|
|
||||||
# init config file names
|
|
||||||
CONFIG_FILE = os.path.join(PROG_DIR, "autoProcessMedia.cfg")
|
|
||||||
SAMPLE_CONFIG_FILE = os.path.join(PROG_DIR, "autoProcessMedia.cfg.sample")
|
|
||||||
MOVIE_CONFIG_FILE = os.path.join(PROG_DIR, "autoProcessMovie.cfg")
|
|
||||||
TV_CONFIG_FILE = os.path.join(PROG_DIR, "autoProcessTv.cfg")
|
|
||||||
LOG_FILE = os.path.join(PROG_DIR, "postprocess.log")
|
|
||||||
|
|
||||||
class config(object):
|
|
||||||
|
|
||||||
# link error handling classes
|
|
||||||
Error = ConfigParser.Error
|
|
||||||
NoSectionError = ConfigParser.NoSectionError
|
|
||||||
NoOptionError = ConfigParser.NoOptionError
|
|
||||||
DuplicateSectionError = ConfigParser.DuplicateSectionError
|
|
||||||
InterpolationError = ConfigParser.InterpolationError
|
|
||||||
InterpolationMissingOptionError = ConfigParser.InterpolationMissingOptionError
|
|
||||||
InterpolationSyntaxError = ConfigParser.InterpolationSyntaxError
|
|
||||||
InterpolationDepthError = ConfigParser.InterpolationDepthError
|
|
||||||
ParsingError = ConfigParser.ParsingError
|
|
||||||
MissingSectionHeaderError = ConfigParser.MissingSectionHeaderError
|
|
||||||
|
|
||||||
def __new__(cls, *file):
|
|
||||||
if not file:
|
|
||||||
file = CONFIG_FILE
|
|
||||||
|
|
||||||
# load config
|
|
||||||
config = ConfigParser.ConfigParser()
|
|
||||||
config.optionxform = str
|
|
||||||
if config.read(file):
|
|
||||||
return config
|
|
|
@ -60,25 +60,32 @@
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
# Exit codes used by NZBGet
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from nzbtomedia.autoProcess.autoProcessComics import autoProcessComics
|
||||||
|
from nzbtomedia.migratecfg import migratecfg
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames
|
||||||
|
|
||||||
import autoProcess.migratecfg as migratecfg
|
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
|
||||||
import autoProcess.autoProcessComics as autoProcessComics
|
if migratecfg().migrate():
|
||||||
from autoProcess.nzbToMediaEnv import *
|
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
||||||
from autoProcess.nzbToMediaUtil import *
|
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
||||||
|
migratecfg().addnzbget()
|
||||||
|
|
||||||
#check to migrate old cfg before trying to load.
|
nzbtomedia_configure_logging(config.LOG_FILE)
|
||||||
if os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample")):
|
Logger = logging.getLogger(__name__)
|
||||||
migratecfg.migrate()
|
Logger.info("====================") # Seperate old from new log
|
||||||
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
Logger.info("nzbToMylar %s", config.NZBTOMEDIA_VERSION)
|
||||||
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
|
||||||
migratecfg.addnzbget()
|
|
||||||
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
Logger = logging.getLogger(__name__)
|
else:
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
Logger.info("====================") # Seperate old from new log
|
# mylar category
|
||||||
Logger.info("nzbToMylar %s", VERSION)
|
mlCategory = (config().get("Mylar", "mlCategory")).split(',') # tv
|
||||||
|
|
||||||
WakeUp()
|
WakeUp()
|
||||||
|
|
||||||
|
@ -87,25 +94,18 @@ WakeUp()
|
||||||
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.info("MAIN: Script triggered from NZBGet (11.0 or later).")
|
||||||
|
|
||||||
# NZBGet argv: all passed as environment variables.
|
|
||||||
# Exit codes used by NZBGet
|
|
||||||
POSTPROCESS_PARCHECK=92
|
|
||||||
POSTPROCESS_SUCCESS=93
|
|
||||||
POSTPROCESS_ERROR=94
|
|
||||||
POSTPROCESS_NONE=95
|
|
||||||
|
|
||||||
# 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("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
||||||
sys.exit(POSTPROCESS_ERROR)
|
sys.exit(config.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("MAIN: Par-check successful, but Par-repair disabled, exiting")
|
||||||
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
||||||
sys.exit(POSTPROCESS_NONE)
|
sys.exit(config.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("MAIN: Par-repair failed, setting status \"failed\"")
|
||||||
|
@ -135,9 +135,9 @@ 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.
|
||||||
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessComics...")
|
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessComics...")
|
||||||
result = autoProcessComics.processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status)
|
result = autoProcessComics().processEpisode(os.environ['NZBPP_DIRECTORY'], os.environ['NZBPP_NZBNAME'], status)
|
||||||
# SABnzbd Pre 0.7.17
|
# SABnzbd Pre 0.7.17
|
||||||
elif len(sys.argv) == SABNZB_NO_OF_ARGUMENTS:
|
elif len(sys.argv) == config.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,9 +147,9 @@ elif len(sys.argv) == SABNZB_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
|
||||||
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessComics...")
|
Logger.info("MAIN: Script triggered from SABnzbd, starting autoProcessComics...")
|
||||||
result = autoProcessComics.processEpisode(sys.argv[1], sys.argv[3], sys.argv[7])
|
result = autoProcessComics().processEpisode(sys.argv[1], sys.argv[3], sys.argv[7])
|
||||||
# SABnzbd 0.7.17+
|
# SABnzbd 0.7.17+
|
||||||
elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
elif len(sys.argv) >= config.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
|
||||||
|
@ -160,17 +160,23 @@ elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
||||||
# 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.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessComics...")
|
||||||
result = autoProcessComics.processEpisode(sys.argv[1], sys.argv[3], sys.argv[7])
|
result = autoProcessComics().processEpisode(sys.argv[1], sys.argv[3], sys.argv[7])
|
||||||
else:
|
else:
|
||||||
|
result = 0
|
||||||
|
|
||||||
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
Logger.warn("MAIN: Invalid number of arguments received from client.")
|
||||||
Logger.info("MAIN: Running autoProcessComics as a manual run...")
|
Logger.info("MAIN: Running autoProcessComics as a manual run...")
|
||||||
result = autoProcessComics.processEpisode('Manual Run', 'Manual Run', 0)
|
|
||||||
|
for dirName in get_dirnames("Mylar", mlCategory[0]):
|
||||||
|
Logger.info("MAIN: Calling Mylar to post-process: %s", dirName)
|
||||||
|
result = autoProcessComics().processEpisode(dirName, dirName, 0)
|
||||||
|
if result != 0: break
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
Logger.info("MAIN: The autoProcessComics script completed successfully.")
|
Logger.info("MAIN: 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(POSTPROCESS_SUCCESS)
|
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS)
|
||||||
else:
|
else:
|
||||||
Logger.info("MAIN: A problem was reported in the autoProcessComics script.")
|
Logger.info("MAIN: 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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
||||||
|
|
|
@ -123,33 +123,31 @@
|
||||||
|
|
||||||
### NZBGET POST-PROCESSING SCRIPT ###
|
### NZBGET POST-PROCESSING SCRIPT ###
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV
|
||||||
|
from nzbtomedia.migratecfg import migratecfg
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import nzbtomedia_configure_logging, WakeUp, get_dirnames
|
||||||
|
|
||||||
import autoProcess.migratecfg as migratecfg
|
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
|
||||||
import autoProcess.autoProcessTV as autoProcessTV
|
if migratecfg().migrate():
|
||||||
from autoProcess.nzbToMediaEnv import *
|
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
||||||
from autoProcess.nzbToMediaUtil import *
|
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
||||||
|
migratecfg().addnzbget()
|
||||||
|
|
||||||
# NZBGet argv: all passed as environment variables.
|
nzbtomedia_configure_logging(config.LOG_FILE)
|
||||||
# Exit codes used by NZBGet
|
Logger = logging.getLogger(__name__)
|
||||||
POSTPROCESS_PARCHECK = 92
|
Logger.info("====================") # Seperate old from new log
|
||||||
POSTPROCESS_SUCCESS = 93
|
Logger.info("nzbToSickBeard %s", config.NZBTOMEDIA_VERSION)
|
||||||
POSTPROCESS_ERROR = 94
|
|
||||||
POSTPROCESS_NONE = 95
|
|
||||||
|
|
||||||
#check to migrate old cfg before trying to load.
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
if os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample")):
|
else:
|
||||||
migratecfg.migrate()
|
sys.exit(-1)
|
||||||
# check to write settings from nzbGet UI to autoProcessMedia.cfg.
|
|
||||||
if os.environ.has_key('NZBOP_SCRIPTDIR'):
|
|
||||||
migratecfg.addnzbget()
|
|
||||||
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
# sickbeard category
|
||||||
Logger = logging.getLogger(__name__)
|
sbCategory = (config().get("SickBeard", "sbCategory")).split(',') # tv
|
||||||
|
|
||||||
Logger.info("====================") # Seperate old from new log
|
|
||||||
Logger.info("nzbToSickBeard %s", VERSION)
|
|
||||||
|
|
||||||
WakeUp()
|
WakeUp()
|
||||||
|
|
||||||
|
@ -163,13 +161,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':
|
||||||
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
Logger.error("MAIN: Please enable option \"Unpack\" in nzbget configuration file, exiting")
|
||||||
sys.exit(POSTPROCESS_ERROR)
|
sys.exit(config.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("MAIN: Par-check successful, but Par-repair disabled, exiting")
|
||||||
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
Logger.info("MAIN: Please check your Par-repair settings for future downloads.")
|
||||||
sys.exit(POSTPROCESS_NONE)
|
sys.exit(config.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("MAIN: Par-repair failed, setting status \"failed\"")
|
||||||
|
@ -200,9 +198,9 @@ 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.
|
||||||
Logger.info("MAIN: Script triggered from NZBGet, starting autoProcessTV...")
|
Logger.info("MAIN: 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) == SABNZB_NO_OF_ARGUMENTS:
|
elif len(sys.argv) == config.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
|
||||||
|
@ -213,9 +211,9 @@ elif len(sys.argv) == SABNZB_NO_OF_ARGUMENTS:
|
||||||
# 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.info("MAIN: 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) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
elif len(sys.argv) >= config.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
|
||||||
|
@ -227,24 +225,23 @@ elif len(sys.argv) >= SABNZB_0717_NO_OF_ARGUMENTS:
|
||||||
# 8 Failure URL
|
# 8 Failure URL
|
||||||
Logger.info("MAIN: Script triggered from SABnzbd 0.7.17+, starting autoProcessTV...")
|
Logger.info("MAIN: 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
|
||||||
sbCategory = (config().get("SickBeard", "sbCategory")).split(',') # tv
|
|
||||||
dirNames = get_dirnames("SickBeard", sbCategory[0])
|
|
||||||
|
|
||||||
Logger.debug("MAIN: Invalid number of arguments received from client.")
|
Logger.debug("MAIN: Invalid number of arguments received from client.")
|
||||||
Logger.info("MAIN: Running autoProcessTV as a manual run...")
|
Logger.info("MAIN: Running autoProcessTV as a manual run...")
|
||||||
|
|
||||||
for dirName in dirNames:
|
for dirName in get_dirnames("SickBeard", sbCategory[0]):
|
||||||
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", dirName)
|
Logger.info("MAIN: Calling Sick-Beard to post-process: %s", dirName)
|
||||||
result = autoProcessTV.processEpisode(dirName, dirName, 0)
|
result = autoProcessTV().processEpisode(dirName, dirName, 0)
|
||||||
if result != 0: break
|
if result != 0: break
|
||||||
|
|
||||||
if result == 0:
|
if result == 0:
|
||||||
Logger.info("MAIN: The autoProcessTV script completed successfully.")
|
Logger.info("MAIN: 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(POSTPROCESS_SUCCESS)
|
sys.exit(config.NZBGET_POSTPROCESS_SUCCESS)
|
||||||
else:
|
else:
|
||||||
Logger.info("MAIN: A problem was reported in the autoProcessTV script.")
|
Logger.info("MAIN: 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(POSTPROCESS_ERROR)
|
sys.exit(config.NZBGET_POSTPROCESS_ERROR)
|
||||||
|
|
144
nzbtomedia/Transcoder.py
Normal file
144
nzbtomedia/Transcoder.py
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
import errno
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from subprocess import call
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
|
||||||
|
|
||||||
|
class Transcoder:
|
||||||
|
def Transcode_directory(self, dirName):
|
||||||
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
if os.name == 'nt':
|
||||||
|
ffmpeg = os.path.join(os.path.dirname(sys.argv[0]), 'ffmpeg\\bin\\ffmpeg.exe') # note, will need to package in this dir.
|
||||||
|
useNiceness = False
|
||||||
|
if not os.path.isfile(ffmpeg): # problem
|
||||||
|
Logger.error("ffmpeg not found. ffmpeg needs to be located at: %s", ffmpeg)
|
||||||
|
Logger.info("Cannot transcode files in folder %s", dirName)
|
||||||
|
return 1 # failure
|
||||||
|
else:
|
||||||
|
if call(['which', 'ffmpeg']) != 0:
|
||||||
|
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.
|
||||||
|
Logger.error("Failed to install ffmpeg. Please install manually")
|
||||||
|
Logger.info("Cannot transcode files in folder %s", dirName)
|
||||||
|
return 1 # failure
|
||||||
|
else:
|
||||||
|
ffmpeg = 'ffmpeg'
|
||||||
|
else:
|
||||||
|
ffmpeg = 'ffmpeg'
|
||||||
|
useNiceness = True
|
||||||
|
|
||||||
|
Logger.info("Loading config from %s", config.CONFIG_FILE)
|
||||||
|
|
||||||
|
if not config():
|
||||||
|
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
mediaContainer = (config().get("Extensions", "mediaExtensions")).split(',')
|
||||||
|
duplicate = int(config().get("Transcoder", "duplicate"))
|
||||||
|
ignoreExtensions = (config().get("Transcoder", "ignoreExtensions")).split(',')
|
||||||
|
outputVideoExtension = config().get("Transcoder", "outputVideoExtension").strip()
|
||||||
|
outputVideoCodec = config().get("Transcoder", "outputVideoCodec").strip()
|
||||||
|
outputVideoPreset = config().get("Transcoder", "outputVideoPreset").strip()
|
||||||
|
outputVideoFramerate = config().get("Transcoder", "outputVideoFramerate").strip()
|
||||||
|
outputVideoBitrate = config().get("Transcoder", "outputVideoBitrate").strip()
|
||||||
|
outputAudioCodec = config().get("Transcoder", "outputAudioCodec").strip()
|
||||||
|
outputAudioBitrate = config().get("Transcoder", "outputAudioBitrate").strip()
|
||||||
|
outputSubtitleCodec = config().get("Transcoder", "outputSubtitleCodec").strip()
|
||||||
|
outputFastStart = int(config().get("Transcoder", "outputFastStart"))
|
||||||
|
outputQualityPercent = int(config().get("Transcoder", "outputQualityPercent"))
|
||||||
|
|
||||||
|
niceness = None
|
||||||
|
if useNiceness:niceness = int(config().get("Transcoder", "niceness"))
|
||||||
|
|
||||||
|
map(lambda ext: ext.strip(), mediaContainer)
|
||||||
|
map(lambda ext: ext.strip(), ignoreExtensions)
|
||||||
|
|
||||||
|
Logger.info("Checking for files to be transcoded")
|
||||||
|
final_result = 0 # initialize as successful
|
||||||
|
for dirpath, dirnames, filenames in os.walk(dirName):
|
||||||
|
for file in filenames:
|
||||||
|
filePath = os.path.join(dirpath, file)
|
||||||
|
name, ext = os.path.splitext(filePath)
|
||||||
|
if ext in mediaContainer: # If the file is a video file
|
||||||
|
if ext in ignoreExtensions:
|
||||||
|
Logger.info("No need to transcode video type %s", ext)
|
||||||
|
continue
|
||||||
|
if ext == outputVideoExtension: # we need to change the name to prevent overwriting itself.
|
||||||
|
outputVideoExtension = '-transcoded' + outputVideoExtension # adds '-transcoded.ext'
|
||||||
|
newfilePath = os.path.normpath(name + outputVideoExtension)
|
||||||
|
|
||||||
|
command = [ffmpeg, '-loglevel', 'warning', '-i', filePath, '-map', '0'] # -map 0 takes all input streams
|
||||||
|
|
||||||
|
if useNiceness:
|
||||||
|
command = ['nice', '-%d' % niceness] + command
|
||||||
|
|
||||||
|
if len(outputVideoCodec) > 0:
|
||||||
|
command.append('-c:v')
|
||||||
|
command.append(outputVideoCodec)
|
||||||
|
if outputVideoCodec == 'libx264' and outputVideoPreset:
|
||||||
|
command.append('-preset')
|
||||||
|
command.append(outputVideoPreset)
|
||||||
|
else:
|
||||||
|
command.append('-c:v')
|
||||||
|
command.append('copy')
|
||||||
|
if len(outputVideoFramerate) > 0:
|
||||||
|
command.append('-r')
|
||||||
|
command.append(str(outputVideoFramerate))
|
||||||
|
if len(outputVideoBitrate) > 0:
|
||||||
|
command.append('-b:v')
|
||||||
|
command.append(str(outputVideoBitrate))
|
||||||
|
if len(outputAudioCodec) > 0:
|
||||||
|
command.append('-c:a')
|
||||||
|
command.append(outputAudioCodec)
|
||||||
|
if outputAudioCodec == 'aac': # Allow users to use the experimental AAC codec that's built into recent versions of ffmpeg
|
||||||
|
command.append('-strict')
|
||||||
|
command.append('-2')
|
||||||
|
else:
|
||||||
|
command.append('-c:a')
|
||||||
|
command.append('copy')
|
||||||
|
if len(outputAudioBitrate) > 0:
|
||||||
|
command.append('-b:a')
|
||||||
|
command.append(str(outputAudioBitrate))
|
||||||
|
if outputFastStart > 0:
|
||||||
|
command.append('-movflags')
|
||||||
|
command.append('+faststart')
|
||||||
|
if outputQualityPercent > 0:
|
||||||
|
command.append('-q:a')
|
||||||
|
command.append(str(outputQualityPercent))
|
||||||
|
if len(outputSubtitleCodec) > 0: # Not every subtitle codec can be used for every video container format!
|
||||||
|
command.append('-c:s')
|
||||||
|
command.append(outputSubtitleCodec) # http://en.wikibooks.org/wiki/FFMPEG_An_Intermediate_Guide/subtitle_options
|
||||||
|
else:
|
||||||
|
command.append('-sn') # Don't copy the subtitles over
|
||||||
|
command.append(newfilePath)
|
||||||
|
|
||||||
|
try: # Try to remove the file that we're transcoding to just in case. (ffmpeg will return an error if it already exists for some reason)
|
||||||
|
os.remove(newfilePath)
|
||||||
|
except OSError, e:
|
||||||
|
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)
|
||||||
|
except Exception, e:
|
||||||
|
Logger.debug("Error when removing transcoding target: %s", e)
|
||||||
|
|
||||||
|
Logger.info("Transcoding video: %s", file)
|
||||||
|
cmd = ""
|
||||||
|
for item in command:
|
||||||
|
cmd = cmd + " " + item
|
||||||
|
Logger.debug("calling command:%s", cmd)
|
||||||
|
result = 1 # set result to failed in case call fails.
|
||||||
|
try:
|
||||||
|
result = call(command)
|
||||||
|
except:
|
||||||
|
Logger.exception("Transcoding of video %s has failed", filePath)
|
||||||
|
if result == 0:
|
||||||
|
Logger.info("Transcoding of video %s to %s succeeded", filePath, newfilePath)
|
||||||
|
if duplicate == 0: # we get rid of the original file
|
||||||
|
os.unlink(filePath)
|
||||||
|
else:
|
||||||
|
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.
|
||||||
|
final_result = final_result + result
|
||||||
|
return final_result
|
72
nzbtomedia/autoProcess/autoProcessComics.py
Normal file
72
nzbtomedia/autoProcess/autoProcessComics.py
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import logging
|
||||||
|
import urllib
|
||||||
|
import requests
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import convert_to_ascii
|
||||||
|
|
||||||
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
class autoProcessComics:
|
||||||
|
def processEpisode(self, dirName, nzbName=None, status=0, clientAgent='manual', inputCategory=None):
|
||||||
|
if dirName is None:
|
||||||
|
Logger.error("No directory was given!")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
|
||||||
|
|
||||||
|
Logger.info("Loading config from %s", config.CONFIG_FILE)
|
||||||
|
|
||||||
|
section = "Mylar"
|
||||||
|
if inputCategory != None and config().has_section(inputCategory):
|
||||||
|
section = inputCategory
|
||||||
|
host = config().get(section, "host")
|
||||||
|
port = config().get(section, "port")
|
||||||
|
username = config().get(section, "username")
|
||||||
|
password = config().get(section, "password")
|
||||||
|
try:
|
||||||
|
ssl = int(config().get(section, "ssl"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
ssl = 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
web_root = config().get(section, "web_root")
|
||||||
|
except config.NoOptionError:
|
||||||
|
web_root = ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
watch_dir = config().get(section, "watch_dir")
|
||||||
|
except config.NoOptionError:
|
||||||
|
watch_dir = ""
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
||||||
|
|
||||||
|
if dirName == "Manual Run" and watch_dir != "":
|
||||||
|
dirName = watch_dir
|
||||||
|
|
||||||
|
params['nzb_folder'] = dirName
|
||||||
|
if nzbName != None:
|
||||||
|
params['nzb_name'] = nzbName
|
||||||
|
|
||||||
|
if ssl:
|
||||||
|
protocol = "https://"
|
||||||
|
else:
|
||||||
|
protocol = "http://"
|
||||||
|
|
||||||
|
url = protocol + host + ":" + port + web_root + "/post_process?" + urllib.urlencode(params)
|
||||||
|
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url, auth=(username, password))
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
if r.ok:
|
||||||
|
Logger.info("%s", r.content)
|
||||||
|
|
||||||
|
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
|
72
nzbtomedia/autoProcess/autoProcessGames.py
Normal file
72
nzbtomedia/autoProcess/autoProcessGames.py
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
|
import requests
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import convert_to_ascii
|
||||||
|
|
||||||
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
class autoProcessGames:
|
||||||
|
def process(self, dirName, nzbName=None, status=0, clientAgent='manual', inputCategory=None):
|
||||||
|
if dirName is None:
|
||||||
|
Logger.error("No directory was given!")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
|
||||||
|
|
||||||
|
Logger.info("Loading config from %s", config.CONFIG_FILE)
|
||||||
|
|
||||||
|
status = int(status)
|
||||||
|
|
||||||
|
section = "Gamez"
|
||||||
|
if inputCategory != None and config().has_section(inputCategory):
|
||||||
|
section = inputCategory
|
||||||
|
|
||||||
|
host = config().get(section, "host")
|
||||||
|
port = config().get(section, "port")
|
||||||
|
apikey = config().get(section, "apikey")
|
||||||
|
|
||||||
|
try:
|
||||||
|
ssl = int(config().get(section, "ssl"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
ssl = 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
web_root = config().get(section, "web_root")
|
||||||
|
except config.NoOptionError:
|
||||||
|
web_root = ""
|
||||||
|
|
||||||
|
if ssl:
|
||||||
|
protocol = "https://"
|
||||||
|
else:
|
||||||
|
protocol = "http://"
|
||||||
|
|
||||||
|
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
||||||
|
|
||||||
|
baseURL = protocol + host + ":" + port + web_root + "/api?api_key=" + apikey + "&mode="
|
||||||
|
|
||||||
|
fields = nzbName.split("-")
|
||||||
|
gamezID = fields[0].replace("[","").replace("]","").replace(" ","")
|
||||||
|
downloadStatus = 'Wanted'
|
||||||
|
if status == 0:
|
||||||
|
downloadStatus = 'Downloaded'
|
||||||
|
|
||||||
|
url = baseURL + "UPDATEREQUESTEDSTATUS&db_id=" + gamezID + "&status=" + downloadStatus
|
||||||
|
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url)
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
result = json.load(r.content)
|
||||||
|
Logger.info("Gamez returned %s", result)
|
||||||
|
if result['success']:
|
||||||
|
Logger.info("Status for %s has been set to %s in Gamez", gamezID, downloadStatus)
|
||||||
|
return 0 # Success
|
||||||
|
else:
|
||||||
|
Logger.error("Status for %s has NOT been updated in Gamez", gamezID)
|
||||||
|
return 1 # failure
|
324
nzbtomedia/autoProcess/autoProcessMovie.py
Normal file
324
nzbtomedia/autoProcess/autoProcessMovie.py
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
|
import urllib
|
||||||
|
import requests
|
||||||
|
import shutil
|
||||||
|
import json
|
||||||
|
from nzbtomedia.Transcoder import Transcoder
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions
|
||||||
|
from nzbtomedia.nzbToMediaUtil import getDirectorySize, convert_to_ascii
|
||||||
|
|
||||||
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
class autoProcessMovie:
|
||||||
|
def get_imdb(self, nzbName, dirName):
|
||||||
|
imdbid = ""
|
||||||
|
|
||||||
|
a = nzbName.find('.cp(') + 4 #search for .cptt( in nzbName
|
||||||
|
b = nzbName[a:].find(')') + a
|
||||||
|
if a > 3: # a == 3 if not exist
|
||||||
|
imdbid = nzbName[a:b]
|
||||||
|
|
||||||
|
if imdbid:
|
||||||
|
Logger.info("Found movie id %s in name", imdbid)
|
||||||
|
return imdbid
|
||||||
|
|
||||||
|
a = dirName.find('.cp(') + 4 #search for .cptt( in dirname
|
||||||
|
b = dirName[a:].find(')') + a
|
||||||
|
if a > 3: # a == 3 if not exist
|
||||||
|
imdbid = dirName[a:b]
|
||||||
|
|
||||||
|
if imdbid:
|
||||||
|
Logger.info("Found movie id %s in directory", imdbid)
|
||||||
|
return imdbid
|
||||||
|
|
||||||
|
else:
|
||||||
|
Logger.debug("Could not find an imdb id in directory or name")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def get_movie_info(self, baseURL, imdbid, download_id):
|
||||||
|
|
||||||
|
movie_id = ""
|
||||||
|
movie_status = None
|
||||||
|
release_status = None
|
||||||
|
if not imdbid and not download_id:
|
||||||
|
return movie_id, imdbid, download_id, movie_status, release_status
|
||||||
|
|
||||||
|
releaselist = []
|
||||||
|
movieid = []
|
||||||
|
moviestatus = []
|
||||||
|
library = []
|
||||||
|
release = []
|
||||||
|
offset = int(0)
|
||||||
|
while True:
|
||||||
|
url = baseURL + "media.list/?status=active&release_status=snatched&limit_offset=50," + str(offset)
|
||||||
|
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url)
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
break
|
||||||
|
|
||||||
|
movieid2 = []
|
||||||
|
library2 = []
|
||||||
|
release2 = []
|
||||||
|
moviestatus2 = []
|
||||||
|
try:
|
||||||
|
result = json.load(r.content)
|
||||||
|
movieid2 = [item["_id"] for item in result["movies"]]
|
||||||
|
for item in result["movies"]:
|
||||||
|
if "identifier" in item:
|
||||||
|
library2.append(item["identifier"])
|
||||||
|
else:
|
||||||
|
library2.append(item["identifiers"]["imdb"])
|
||||||
|
release2 = [item["releases"] for item in result["movies"]]
|
||||||
|
moviestatus2 = [item["status"] for item in result["movies"]]
|
||||||
|
except:
|
||||||
|
Logger.exception("Unable to parse json data for movies")
|
||||||
|
break
|
||||||
|
|
||||||
|
movieid.extend(movieid2)
|
||||||
|
moviestatus.extend(moviestatus2)
|
||||||
|
library.extend(library2)
|
||||||
|
release.extend(release2)
|
||||||
|
if len(movieid2) < int(50): # finished parsing list of movies. Time to break.
|
||||||
|
break
|
||||||
|
offset = offset + 50
|
||||||
|
|
||||||
|
result = None # reset
|
||||||
|
for index in range(len(movieid)):
|
||||||
|
releaselist1 = [item for item in release[index] if item["status"] == "snatched" and "download_info" in item]
|
||||||
|
if download_id:
|
||||||
|
releaselist = [item for item in releaselist1 if item["download_info"]["id"].lower() == download_id.lower()]
|
||||||
|
else:
|
||||||
|
releaselist = releaselist1
|
||||||
|
|
||||||
|
if imdbid and library[index] == imdbid:
|
||||||
|
movie_id = str(movieid[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)
|
||||||
|
if not download_id and len(releaselist) == 1:
|
||||||
|
download_id = releaselist[0]["download_info"]["id"]
|
||||||
|
|
||||||
|
elif not imdbid and download_id and len(releaselist) > 0:
|
||||||
|
movie_id = str(movieid[index])
|
||||||
|
movie_status = str(moviestatus[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)
|
||||||
|
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if len(releaselist) == 1:
|
||||||
|
release_status = releaselist[0]["status"]
|
||||||
|
Logger.debug("Found a single release with download_id: %s. Release status is: %s", download_id, release_status)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
if not movie_id:
|
||||||
|
Logger.exception("Could not parse database results to determine imdbid or movie id")
|
||||||
|
|
||||||
|
return movie_id, imdbid, download_id, movie_status, release_status
|
||||||
|
|
||||||
|
def get_status(self, baseURL, movie_id, download_id):
|
||||||
|
result = None
|
||||||
|
movie_status = None
|
||||||
|
release_status = None
|
||||||
|
if not movie_id:
|
||||||
|
return movie_status, release_status
|
||||||
|
|
||||||
|
Logger.debug("Looking for status of movie: %s", movie_id)
|
||||||
|
url = baseURL + "media.get/?id=" + str(movie_id)
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url)
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = json.load(r.content)
|
||||||
|
movie_status = str(result["media"]["status"])
|
||||||
|
Logger.debug("This movie is marked as status %s in CouchPotatoServer", movie_status)
|
||||||
|
except:
|
||||||
|
Logger.exception("Could not find a status for this movie")
|
||||||
|
|
||||||
|
try:
|
||||||
|
if len(result["media"]["releases"]) == 1 and result["media"]["releases"][0]["status"] == "done":
|
||||||
|
release_status = result["media"]["releases"][0]["status"]
|
||||||
|
else:
|
||||||
|
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:
|
||||||
|
release_status = release_status_list[0]
|
||||||
|
Logger.debug("This release is marked as status %s in CouchPotatoServer", release_status)
|
||||||
|
except: # index out of range/doesn't exist?
|
||||||
|
Logger.exception("Could not find a status for this release")
|
||||||
|
|
||||||
|
return movie_status, release_status
|
||||||
|
|
||||||
|
def process(self, dirName, nzbName=None, status=0, clientAgent = "manual", download_id = "", inputCategory=None):
|
||||||
|
if dirName is None:
|
||||||
|
Logger.error("No directory was given!")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
|
||||||
|
Logger.info("Loading config from %s", config.CONFIG_FILE)
|
||||||
|
|
||||||
|
status = int(status)
|
||||||
|
|
||||||
|
section = "CouchPotato"
|
||||||
|
if inputCategory != None and config().has_section(inputCategory):
|
||||||
|
section = inputCategory
|
||||||
|
|
||||||
|
host = config().get(section, "host")
|
||||||
|
port = config().get(section, "port")
|
||||||
|
apikey = config().get(section, "apikey")
|
||||||
|
delay = float(config().get(section, "delay"))
|
||||||
|
method = config().get(section, "method")
|
||||||
|
delete_failed = int(config().get(section, "delete_failed"))
|
||||||
|
wait_for = int(config().get(section, "wait_for"))
|
||||||
|
try:
|
||||||
|
TimePerGiB = int(config().get(section, "TimePerGiB"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
|
||||||
|
try:
|
||||||
|
ssl = int(config().get(section, "ssl"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
ssl = 0
|
||||||
|
try:
|
||||||
|
web_root = config().get(section, "web_root")
|
||||||
|
except config.NoOptionError:
|
||||||
|
web_root = ""
|
||||||
|
try:
|
||||||
|
transcode = int(config().get("Transcoder", "transcode"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
transcode = 0
|
||||||
|
try:
|
||||||
|
remoteCPS = int(config().get(section, "remoteCPS"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
remoteCPS = 0
|
||||||
|
|
||||||
|
nzbName = str(nzbName) # make sure it is a string
|
||||||
|
|
||||||
|
imdbid = self.get_imdb(nzbName, dirName)
|
||||||
|
|
||||||
|
if ssl:
|
||||||
|
protocol = "https://"
|
||||||
|
else:
|
||||||
|
protocol = "http://"
|
||||||
|
# don't delay when we are calling this script manually.
|
||||||
|
if clientAgent == "manual":
|
||||||
|
delay = 0
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
process_all_exceptions(nzbName.lower(), dirName)
|
||||||
|
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
||||||
|
|
||||||
|
if status == 0:
|
||||||
|
if transcode == 1:
|
||||||
|
result = Transcoder().Transcode_directory(dirName)
|
||||||
|
if result == 0:
|
||||||
|
Logger.debug("Transcoding succeeded for files in %s", dirName)
|
||||||
|
else:
|
||||||
|
Logger.warning("Transcoding failed for files in %s", dirName)
|
||||||
|
|
||||||
|
if method == "manage":
|
||||||
|
command = "manage.update"
|
||||||
|
else:
|
||||||
|
command = "renamer.scan"
|
||||||
|
if clientAgent != "manual" and download_id != None:
|
||||||
|
if remoteCPS == 1:
|
||||||
|
command = command + "/?downloader=" + clientAgent + "&download_id=" + download_id
|
||||||
|
else:
|
||||||
|
command = command + "/?media_folder=" + urllib.quote(dirName) + "&downloader=" + clientAgent + "&download_id=" + download_id
|
||||||
|
|
||||||
|
dirSize = getDirectorySize(dirName) # get total directory size to calculate needed processing time.
|
||||||
|
TIME_OUT2 = int(TimePerGiB) * dirSize # Couchpotato needs to complete all moving and renaming before returning the status.
|
||||||
|
TIME_OUT2 += 60 # Add an extra minute for over-head/processing/metadata.
|
||||||
|
socket.setdefaulttimeout(int(TIME_OUT2)) #initialize socket timeout. We may now be able to remove the delays from the wait_for section below? If true, this should exit on first loop.
|
||||||
|
|
||||||
|
url = baseURL + command
|
||||||
|
|
||||||
|
Logger.info("Waiting for %s seconds to allow CPS to process newly extracted files", str(delay))
|
||||||
|
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url)
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
result = json.load(r.content)
|
||||||
|
Logger.info("CouchPotatoServer returned %s", result)
|
||||||
|
if result['success']:
|
||||||
|
Logger.info("%s scan started on CouchPotatoServer for %s", method, nzbName)
|
||||||
|
else:
|
||||||
|
Logger.error("%s scan has NOT started on CouchPotatoServer for %s. Exiting", method, nzbName)
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
else:
|
||||||
|
Logger.info("Download of %s has failed.", nzbName)
|
||||||
|
Logger.info("Trying to re-cue the next highest ranked release")
|
||||||
|
|
||||||
|
if not movie_id:
|
||||||
|
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.error("Exiting autoProcessMovie script")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
url = baseURL + "movie.searcher.try_next/?media_id=" + movie_id
|
||||||
|
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url)
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
Logger.info("%s", r.content)
|
||||||
|
Logger.info("Movie %s set to try the next best release on CouchPotatoServer", movie_id)
|
||||||
|
if delete_failed and not dirName in ['sys.argv[0]','/','']:
|
||||||
|
Logger.info("Deleting failed files and folder %s", dirName)
|
||||||
|
try:
|
||||||
|
shutil.rmtree(dirName)
|
||||||
|
except:
|
||||||
|
Logger.exception("Unable to delete folder %s", dirName)
|
||||||
|
return 0 # success
|
||||||
|
|
||||||
|
if clientAgent == "manual":
|
||||||
|
return 0 # success
|
||||||
|
if not download_id:
|
||||||
|
return 1 # just to be sure TorrentToMedia doesn't start deleting files as we havent verified changed status.
|
||||||
|
|
||||||
|
# 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
|
||||||
|
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?
|
||||||
|
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.
|
||||||
|
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)
|
||||||
|
return 0 # success
|
||||||
|
datetime.time.sleep(pause_for) # Just stop this looping infinitely and hogging resources for 2 minutes ;)
|
||||||
|
else:
|
||||||
|
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)
|
||||||
|
return 0 # success
|
||||||
|
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)
|
||||||
|
return 1 # failure
|
100
nzbtomedia/autoProcess/autoProcessMusic.py
Normal file
100
nzbtomedia/autoProcess/autoProcessMusic.py
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
|
import requests
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, getDirectorySize
|
||||||
|
|
||||||
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
class autoProcessMusic:
|
||||||
|
def process(self, dirName, nzbName=None, status=0, clientAgent="manual", inputCategory=None):
|
||||||
|
if dirName is None:
|
||||||
|
Logger.error("No directory was given!")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
|
||||||
|
|
||||||
|
Logger.info("Loading config from %s", config.CONFIG_FILE)
|
||||||
|
|
||||||
|
status = int(status)
|
||||||
|
|
||||||
|
section = "HeadPhones"
|
||||||
|
if inputCategory != None and config().has_section(inputCategory):
|
||||||
|
section = inputCategory
|
||||||
|
|
||||||
|
host = config().get(section, "host")
|
||||||
|
port = config().get(section, "port")
|
||||||
|
apikey = config().get(section, "apikey")
|
||||||
|
delay = float(config().get(section, "delay"))
|
||||||
|
|
||||||
|
try:
|
||||||
|
ssl = int(config().get(section, "ssl"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
ssl = 0
|
||||||
|
try:
|
||||||
|
web_root = config().get(section, "web_root")
|
||||||
|
except config.NoOptionError:
|
||||||
|
web_root = ""
|
||||||
|
try:
|
||||||
|
TimePerGiB = int(config().get(section, "TimePerGiB"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
|
||||||
|
if ssl:
|
||||||
|
protocol = "https://"
|
||||||
|
else:
|
||||||
|
protocol = "http://"
|
||||||
|
# don't delay when we are calling this script manually.
|
||||||
|
if clientAgent == "manual":
|
||||||
|
delay = 0
|
||||||
|
|
||||||
|
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
||||||
|
|
||||||
|
dirSize = getDirectorySize(dirName) # get total directory size to calculate needed processing time.
|
||||||
|
TIME_OUT = int(TimePerGiB) * dirSize # HeadPhones needs to complete all moving/transcoding and renaming before returning the status.
|
||||||
|
TIME_OUT += 60 # Add an extra minute for over-head/processing/metadata.
|
||||||
|
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
|
||||||
|
|
||||||
|
baseURL = protocol + host + ":" + port + web_root + "/api?apikey=" + apikey + "&cmd="
|
||||||
|
|
||||||
|
if status == 0:
|
||||||
|
command = "forceProcess"
|
||||||
|
|
||||||
|
url = baseURL + command
|
||||||
|
|
||||||
|
Logger.info("Waiting for %s seconds to allow HeadPhones to process newly extracted files", str(delay))
|
||||||
|
|
||||||
|
datetime.time.sleep(delay)
|
||||||
|
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url)
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
Logger.info("HeadPhones returned %s", r.content)
|
||||||
|
if r.content[0] == "OK":
|
||||||
|
Logger.info("%s started on HeadPhones for %s", command, nzbName)
|
||||||
|
else:
|
||||||
|
Logger.error("%s has NOT started on HeadPhones for %s. Exiting", command, nzbName)
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
else:
|
||||||
|
Logger.info("The download failed. Nothing to process")
|
||||||
|
return 0 # Success (as far as this script is concerned)
|
||||||
|
|
||||||
|
if nzbName == "Manual Run":
|
||||||
|
return 0 # success
|
||||||
|
|
||||||
|
# we will now wait 1 minutes for this album to be processed before returning to TorrentToMedia and unpausing.
|
||||||
|
## Hopefully we can use a "getHistory" check in here to confirm processing complete...
|
||||||
|
start = datetime.datetime.now() # set time for timeout
|
||||||
|
while (datetime.datetime.now() - start) < datetime.timedelta(minutes=1): # only wait 2 minutes, then return to TorrentToMedia
|
||||||
|
datetime.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.
|
||||||
|
Logger.info("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")
|
||||||
|
# return 1 # failure
|
||||||
|
return 0 # success for now.
|
188
nzbtomedia/autoProcess/autoProcessTV.py
Normal file
188
nzbtomedia/autoProcess/autoProcessTV.py
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
import copy
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import urllib
|
||||||
|
import requests
|
||||||
|
import time
|
||||||
|
from nzbtomedia.Transcoder import Transcoder
|
||||||
|
from nzbtomedia.nzbToMediaAutoFork import autoFork
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions
|
||||||
|
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, is_sample, flatten, getDirectorySize, delete
|
||||||
|
|
||||||
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
class autoProcessTV:
|
||||||
|
def processEpisode(self, dirName, nzbName=None, failed=False, clientAgent = "manual", inputCategory=None):
|
||||||
|
if dirName is None:
|
||||||
|
Logger.error("No directory was given!")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
|
||||||
|
|
||||||
|
Logger.info("Loading config from %s", config.CONFIG_FILE)
|
||||||
|
|
||||||
|
status = int(failed)
|
||||||
|
|
||||||
|
section = "SickBeard"
|
||||||
|
if inputCategory != None and config().has_section(inputCategory):
|
||||||
|
section = inputCategory
|
||||||
|
|
||||||
|
host = config().get(section, "host")
|
||||||
|
port = config().get(section, "port")
|
||||||
|
username = config().get(section, "username")
|
||||||
|
password = config().get(section, "password")
|
||||||
|
|
||||||
|
try:
|
||||||
|
ssl = int(config().get(section, "ssl"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
ssl = 0
|
||||||
|
try:
|
||||||
|
web_root = config().get(section, "web_root")
|
||||||
|
except config.NoOptionError:
|
||||||
|
web_root = ""
|
||||||
|
try:
|
||||||
|
watch_dir = config().get(section, "watch_dir")
|
||||||
|
except config.NoOptionError:
|
||||||
|
watch_dir = ""
|
||||||
|
try:
|
||||||
|
transcode = int(config().get("Transcoder", "transcode"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
transcode = 0
|
||||||
|
try:
|
||||||
|
delete_failed = int(config().get(section, "delete_failed"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
delete_failed = 0
|
||||||
|
try:
|
||||||
|
delay = float(config().get(section, "delay"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
delay = 0
|
||||||
|
try:
|
||||||
|
TimePerGiB = int(config().get(section, "TimePerGiB"))
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
|
||||||
|
try:
|
||||||
|
SampleIDs = (config().get("Extensions", "SampleIDs")).split(',')
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
SampleIDs = ['sample','-s.']
|
||||||
|
try:
|
||||||
|
nzbExtractionBy = config().get(section, "nzbExtractionBy")
|
||||||
|
except (config.NoOptionError, ValueError):
|
||||||
|
nzbExtractionBy = "Downloader"
|
||||||
|
try:
|
||||||
|
process_method = config().get(section, "process_method")
|
||||||
|
except config.NoOptionError:
|
||||||
|
process_method = None
|
||||||
|
|
||||||
|
mediaContainer = (config().get("Extensions", "mediaExtensions")).split(',')
|
||||||
|
minSampleSize = int(config().get("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.
|
||||||
|
dirName = os.path.split(os.path.normpath(dirName))[0]
|
||||||
|
|
||||||
|
SpecificPath = os.path.join(dirName, str(nzbName))
|
||||||
|
cleanName = os.path.splitext(SpecificPath)
|
||||||
|
if cleanName[1] == ".nzb":
|
||||||
|
SpecificPath = cleanName[0]
|
||||||
|
if os.path.isdir(SpecificPath):
|
||||||
|
dirName = SpecificPath
|
||||||
|
|
||||||
|
# auto-detect fork type
|
||||||
|
fork, params = autoFork(section)
|
||||||
|
|
||||||
|
if fork not in config.SICKBEARD_TORRENT or (clientAgent in ['nzbget','sabnzbd'] and nzbExtractionBy != "Destination"):
|
||||||
|
if nzbName:
|
||||||
|
process_all_exceptions(nzbName.lower(), dirName)
|
||||||
|
nzbName, dirName = convert_to_ascii(nzbName, dirName)
|
||||||
|
|
||||||
|
# Now check if tv files exist in destination. Eventually extraction may be done here if nzbExtractionBy == TorrentToMedia
|
||||||
|
video = int(0)
|
||||||
|
for dirpath, dirnames, filenames in os.walk(dirName):
|
||||||
|
for file in filenames:
|
||||||
|
filePath = os.path.join(dirpath, file)
|
||||||
|
fileExtension = os.path.splitext(file)[1]
|
||||||
|
if fileExtension in mediaContainer: # If the file is a video file
|
||||||
|
if is_sample(filePath, nzbName, minSampleSize, SampleIDs):
|
||||||
|
Logger.debug("Removing sample file: %s", filePath)
|
||||||
|
os.unlink(filePath) # remove samples
|
||||||
|
else:
|
||||||
|
video = video + 1
|
||||||
|
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)
|
||||||
|
elif clientAgent == "manual":
|
||||||
|
Logger.warning("No media files found in directory %s to manually process.", dirName)
|
||||||
|
return 0 # Success (as far as this script is concerned)
|
||||||
|
else:
|
||||||
|
Logger.warning("No media files found in directory %s. Processing this as a failed download", dirName)
|
||||||
|
status = int(1)
|
||||||
|
failed = True
|
||||||
|
|
||||||
|
dirSize = getDirectorySize(dirName) # get total directory size to calculate needed processing time.
|
||||||
|
TIME_OUT = int(TimePerGiB) * dirSize # SickBeard needs to complete all moving and renaming before returning the log sequence via url.
|
||||||
|
TIME_OUT += 60 # Add an extra minute for over-head/processing/metadata.
|
||||||
|
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
|
||||||
|
|
||||||
|
# configure SB params to pass
|
||||||
|
params['quiet'] = 1
|
||||||
|
if nzbName is not None:
|
||||||
|
params['nzbName'] = nzbName
|
||||||
|
|
||||||
|
for param in copy.copy(params):
|
||||||
|
if param == "failed":
|
||||||
|
params[param] = failed
|
||||||
|
|
||||||
|
if param in ["dirName", "dir"]:
|
||||||
|
params[param] = dirName
|
||||||
|
|
||||||
|
if param == "process_method":
|
||||||
|
if process_method:
|
||||||
|
params[param] = process_method
|
||||||
|
else:
|
||||||
|
del params[param]
|
||||||
|
|
||||||
|
# delete any unused params so we don't pass them to SB by mistake
|
||||||
|
[params.pop(k) for k,v in params.items() if v is None]
|
||||||
|
|
||||||
|
if status == 0:
|
||||||
|
Logger.info("The download succeeded. Sending process request to SickBeard's %s branch", fork)
|
||||||
|
elif fork in config.SICKBEARD_FAILED:
|
||||||
|
Logger.info("The download failed. Sending 'failed' process request to SickBeard's %s branch", fork)
|
||||||
|
else:
|
||||||
|
Logger.info("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]','/','']:
|
||||||
|
Logger.info("Deleting directory: %s", dirName)
|
||||||
|
delete(dirName)
|
||||||
|
return 0 # Success (as far as this script is concerned)
|
||||||
|
|
||||||
|
if status == 0 and transcode == 1: # only transcode successful downlaods
|
||||||
|
result = Transcoder().Transcode_directory(dirName)
|
||||||
|
if result == 0:
|
||||||
|
Logger.debug("Transcoding succeeded for files in %s", dirName)
|
||||||
|
else:
|
||||||
|
Logger.warning("Transcoding failed for files in %s", dirName)
|
||||||
|
|
||||||
|
if ssl:
|
||||||
|
protocol = "https://"
|
||||||
|
else:
|
||||||
|
protocol = "http://"
|
||||||
|
|
||||||
|
url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(params)
|
||||||
|
|
||||||
|
if clientAgent == "manual":delay = 0
|
||||||
|
Logger.info("Waiting for %s seconds to allow SB to process newly extracted files", str(delay))
|
||||||
|
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
Logger.debug("Opening URL: %s", url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.get(url, auth=(username, password))
|
||||||
|
except requests.ConnectionError:
|
||||||
|
Logger.exception("Unable to open URL")
|
||||||
|
return 1 # failure
|
||||||
|
|
||||||
|
Logger.info("%s", r.content)
|
||||||
|
if status != 0 and delete_failed and not dirName in ['sys.argv[0]','/','']:
|
||||||
|
delete(dirName)
|
||||||
|
return 0 # Success
|
|
@ -1,9 +1,9 @@
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from nzbToMediaConfig import *
|
|
||||||
from subprocess import call, Popen
|
from subprocess import call, Popen
|
||||||
from autoProcess.nzbToMediaUtil import create_destination
|
|
||||||
|
from nzbtomedia.nzbToMediaConfig import *
|
||||||
|
from nzbtomedia.nzbToMediaUtil import create_destination
|
||||||
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
Logger = logging.getLogger()
|
||||||
|
@ -111,7 +111,7 @@ def extract(filePath, outputDestination):
|
||||||
# Create outputDestination folder
|
# Create outputDestination folder
|
||||||
create_destination(outputDestination)
|
create_destination(outputDestination)
|
||||||
|
|
||||||
Logger.info("MAIN: Loading config from %s", CONFIG_FILE)
|
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
|
||||||
|
|
||||||
passwordsfile = config().get("passwords", "PassWordFile")
|
passwordsfile = config().get("passwords", "PassWordFile")
|
||||||
if passwordsfile != "" and os.path.isfile(os.path.normpath(passwordsfile)):
|
if passwordsfile != "" and os.path.isfile(os.path.normpath(passwordsfile)):
|
244
nzbtomedia/migratecfg.py
Normal file
244
nzbtomedia/migratecfg.py
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
|
||||||
|
class migratecfg:
|
||||||
|
def migrate(self):
|
||||||
|
categories = []
|
||||||
|
|
||||||
|
# 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):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
section = "CouchPotato"
|
||||||
|
for option, value in configold.items(section) or config(config.MOVIE_CONFIG_FILE).items(section):
|
||||||
|
if option == "category": # change this old format
|
||||||
|
option = "cpsCategory"
|
||||||
|
if option == "outputDirectory": # move this to new location format
|
||||||
|
value = os.path.split(os.path.normpath(value))[0]
|
||||||
|
confignew.set("Torrent", option, value)
|
||||||
|
continue
|
||||||
|
if option in ["username", "password" ]: # these are no-longer needed.
|
||||||
|
continue
|
||||||
|
if option == "cpsCategory":
|
||||||
|
categories.extend(value.split(','))
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
section = "SickBeard"
|
||||||
|
for option, value in configold.items(section) or config(config.TV_CONFIG_FILE).items(section):
|
||||||
|
if option == "category": # change this old format
|
||||||
|
option = "sbCategory"
|
||||||
|
if option == "wait_for": # remove old format
|
||||||
|
continue
|
||||||
|
if option == "failed_fork": # change this old format
|
||||||
|
option = "fork"
|
||||||
|
if value not in ["default", "failed", "failed-torrent", "auto"]:
|
||||||
|
value = "auto"
|
||||||
|
if option == "fork" and value not in ["default", "failed", "failed-torrent", "auto"]:
|
||||||
|
value = "auto"
|
||||||
|
if option == "outputDirectory": # move this to new location format
|
||||||
|
value = os.path.split(os.path.normpath(value))[0]
|
||||||
|
confignew.set("Torrent", option, value)
|
||||||
|
continue
|
||||||
|
if option == "sbCategory":
|
||||||
|
categories.extend(value.split(','))
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
for section in configold.sections():
|
||||||
|
try:
|
||||||
|
for option, value in configold.items(section):
|
||||||
|
if section == "HeadPhones":
|
||||||
|
if option in ["username", "password" ]:
|
||||||
|
continue
|
||||||
|
if option == "hpCategory":
|
||||||
|
categories.extend(value.split(','))
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "Mylar":
|
||||||
|
if option in "mlCategory":
|
||||||
|
categories.extend(value.split(','))
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "Gamez":
|
||||||
|
if option in ["username", "password" ]: # these are no-longer needed.
|
||||||
|
continue
|
||||||
|
if option == "gzCategory":
|
||||||
|
categories.extend(value.split(','))
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "Torrent":
|
||||||
|
if option in ["compressedExtensions", "mediaExtensions", "metaExtensions", "minSampleSize"]:
|
||||||
|
section = "Extensions" # these were moved
|
||||||
|
if option == "useLink": # Sym links supported now as well.
|
||||||
|
if isinstance(value, int):
|
||||||
|
num_value = int(value)
|
||||||
|
if num_value == 1:
|
||||||
|
value = "hard"
|
||||||
|
else:
|
||||||
|
value = "no"
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "Extensions":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "Transcoder":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "WakeOnLan":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "UserScript":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "ASCII":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "passwords":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "loggers":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "handlers":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "formatters":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "logger_root":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "handler_console":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
if section == "formatter_generic":
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
except config.InterpolationMissingOptionError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for section in categories:
|
||||||
|
try:
|
||||||
|
if configold.items(section):
|
||||||
|
confignew.add_section(section)
|
||||||
|
|
||||||
|
for option, value in configold.items(section):
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
except config.NoSectionError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# create a backup of our old config
|
||||||
|
if os.path.isfile(config.CONFIG_FILE):
|
||||||
|
cfgbak_name = config.CONFIG_FILE + ".old"
|
||||||
|
if os.path.isfile(cfgbak_name): # remove older backups
|
||||||
|
os.unlink(cfgbak_name)
|
||||||
|
os.rename(config.CONFIG_FILE, cfgbak_name)
|
||||||
|
|
||||||
|
# writing our configuration file to 'autoProcessMedia.cfg'
|
||||||
|
with open(config.CONFIG_FILE, 'wb') as configFile:
|
||||||
|
confignew.write(configFile)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def addnzbget(self):
|
||||||
|
confignew = config()
|
||||||
|
section = "CouchPotato"
|
||||||
|
envKeys = ['CATEGORY', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT', 'DELAY', 'METHOD', 'DELETE_FAILED', 'REMOTECPS', 'WAIT_FOR', 'TIMEPERGIB']
|
||||||
|
cfgKeys = ['cpsCategory', 'apikey', 'host', 'port', 'ssl', 'web_root', 'delay', 'method', 'delete_failed', 'remoteCPS', 'wait_for', 'TimePerGiB']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_CPS' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
|
||||||
|
section = "SickBeard"
|
||||||
|
envKeys = ['CATEGORY', 'HOST', 'PORT', 'USERNAME', 'PASSWORD', 'SSL', 'WEB_ROOT', 'WATCH_DIR', 'FORK', 'DELETE_FAILED', 'DELAY', 'TIMEPERGIB', 'PROCESS_METHOD']
|
||||||
|
cfgKeys = ['sbCategory', 'host', 'port', 'username', 'password', 'ssl', 'web_root', 'watch_dir', 'fork', 'delete_failed', 'delay', 'TimePerGiB', 'process_method']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_SB' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
section = "HeadPhones"
|
||||||
|
envKeys = ['CATEGORY', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT', 'DELAY', 'TIMEPERGIB']
|
||||||
|
cfgKeys = ['hpCategory', 'apikey', 'host', 'port', 'ssl', 'web_root', 'delay', 'TimePerGiB']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_HP' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
section = "Mylar"
|
||||||
|
envKeys = ['CATEGORY', 'HOST', 'PORT', 'USERNAME', 'PASSWORD', 'SSL', 'WEB_ROOT']
|
||||||
|
cfgKeys = ['mlCategory', 'host', 'port', 'username', 'password', 'ssl', 'web_root']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_MY' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
section = "Gamez"
|
||||||
|
envKeys = ['CATEGORY', 'APIKEY', 'HOST', 'PORT', 'SSL', 'WEB_ROOT']
|
||||||
|
cfgKeys = ['gzCategory', 'apikey', 'host', 'port', 'ssl', 'web_root']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_GZ' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
section = "Extensions"
|
||||||
|
envKeys = ['COMPRESSEDEXTENSIONS', 'MEDIAEXTENSIONS', 'METAEXTENSIONS']
|
||||||
|
cfgKeys = ['compressedExtensions', 'mediaExtensions', 'metaExtensions']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
section = "Transcoder"
|
||||||
|
envKeys = ['TRANSCODE', 'DUPLICATE', 'IGNOREEXTENSIONS', 'OUTPUTVIDEOEXTENSION', 'OUTPUTVIDEOCODEC', 'OUTPUTVIDEOPRESET', 'OUTPUTVIDEOFRAMERATE', 'OUTPUTVIDEOBITRATE', 'OUTPUTAUDIOCODEC', 'OUTPUTAUDIOBITRATE', 'OUTPUTSUBTITLECODEC']
|
||||||
|
cfgKeys = ['transcode', 'duplicate', 'ignoreExtensions', 'outputVideoExtension', 'outputVideoCodec', 'outputVideoPreset', 'outputVideoFramerate', 'outputVideoBitrate', 'outputAudioCodec', 'outputAudioBitrate', 'outputSubtitleCodec']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
section = "WakeOnLan"
|
||||||
|
envKeys = ['WAKE', 'HOST', 'PORT', 'MAC']
|
||||||
|
cfgKeys = ['wake', 'host', 'port', 'mac']
|
||||||
|
for index in range(len(envKeys)):
|
||||||
|
key = 'NZBPO_WOL' + envKeys[index]
|
||||||
|
if os.environ.has_key(key):
|
||||||
|
option = cfgKeys[index]
|
||||||
|
value = os.environ[key]
|
||||||
|
confignew.set(section, option, value)
|
||||||
|
|
||||||
|
# create a backup of our old config
|
||||||
|
if os.path.isfile(config.CONFIG_FILE):
|
||||||
|
cfgbak_name = config.CONFIG_FILE + ".old"
|
||||||
|
if os.path.isfile(cfgbak_name): # remove older backups
|
||||||
|
os.unlink(cfgbak_name)
|
||||||
|
os.rename(config.CONFIG_FILE, cfgbak_name)
|
||||||
|
|
||||||
|
# writing our configuration file to 'autoProcessMedia.cfg'
|
||||||
|
with open(config.CONFIG_FILE, 'wb') as configFile:
|
||||||
|
confignew.write(configFile)
|
|
@ -1,33 +1,13 @@
|
||||||
import urllib
|
|
||||||
import logging
|
import logging
|
||||||
|
import urllib
|
||||||
|
import requests
|
||||||
|
|
||||||
from nzbToMediaConfig import *
|
from nzbToMediaConfig import config
|
||||||
from autoProcess.nzbToMediaEnv import *
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
def autoFork(section):
|
||||||
|
Logger = logging.getLogger()
|
||||||
class AuthURLOpener(urllib.FancyURLopener):
|
|
||||||
def __init__(self, user, pw):
|
|
||||||
self.username = user
|
|
||||||
self.password = pw
|
|
||||||
self.numTries = 0
|
|
||||||
urllib.FancyURLopener.__init__(self)
|
|
||||||
|
|
||||||
def prompt_user_passwd(self, host, realm):
|
|
||||||
if self.numTries == 0:
|
|
||||||
self.numTries = 1
|
|
||||||
return (self.username, self.password)
|
|
||||||
else:
|
|
||||||
return ('', '')
|
|
||||||
|
|
||||||
def openit(self, url):
|
|
||||||
self.numTries = 0
|
|
||||||
return urllib.FancyURLopener.open(self, url)
|
|
||||||
|
|
||||||
def autoFork():
|
|
||||||
|
|
||||||
# config settings
|
# config settings
|
||||||
section = "SickBeard"
|
|
||||||
host = config().get(section, "host")
|
host = config().get(section, "host")
|
||||||
port = config().get(section, "port")
|
port = config().get(section, "port")
|
||||||
username = config().get(section, "username")
|
username = config().get(section, "username")
|
||||||
|
@ -44,12 +24,10 @@ def autoFork():
|
||||||
web_root = ""
|
web_root = ""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fork = forks.items()[forks.keys().index(config().get(section, "fork"))]
|
fork = config.FORKS.items()[config.FORKS.keys().index(config().get(section, "fork"))]
|
||||||
except:
|
except:
|
||||||
fork = "auto"
|
fork = "auto"
|
||||||
|
|
||||||
myOpener = AuthURLOpener(username, password)
|
|
||||||
|
|
||||||
if ssl:
|
if ssl:
|
||||||
protocol = "https://"
|
protocol = "https://"
|
||||||
else:
|
else:
|
||||||
|
@ -58,17 +36,17 @@ def autoFork():
|
||||||
detected = False
|
detected = False
|
||||||
if fork == "auto":
|
if fork == "auto":
|
||||||
Logger.info("Attempting to auto-detect SickBeard fork")
|
Logger.info("Attempting to auto-detect SickBeard fork")
|
||||||
for fork in sorted(forks.iteritems()):
|
for fork in sorted(config.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
|
||||||
try:
|
try:
|
||||||
urlObj = myOpener.openit(url)
|
r = requests.get(url, auth=(username, password))
|
||||||
except IOError, e:
|
except requests.ConnectionError:
|
||||||
Logger.info("Could not connect to SickBeard to perform auto-fork detection!")
|
Logger.info("Could not connect to SickBeard to perform auto-fork detection!")
|
||||||
break
|
break
|
||||||
|
|
||||||
if urlObj.getcode() == 200:
|
if r.ok:
|
||||||
detected = True
|
detected = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -76,7 +54,7 @@ def autoFork():
|
||||||
Logger.info("SickBeard fork auto-detection successful ...")
|
Logger.info("SickBeard fork auto-detection successful ...")
|
||||||
else:
|
else:
|
||||||
Logger.info("SickBeard fork auto-detection failed")
|
Logger.info("SickBeard fork auto-detection failed")
|
||||||
fork = forks.items()[forks.keys().index(fork_default)]
|
fork = config.FORKS.items()[config.FORKS.keys().index(config.FORK_DEFAULT)]
|
||||||
|
|
||||||
Logger.info("SickBeard fork set to %s", fork[0])
|
Logger.info("SickBeard fork set to %s", fork[0])
|
||||||
return fork[0], fork[1]
|
return fork[0], fork[1]
|
61
nzbtomedia/nzbToMediaConfig.py
Normal file
61
nzbtomedia/nzbToMediaConfig.py
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
import os
|
||||||
|
import ConfigParser
|
||||||
|
|
||||||
|
class config(object):
|
||||||
|
# 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(__file__)))
|
||||||
|
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")
|
||||||
|
|
||||||
|
# config error handling classes
|
||||||
|
Error = ConfigParser.Error
|
||||||
|
NoSectionError = ConfigParser.NoSectionError
|
||||||
|
NoOptionError = ConfigParser.NoOptionError
|
||||||
|
DuplicateSectionError = ConfigParser.DuplicateSectionError
|
||||||
|
InterpolationError = ConfigParser.InterpolationError
|
||||||
|
InterpolationMissingOptionError = ConfigParser.InterpolationMissingOptionError
|
||||||
|
InterpolationSyntaxError = ConfigParser.InterpolationSyntaxError
|
||||||
|
InterpolationDepthError = ConfigParser.InterpolationDepthError
|
||||||
|
ParsingError = ConfigParser.ParsingError
|
||||||
|
MissingSectionHeaderError = ConfigParser.MissingSectionHeaderError
|
||||||
|
|
||||||
|
def __new__(cls, *file):
|
||||||
|
if not file:
|
||||||
|
file = cls.CONFIG_FILE
|
||||||
|
return cls.loadConfig(file)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def loadConfig(file):
|
||||||
|
# load config
|
||||||
|
config = ConfigParser.ConfigParser()
|
||||||
|
config.optionxform = str
|
||||||
|
if config.read(file):
|
||||||
|
return config
|
|
@ -1,26 +1,19 @@
|
||||||
# System imports
|
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from nzbtomedia.nzbToMediaUtil import iterate_media_files
|
||||||
# Custom imports
|
|
||||||
from nzbToMediaUtil import iterate_media_files
|
|
||||||
|
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
def process_all_exceptions(name, dirname):
|
def process_all_exceptions(name, dirname):
|
||||||
for group, exception in __customgroups__.items():
|
for group, exception in __customgroups__.items():
|
||||||
if not (group in name or group in dirname):
|
if not (group in name or group in dirname):
|
||||||
continue
|
continue
|
||||||
process_exception(exception, name, dirname)
|
process_exception(exception, name, dirname)
|
||||||
|
|
||||||
|
|
||||||
def process_exception(exception, name, dirname):
|
def process_exception(exception, name, dirname):
|
||||||
for parentDir, filename in iterate_media_files(dirname):
|
for parentDir, filename in iterate_media_files(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))
|
|
@ -1,15 +1,17 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
import re
|
import logging.handlers
|
||||||
import sys
|
|
||||||
import shutil
|
|
||||||
import struct
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
|
|
||||||
import linktastic.linktastic as linktastic
|
|
||||||
from nzbToMediaConfig import *
|
|
||||||
|
|
||||||
|
from nzbtomedia.linktastic import linktastic
|
||||||
|
from nzbtomedia.nzbToMediaConfig import config
|
||||||
|
|
||||||
Logger = logging.getLogger()
|
Logger = logging.getLogger()
|
||||||
|
|
||||||
|
@ -30,8 +32,8 @@ def safeName(name):
|
||||||
|
|
||||||
def nzbtomedia_configure_logging(logfile=None):
|
def nzbtomedia_configure_logging(logfile=None):
|
||||||
if not logfile:
|
if not logfile:
|
||||||
logfile = LOG_FILE
|
logfile = config.LOG_FILE
|
||||||
logging.config.fileConfig(CONFIG_FILE)
|
logging.config.fileConfig(config.CONFIG_FILE)
|
||||||
fileHandler = logging.handlers.RotatingFileHandler(logfile, mode='a', maxBytes=1048576, backupCount=1, encoding='utf-8', delay=True)
|
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.formatter = logging.Formatter('%(asctime)s|%(levelname)-7.7s %(message)s', '%H:%M:%S')
|
||||||
fileHandler.level = logging.DEBUG
|
fileHandler.level = logging.DEBUG
|
||||||
|
@ -315,7 +317,6 @@ def WakeOnLan(ethernet_address):
|
||||||
ss.sendto(msg, ('<broadcast>', 9))
|
ss.sendto(msg, ('<broadcast>', 9))
|
||||||
ss.close()
|
ss.close()
|
||||||
|
|
||||||
|
|
||||||
#Test Connection function
|
#Test Connection function
|
||||||
def TestCon(host, port):
|
def TestCon(host, port):
|
||||||
try:
|
try:
|
||||||
|
@ -324,7 +325,6 @@ def TestCon(host, port):
|
||||||
except:
|
except:
|
||||||
return "Down"
|
return "Down"
|
||||||
|
|
||||||
|
|
||||||
def WakeUp():
|
def WakeUp():
|
||||||
if not config():
|
if not config():
|
||||||
Logger.error("You need an autoProcessMedia.config() file - did you rename and edit the .sample?")
|
Logger.error("You need an autoProcessMedia.config() file - did you rename and edit the .sample?")
|
||||||
|
@ -333,7 +333,7 @@ def WakeUp():
|
||||||
wake = int(config().get("WakeOnLan", "wake"))
|
wake = int(config().get("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_FILE)
|
Logger.info("Loading WakeOnLan config from %s", config.CONFIG_FILE)
|
||||||
config().get("WakeOnLan", "host")
|
config().get("WakeOnLan", "host")
|
||||||
host = config().get("WakeOnLan", "host")
|
host = config().get("WakeOnLan", "host")
|
||||||
port = int(config().get("WakeOnLan", "port"))
|
port = int(config().get("WakeOnLan", "port"))
|
||||||
|
@ -440,21 +440,16 @@ def parse_transmission(args):
|
||||||
inputID = os.getenv('TR_TORRENT_ID')
|
inputID = os.getenv('TR_TORRENT_ID')
|
||||||
return inputDirectory, inputName, inputCategory, inputHash, inputID
|
return inputDirectory, inputName, inputCategory, inputHash, inputID
|
||||||
|
|
||||||
|
def parse_args(clientAgent):
|
||||||
__ARG_PARSERS__ = {
|
clients = {
|
||||||
'other': parse_other,
|
'other': parse_other,
|
||||||
'rtorrent': parse_rtorrent,
|
'rtorrent': parse_rtorrent,
|
||||||
'utorrent': parse_utorrent,
|
'utorrent': parse_utorrent,
|
||||||
'deluge': parse_deluge,
|
'deluge': parse_deluge,
|
||||||
'transmission': parse_transmission,
|
'transmission': parse_transmission,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return clients[clientAgent](sys.argv)
|
||||||
def parse_args(clientAgent):
|
|
||||||
parseFunc = __ARG_PARSERS__.get(clientAgent, None)
|
|
||||||
if not parseFunc:
|
|
||||||
raise RuntimeError("Could not find client-agent")
|
|
||||||
return parseFunc(sys.argv)
|
|
||||||
|
|
||||||
def get_dirnames(section, category):
|
def get_dirnames(section, category):
|
||||||
try:
|
try:
|
||||||
|
@ -467,7 +462,7 @@ def get_dirnames(section, category):
|
||||||
outputDirectory = ""
|
outputDirectory = ""
|
||||||
|
|
||||||
# set dirName
|
# set dirName
|
||||||
dirNames = None
|
dirNames = []
|
||||||
if watch_dir != "":
|
if watch_dir != "":
|
||||||
if os.path.exists(watch_dir):
|
if os.path.exists(watch_dir):
|
||||||
dirNames = [os.path.join(watch_dir, o) for o in os.listdir(watch_dir) if
|
dirNames = [os.path.join(watch_dir, o) for o in os.listdir(watch_dir) if
|
||||||
|
@ -478,3 +473,15 @@ def get_dirnames(section, category):
|
||||||
os.path.isdir(os.path.join(outputDirectory, o))]
|
os.path.isdir(os.path.join(outputDirectory, o))]
|
||||||
|
|
||||||
return dirNames
|
return dirNames
|
||||||
|
|
||||||
|
def delete(dirName):
|
||||||
|
Logger.info("Deleting failed files and folder %s", dirName)
|
||||||
|
try:
|
||||||
|
shutil.rmtree(dirName, True)
|
||||||
|
except:
|
||||||
|
Logger.exception("Unable to delete folder %s", dirName)
|
||||||
|
|
||||||
|
def getURL(url, username, password):
|
||||||
|
r = requests.get(url, auth=(username, password))
|
||||||
|
return r
|
||||||
|
|
|
@ -19,6 +19,5 @@ __title__ = "synchronous-deluge"
|
||||||
__version__ = "0.1"
|
__version__ = "0.1"
|
||||||
__author__ = "Christian Dale"
|
__author__ = "Christian Dale"
|
||||||
|
|
||||||
from synchronousdeluge.client import DelugeClient
|
from nzbtomedia.synchronousdeluge.exceptions import DelugeRPCError
|
||||||
from synchronousdeluge.exceptions import DelugeRPCError
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from itertools import imap
|
from itertools import imap
|
||||||
|
from exceptions import DelugeRPCError
|
||||||
from synchronousdeluge.exceptions import DelugeRPCError
|
from protocol import DelugeRPCRequest, DelugeRPCResponse
|
||||||
from synchronousdeluge.protocol import DelugeRPCRequest, DelugeRPCResponse
|
from transfer import DelugeTransfer
|
||||||
from synchronousdeluge.transfer import DelugeTransfer
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["DelugeClient"]
|
__all__ = ["DelugeClient"]
|
|
@ -3,7 +3,7 @@ import struct
|
||||||
import socket
|
import socket
|
||||||
import ssl
|
import ssl
|
||||||
|
|
||||||
from synchronousdeluge import rencode
|
from nzbtomedia.synchronousdeluge import rencode
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["DelugeTransfer"]
|
__all__ = ["DelugeTransfer"]
|
18
nzbtomedia/transmissionrpc/__init__.py
Normal file
18
nzbtomedia/transmissionrpc/__init__.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
||||||
|
# Licensed under the MIT license.
|
||||||
|
|
||||||
|
from nzbtomedia.transmissionrpc.constants import DEFAULT_PORT, DEFAULT_TIMEOUT, PRIORITY, RATIO_LIMIT, LOGGER
|
||||||
|
from nzbtomedia.transmissionrpc.error import TransmissionError, HTTPHandlerError
|
||||||
|
from nzbtomedia.transmissionrpc.httphandler import HTTPHandler, DefaultHTTPHandler
|
||||||
|
from nzbtomedia.transmissionrpc.torrent import Torrent
|
||||||
|
from nzbtomedia.transmissionrpc.session import Session
|
||||||
|
from nzbtomedia.transmissionrpc.client import Client
|
||||||
|
from nzbtomedia.transmissionrpc.utils import add_stdout_logger, add_file_logger
|
||||||
|
|
||||||
|
__author__ = 'Erik Svensson <erik.public@gmail.com>'
|
||||||
|
__version_major__ = 0
|
||||||
|
__version_minor__ = 11
|
||||||
|
__version__ = '{0}.{1}'.format(__version_major__, __version_minor__)
|
||||||
|
__copyright__ = 'Copyright (c) 2008-2013 Erik Svensson'
|
||||||
|
__license__ = 'MIT'
|
|
@ -10,12 +10,12 @@ import os
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from transmissionrpc.constants import DEFAULT_PORT, DEFAULT_TIMEOUT
|
from nzbtomedia.transmissionrpc.constants import DEFAULT_PORT, DEFAULT_TIMEOUT
|
||||||
from transmissionrpc.error import TransmissionError, HTTPHandlerError
|
from nzbtomedia.transmissionrpc.error import TransmissionError, HTTPHandlerError
|
||||||
from transmissionrpc.utils import LOGGER, get_arguments, make_rpc_name, argument_value_convert, rpc_bool
|
from nzbtomedia.transmissionrpc.utils import LOGGER, get_arguments, make_rpc_name, argument_value_convert, rpc_bool
|
||||||
from transmissionrpc.httphandler import DefaultHTTPHandler
|
from nzbtomedia.transmissionrpc.httphandler import DefaultHTTPHandler
|
||||||
from transmissionrpc.torrent import Torrent
|
from nzbtomedia.transmissionrpc.torrent import Torrent
|
||||||
from transmissionrpc.session import Session
|
from nzbtomedia.transmissionrpc.session import Session
|
||||||
from six import PY3, integer_types, string_types, iteritems
|
from six import PY3, integer_types, string_types, iteritems
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from six import iteritems
|
from nzbtomedia.transmissionrpc.six import iteritems
|
||||||
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger('transmissionrpc')
|
LOGGER = logging.getLogger('transmissionrpc')
|
|
@ -2,7 +2,7 @@
|
||||||
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
||||||
# Licensed under the MIT license.
|
# Licensed under the MIT license.
|
||||||
|
|
||||||
from six import string_types, integer_types
|
from nzbtomedia.transmissionrpc.six import string_types, integer_types
|
||||||
|
|
||||||
class TransmissionError(Exception):
|
class TransmissionError(Exception):
|
||||||
"""
|
"""
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from transmissionrpc.error import HTTPHandlerError
|
from nzbtomedia.transmissionrpc.error import HTTPHandlerError
|
||||||
from six import PY3
|
from six import PY3
|
||||||
|
|
||||||
if PY3:
|
if PY3:
|
|
@ -2,9 +2,9 @@
|
||||||
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
||||||
# Licensed under the MIT license.
|
# Licensed under the MIT license.
|
||||||
|
|
||||||
from transmissionrpc.utils import Field
|
from nzbtomedia.transmissionrpc.utils import Field
|
||||||
|
|
||||||
from six import iteritems, integer_types
|
from nzbtomedia.transmissionrpc.six import iteritems, integer_types
|
||||||
|
|
||||||
class Session(object):
|
class Session(object):
|
||||||
"""
|
"""
|
|
@ -5,8 +5,8 @@
|
||||||
import sys
|
import sys
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from transmissionrpc.constants import PRIORITY, RATIO_LIMIT, IDLE_LIMIT
|
from nzbtomedia.transmissionrpc.constants import PRIORITY, RATIO_LIMIT, IDLE_LIMIT
|
||||||
from transmissionrpc.utils import Field, format_timedelta
|
from nzbtomedia.transmissionrpc.utils import Field, format_timedelta
|
||||||
from six import integer_types, string_types, text_type, iteritems
|
from six import integer_types, string_types, text_type, iteritems
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,12 @@
|
||||||
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
||||||
# Licensed under the MIT license.
|
# Licensed under the MIT license.
|
||||||
|
|
||||||
import socket
|
import socket, datetime, logging, constants
|
||||||
import datetime
|
|
||||||
import logging
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from constants import LOGGER
|
||||||
|
|
||||||
import transmissionrpc.constants as constants
|
|
||||||
from transmissionrpc.constants import LOGGER
|
|
||||||
from six import string_types, iteritems
|
from six import string_types, iteritems
|
||||||
|
|
||||||
|
|
||||||
UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB']
|
UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB']
|
||||||
|
|
||||||
def format_size(size):
|
def format_size(size):
|
0
nzbtomedia/utorrent/__init__.py
Normal file
0
nzbtomedia/utorrent/__init__.py
Normal file
|
@ -10,7 +10,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
|
|
||||||
from upload import MultiPartForm
|
from nzbtomedia.utorrent.upload import MultiPartForm
|
||||||
|
|
||||||
class UTorrentClient(object):
|
class UTorrentClient(object):
|
||||||
|
|
1
tests/__init__.py
Normal file
1
tests/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
__author__ = 'Justin'
|
|
@ -1,6 +1,3 @@
|
||||||
from autoProcess.nzbToMediaUtil import *
|
from nzbtomedia import *
|
||||||
from autoProcess.autoSickBeardFork import autoFork
|
|
||||||
nzbtomedia_configure_logging(LOG_FILE)
|
|
||||||
|
|
||||||
fork, params = autoFork()
|
fork, params = autoFork()
|
||||||
print fork, params
|
print fork, params
|
|
@ -1,18 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2008-2013 Erik Svensson <erik.public@gmail.com>
|
|
||||||
# Licensed under the MIT license.
|
|
||||||
|
|
||||||
from transmissionrpc.constants import DEFAULT_PORT, DEFAULT_TIMEOUT, PRIORITY, RATIO_LIMIT, LOGGER
|
|
||||||
from transmissionrpc.error import TransmissionError, HTTPHandlerError
|
|
||||||
from transmissionrpc.httphandler import HTTPHandler, DefaultHTTPHandler
|
|
||||||
from transmissionrpc.torrent import Torrent
|
|
||||||
from transmissionrpc.session import Session
|
|
||||||
from transmissionrpc.client import Client
|
|
||||||
from transmissionrpc.utils import add_stdout_logger, add_file_logger
|
|
||||||
|
|
||||||
__author__ = 'Erik Svensson <erik.public@gmail.com>'
|
|
||||||
__version_major__ = 0
|
|
||||||
__version_minor__ = 11
|
|
||||||
__version__ = '{0}.{1}'.format(__version_major__, __version_minor__)
|
|
||||||
__copyright__ = 'Copyright (c) 2008-2013 Erik Svensson'
|
|
||||||
__license__ = 'MIT'
|
|
Loading…
Add table
Add a link
Reference in a new issue