Major overhaul of nzbToMedia code base plus a whole restrucure

This commit is contained in:
echel0n 2014-04-03 03:04:04 -07:00
commit 85d8739512
67 changed files with 1687 additions and 1734 deletions

View file

@ -1,24 +1,25 @@
#!/usr/bin/env python
#System imports
import logging
import datetime
import logging
import os
import re
import sys
import shutil
from subprocess import Popen
# Custom imports
import autoProcess.migratecfg as migratecfg
import extractor.extractor as extractor
import autoProcess.autoProcessComics as autoProcessComics
import autoProcess.autoProcessGames as autoProcessGames
import autoProcess.autoProcessMusic as autoProcessMusic
import autoProcess.autoProcessMovie as autoProcessMovie
import autoProcess.autoProcessTV as autoProcessTV
from autoProcess.nzbToMediaEnv import *
from autoProcess.nzbToMediaUtil import *
from autoProcess.autoSickBeardFork import autoFork
from utorrent.client import UTorrentClient
from transmissionrpc.client import Client as TransmissionClient
from synchronousdeluge.client import DelugeClient
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.extractor import extractor
from nzbtomedia.migratecfg import migratecfg
from nzbtomedia.nzbToMediaAutoFork import autoFork
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaUtil import category_search, safeName, is_sample, copy_link, WakeUp, parse_args, flatten, \
nzbtomedia_configure_logging
from nzbtomedia.synchronousdeluge.client import DelugeClient
from nzbtomedia.utorrent.client import UTorrentClient
from nzbtomedia.transmissionrpc.client import Client as TransmissionClient
def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
@ -31,6 +32,14 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
extractionSuccess = False
copy_list = []
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)
@ -38,15 +47,14 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
Logger.debug("MAIN: Determined Directory: %s | Name: %s | Category: %s", inputDirectory, inputName, inputCategory)
sbFork, sbParams = autoFork()
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",sbFork ,inputName)
result = autoProcessTV.processEpisode(inputDirectory, inputName, int(0))
if result == 1:
Logger.info("MAIN: A problem was reported in the autoProcess* script.")
Logger.info("MAIN: All done.")
sys.exit()
if inputCategory in sbCategory:
if fork in config.SICKBEARD_TORRENT and Torrent_ForceLink != 1:
Logger.info("MAIN: Calling SickBeard's %s branch to post-process: %s",fork ,inputName)
result = autoProcessTV().processEpisode(inputDirectory, inputName, 0)
if result != 0:
Logger.info("MAIN: A problem was reported in the autoProcess* script.")
Logger.info("MAIN: All done.")
sys.exit()
outputDestination = ""
for category in categories:
@ -63,7 +71,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
continue
if outputDestination == "":
if inputCategory == "":
inputCategory = "UNCAT"
inputCategory = "UNCAT"
if os.path.basename(inputDirectory) == inputName and os.path.isdir(inputDirectory):
Logger.info("MAIN: Download is a directory")
outputDestination = os.path.normpath(os.path.join(outputDirectory, inputCategory, safeName(inputName)))
@ -79,7 +87,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
processOnly.extend(user_script_categories) # Adds all categories to be processed by userscript.
if not inputCategory in processOnly:
Logger.info("MAIN: No processing to be done for category: %s. Exiting", inputCategory)
Logger.info("MAIN: No processing to be done for category: %s. Exiting", inputCategory)
Logger.info("MAIN: All done.")
sys.exit()
@ -91,14 +99,14 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
utorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD)
except:
Logger.exception("MAIN: Failed to connect to uTorrent")
utorrentClass = ""
if clientAgent == 'transmission':
try:
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, TransmissionHost, TransmissionPort)
TransmissionClass = TransmissionClient(TransmissionHost, TransmissionPort, TransmissionUSR, TransmissionPWD)
except:
Logger.exception("MAIN: Failed to connect to Transmission")
TransmissionClass = ""
if clientAgent == 'deluge':
try:
Logger.debug("MAIN: Connecting to %s: http://%s:%s", clientAgent, DelugeHost, DelugePort)
@ -106,17 +114,16 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
delugeClient.connect(host = DelugeHost, port = DelugePort, username = DelugeUSR, password = DelugePWD)
except:
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
Logger.debug("MAIN: Stoping torrent %s in %s while processing", inputName, clientAgent)
if clientAgent == 'utorrent' and utorrentClass != "":
if clientAgent == 'utorrent' and utorrentClass != "":
utorrentClass.stop(inputHash)
if clientAgent == 'transmission' and TransmissionClass !="":
TransmissionClass.stop_torrent(inputID)
if clientAgent == 'deluge' and delugeClient != "":
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)
@ -125,9 +132,9 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
if useLink in ['sym','move']: # These don't work for HeadPhones.
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)
outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards.
now = datetime.datetime.now()
for dirpath, dirnames, filenames in os.walk(inputDirectory):
@ -147,7 +154,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
targetDirectory = os.path.join(outputDestination, file)
if root == 1:
if foundFile == int(0):
if foundFile == int(0):
Logger.debug("MAIN: Looking for %s in: %s", inputName, file)
if (safeName(inputName) in safeName(file)) or (safeName(fileName) in safeName(inputName)):
#pass # This file does match the Torrent name
@ -167,7 +174,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
else:
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)
try:
copy_link(filePath, targetDirectory, useLink, outputDestination)
@ -208,13 +215,13 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
if re.search(r'\d+', os.path.splitext(fileName)[1]) and os.path.dirname(filePath) in extracted_folder and not any(item in os.path.splitext(fileName)[1] for item in ['.720p','.1080p','.x264']):
part = int(re.search(r'\d+', os.path.splitext(fileName)[1]).group())
if part == 1: # we only want to extract the primary part.
Logger.debug("MAIN: Found primary part of a multi-part archive %s. Extracting", file)
Logger.debug("MAIN: Found primary part of a multi-part archive %s. Extracting", file)
else:
Logger.debug("MAIN: Found part %s of a multi-part archive %s. Ignoring", part, file)
continue
Logger.info("MAIN: Found compressed archive %s for file %s", fileExtension, filePath)
try:
if inputCategory in hpCategory: # HP needs to scan the same dir as passed to downloader.
if inputCategory in hpCategory: # HP needs to scan the same dir as passed to downloader.
extractor.extract(filePath, inputDirectory)
else:
extractor.extract(filePath, outputDestination)
@ -233,11 +240,11 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
continue
outputDestination = outputDestinationMaster # Reset here.
if not inputCategory in noFlatten: #don't flatten hp in case multi cd albums, and we need to copy this back later.
if not inputCategory in noFlatten: #don't flatten hp in case multi cd albums, and we need to copy this back later.
flatten(outputDestination)
# Now check if movie files exist in destination:
if inputCategory in 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 file in filenames:
filePath = os.path.join(dirpath, file)
@ -257,7 +264,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
else:
Logger.debug("MAIN: Found %s media files in output. %s were found in input", str(video2), str(video))
if inputCategory in sbCategory and sbFork in SICKBEARD_TORRENT:
if inputCategory in sbCategory and fork in config.SICKBEARD_TORRENT:
if len(copy_list) > 0:
Logger.debug("MAIN: Found and linked %s files", str(len(copy_list)))
status = int(0)
@ -274,22 +281,23 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
Logger.error("MAIN: Something failed! Please check logs. Exiting")
sys.exit(-1)
result = 0
if inputCategory in cpsCategory:
Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName)
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:
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:
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:
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:
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:
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)
if clientAgent == 'deluge' and delugeClient != "":
delugeClient.core.resume_torrent([inputID])
time.sleep(5)
datetime.time.sleep(5)
#cleanup
if inputCategory in processCategories and result == 0 and os.path.isdir(outputDestination):
num_files_new = int(0)
@ -346,7 +354,7 @@ def main(inputDirectory, inputName, inputCategory, inputHash, inputID):
if fileExtension in mediaContainer or fileExtension in metaContainer:
num_files_new = num_files_new + 1
file_list.append(file)
if num_files_new == int(0) or forceClean == 1:
if num_files_new == int(0) or forceClean == 1:
Logger.info("All files have been processed. Cleaning outputDirectory %s", outputDestination)
shutil.rmtree(outputDestination)
else:
@ -411,11 +419,10 @@ def external_script(outputDestination,torrentName,torrentLabel):
result = int(1)
final_result = final_result + result
time.sleep(user_delay)
datetime.time.sleep(user_delay)
num_files_new = int(0)
for dirpath, dirnames, filenames in os.walk(outputDestination):
for file in filenames:
filePath = os.path.join(dirpath, file)
fileName, fileExtension = os.path.splitext(file)
@ -426,31 +433,24 @@ def external_script(outputDestination,torrentName,torrentLabel):
Logger.info("All files have been processed. Cleaning outputDirectory %s", outputDestination)
shutil.rmtree(outputDestination)
elif user_script_clean == int(1) and num_files_new != int(0):
Logger.info("%s files were processed, but %s still remain. outputDirectory will not be cleaned.", num_files, num_files_new)
Logger.info("%s files were processed, but %s still remain. outputDirectory will not be cleaned.", num_files, num_files_new)
return final_result
if __name__ == "__main__":
# run migrate to convert old cfg to new style cfg plus fix any cfg missing values/options.
if migratecfg().migrate():
nzbtomedia_configure_logging(config.LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("TorrentToMedia %s", config.NZBTOMEDIA_VERSION)
#check to migrate old cfg before trying to load.
if os.path.isfile(os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample")):
migratecfg.migrate()
# Logging
nzbtomedia_configure_logging(LOG_FILE)
Logger = logging.getLogger(__name__)
Logger.info("====================") # Seperate old from new log
Logger.info("TorrentToMedia %s", VERSION)
Logger.info("MAIN: Loading config from %s", config.CONFIG_FILE)
else:
sys.exit(-1)
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
useLink_in = config().get("Torrent", "useLink") # no | hard | sym
outputDirectory = config().get("Torrent", "outputDirectory") # /abs/path/to/complete/
@ -470,19 +470,20 @@ if __name__ == "__main__":
DelugePort = config().get("Torrent", "DelugePort") # 8084
DelugeUSR = config().get("Torrent", "DelugeUSR") # mysecretusr
DelugePWD = config().get("Torrent", "DelugePWD") # mysecretpwr
deleteOriginal = int(config().get("Torrent", "deleteOriginal")) # 0
forceClean = int(config().get("Torrent", "forceClean")) # 0
compressedContainer = (config().get("Extensions", "compressedExtensions")).split(',') # .zip,.rar,.7z
mediaContainer = (config().get("Extensions", "mediaExtensions")).split(',') # .mkv,.avi,.divx
metaContainer = (config().get("Extensions", "metaExtensions")).split(',') # .nfo,.sub,.srt
minSampleSize = int(config().get("Extensions", "minSampleSize")) # 200 (in MB)
SampleIDs = (config().get("Extensions", "SampleIDs")).split(',') # sample,-s.
Torrent_ForceLink = int(config().get("SickBeard", "Torrent_ForceLink")) # 1
cpsCategory = (config().get("CouchPotato", "cpsCategory")).split(',') # movie
sbCategory = (config().get("SickBeard", "sbCategory")).split(',') # tv
Torrent_ForceLink = int(config().get("SickBeard", "Torrent_ForceLink")) # 1
hpCategory = (config().get("HeadPhones", "hpCategory")).split(',') # music
mlCategory = (config().get("Mylar", "mlCategory")).split(',') # comics
gzCategory = (config().get("Gamez", "gzCategory")).split(',') # games
@ -493,7 +494,7 @@ if __name__ == "__main__":
categories.extend(gzCategory)
user_script_categories = config().get("UserScript", "user_script_categories").split(',') # NONE
if not "NONE" in user_script_categories:
if not "NONE" in user_script_categories:
user_script_mediaExtensions = (config().get("UserScript", "user_script_mediaExtensions")).split(',')
user_script = config().get("UserScript", "user_script_path")
user_script_param = (config().get("UserScript", "user_script_param")).split(',')
@ -501,18 +502,18 @@ if __name__ == "__main__":
user_script_clean = int(config().get("UserScript", "user_script_clean"))
user_delay = int(config().get("UserScript", "delay"))
user_script_runOnce = int(config().get("UserScript", "user_script_runOnce"))
transcode = int(config().get("Transcoder", "transcode"))
n = 0
n = 0
for arg in sys.argv:
Logger.debug("arg %s is: %s", n, arg)
n = n+1
try:
inputDirectory, inputName, inputCategory, inputHash, inputID = parse_args(clientAgent)
except:
if not len(sys.argv) > 1:
Logger.exception("MAIN: There was a problem loading variables")
sys.exit(-1)
# process torrent
inputDirectory, inputName, inputCategory, inputHash, inputID = parse_args(clientAgent)
main(inputDirectory, inputName, inputCategory, inputHash, inputID)