diff --git a/Transcoder.py b/Transcoder.py deleted file mode 100644 index 304d1623..00000000 --- a/Transcoder.py +++ /dev/null @@ -1,93 +0,0 @@ -import sys -import os -import ConfigParser -import logging -from subprocess import call - -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. - 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]): - res = call([os.path.join(os.path.dirname(sys.argv[0]),'getffmpeg.sh')]) - if res or call(['which', ffmpeg]): # 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' - - config = ConfigParser.ConfigParser() - configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - Logger.info("Loading config from %s", configFilename) - - if not os.path.isfile(configFilename): - Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") - return 1 # failure - - config.read(configFilename) - - mediaContainer = (config.get("Extensions", "mediaExtensions")).split(',') - duplicate = int(config.get("Transcoder", "duplicate")) - ignoreExtensions = (config.get("Transcoder", "ignoreExtensions")).split(',') - outputVideoExtension = config.get("Transcoder", "outputVideoExtension") - outputVideoCodec = config.get("Transcoder", "outputVideoCodec") - outputVideoFramerate = config.get("Transcoder", "outputVideoFramerate") - outputVideoBitrate = config.get("Transcoder", "outputVideoBitrate") - outputAudioCodec = config.get("Transcoder", "outputAudioCodec") - outputAudioBitrate = config.get("Transcoder", "outputAudioBitrate") - - 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, '-i', filePath] - if outputVideoCodec: - command.append('-c:v') - command.append(outputVideoCodec) - if outputVideoFramerate: - command.append('-r') - command.append(outputVideoFramerate) - if outputVideoBitrate: - command.append('-b:v') - command.append(outputVideoBitrate) - if outputAudioCodec: - command.append('-c:a') - command.append(outputAudioCodec) - if outputAudioBitrate: - command.append('-b:a') - command.append(outputAudioBitrate) - command.append(newfilePath) - - Logger.debug("Transcoding video %s to %s", filePath, newfilePath) - result = 1 # set result to failed in case call fails. - try: - result = call(command) - except e: - Logger.error("Transcoding of video %s failed due to: ", filePath, str(e)) - if result == 0: - Logger.info("Transcoding of video %s to %s succeded", 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 sucessful, else will return a positive integer for failure. - final_result = final_result + result - return final_result diff --git a/autoProcessComics.py b/autoProcessComics.py deleted file mode 100644 index 2ac8071c..00000000 --- a/autoProcessComics.py +++ /dev/null @@ -1,92 +0,0 @@ -import sys -import urllib -import os.path -import time -import ConfigParser -import logging - -from nzbToMediaEnv import * -from nzbToMediaSceneExceptions import process_all_exceptions - -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 processEpisode(dirName, nzbName=None, status=0): - - config = ConfigParser.ConfigParser() - configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - Logger.info("Loading config from %s", configFilename) - - if not os.path.isfile(configFilename): - Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") - return 1 # failure - - try: - fp = open(configFilename, "r") - config.readfp(fp) - fp.close() - except IOError, e: - Logger.error("Could not read configuration file: %s", str(e)) - return 1 # failure - - host = config.get("Mylar", "host") - port = config.get("Mylar", "port") - username = config.get("Mylar", "username") - password = config.get("Mylar", "password") - try: - ssl = int(config.get("Mylar", "ssl")) - except (ConfigParser.NoOptionError, ValueError): - ssl = 0 - - try: - web_root = config.get("Mylar", "web_root") - except ConfigParser.NoOptionError: - web_root = "" - - params = {} - - 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 IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - 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 diff --git a/autoProcessGames.py b/autoProcessGames.py deleted file mode 100644 index 836b02fe..00000000 --- a/autoProcessGames.py +++ /dev/null @@ -1,94 +0,0 @@ -import sys -import urllib -import os -import shutil -import ConfigParser -import datetime -import time -import json -import logging - -from nzbToMediaEnv 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 - return urllib.FancyURLopener.open(self, url) - -def process(dirName, nzbName=None, status=0): - - status = int(status) - config = ConfigParser.ConfigParser() - configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - Logger.info("Loading config from %s", configFilename) - - if not os.path.isfile(configFilename): - Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") - return 1 # failure - - config.read(configFilename) - - host = config.get("Gamez", "host") - port = config.get("Gamez", "port") - username = config.get("Gamez", "username") - password = config.get("Gamez", "password") - apikey = config.get("Gamez", "apikey") - - try: - ssl = int(config.get("Gamez", "ssl")) - except (ConfigParser.NoOptionError, ValueError): - ssl = 0 - - try: - web_root = config.get("Gamez", "web_root") - except ConfigParser.NoOptionError: - web_root = "" - - myOpener = AuthURLOpener(username, password) - - if ssl: - protocol = "https://" - else: - protocol = "http://" - - 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 = myOpener.openit(url) - except IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - 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 diff --git a/autoProcessMovie.py b/autoProcessMovie.py deleted file mode 100644 index 3098a1c4..00000000 --- a/autoProcessMovie.py +++ /dev/null @@ -1,244 +0,0 @@ -import sys -import urllib -import os -import shutil -import ConfigParser -import datetime -import time -import json -import logging - -import Transcoder -from nzbToMediaEnv import * -from nzbToMediaSceneExceptions import process_all_exceptions - -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 get_imdb(nzbName, dirName): - - a=nzbName.find('.cp(')+4 #search for .cptt( in nzbName - b=nzbName[a:].find(')')+a - 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 - imdbid=dirName[a:b] - - if imdbid: - Logger.info("Found movie id %s in directory", imdbid) - return imdbid - else: - Logger.warning("Could not find an imdb id in directory or name") - Logger.info("Postprocessing will continue, but the movie may not be identified correctly by CouchPotato") - return "" - -def get_movie_info(myOpener, baseURL, imdbid): - - if not imdbid: - return "" - url = baseURL + "movie.list" - - Logger.debug("Opening URL: %s", url) - - try: - urlObj = myOpener.openit(url) - except IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - return "" - - movie_id = "" - result = json.load(urlObj) - movieid = [item["id"] for item in result["movies"]] - library = [item["library"]["identifier"] for item in result["movies"]] - for index in range(len(movieid)): - if library[index] == imdbid: - movie_id = str(movieid[index]) - Logger.info("Found movie id %s in CPS database for movie %s", movie_id, imdbid) - break - return movie_id - -def get_status(myOpener, baseURL, movie_id): - - if not movie_id: - return "" - url = baseURL + "movie.get/?id=" + str(movie_id) - - Logger.debug("Opening URL: %s", url) - - try: - urlObj = myOpener.openit(url) - except IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - return "" - result = json.load(urlObj) - try: - movie_status = result["movie"]["status"]["identifier"] - Logger.debug("This movie is marked as status %s in CouchPotatoServer", movie_status) - return movie_status - except e: # index out of range/doesn't exist? - Logger.error("Could not find a status for this movie due to: %s", str(e)) - return "" - -def process(dirName, nzbName=None, status=0): - - status = int(status) - config = ConfigParser.ConfigParser() - configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - Logger.info("Loading config from %s", configFilename) - - if not os.path.isfile(configFilename): - Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") - return 1 # failure - - config.read(configFilename) - - host = config.get("CouchPotato", "host") - port = config.get("CouchPotato", "port") - username = config.get("CouchPotato", "username") - password = config.get("CouchPotato", "password") - apikey = config.get("CouchPotato", "apikey") - delay = float(config.get("CouchPotato", "delay")) - method = config.get("CouchPotato", "method") - delete_failed = int(config.get("CouchPotato", "delete_failed")) - - try: - ssl = int(config.get("CouchPotato", "ssl")) - except (ConfigParser.NoOptionError, ValueError): - ssl = 0 - - try: - web_root = config.get("CouchPotato", "web_root") - except ConfigParser.NoOptionError: - web_root = "" - - try: - transcode = int(config.get("Transcoder", "transcode")) - except (ConfigParser.NoOptionError, ValueError): - transcode = 0 - - myOpener = AuthURLOpener(username, password) - - 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 = get_movie_info(myOpener, baseURL, imdbid) # get the CPS database movie id this movie. - - initial_status = get_status(myOpener, baseURL, movie_id) - - process_all_exceptions(nzbName.lower(), 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" - - 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 = myOpener.openit(url) - except IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - return 1 # failure - - result = json.load(urlObj) - Logger.info("CouchPotatoServer returned %s", result) - if result['success']: - Logger.info("%s started on CouchPotatoServer for %s", command, nzbName) - else: - Logger.error("%s has NOT started on CouchPotatoServer for %s. Exiting", command, 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 + "searcher.try_next/?id=" + movie_id - - Logger.debug("Opening URL: %s", url) - - try: - urlObj = myOpener.openit(url) - except IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - 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: - Logger.info("Deleting failed files and folder %s", dirName) - try: - shutil.rmtree(dirName) - except e: - Logger.error("Unable to delete folder %s due to: %s", dirName, str(e)) - return 0 # success - - if nzbName == "Manual Run": - return 0 # success - - # we will now check to see if CPS has finished renaming before returning to TorrentToMedia and unpausing. - start = datetime.datetime.now() # set time for timeout - while (datetime.datetime.now() - start) < datetime.timedelta(minutes=2): # only wait 2 minutes, then return to TorrentToMedia - movie_status = get_status(myOpener, baseURL, movie_id) # get the current status fo this movie. - if 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(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 resule seeding now. - Logger.warning("The movie does not appear to have changed status after 2 minutes. Please check CouchPotato Logs") - return 1 # failure diff --git a/autoProcessMusic.py b/autoProcessMusic.py deleted file mode 100644 index 7787c51d..00000000 --- a/autoProcessMusic.py +++ /dev/null @@ -1,116 +0,0 @@ -import sys -import urllib -import os -import shutil -import ConfigParser -import datetime -import time -import json -import logging - -from nzbToMediaEnv 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 - return urllib.FancyURLopener.open(self, url) - -def process(dirName, nzbName=None, status=0): - - status = int(status) - config = ConfigParser.ConfigParser() - configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - Logger.info("Loading config from %s", configFilename) - - if not os.path.isfile(configFilename): - Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") - return 1 # failure - - config.read(configFilename) - - host = config.get("HeadPhones", "host") - port = config.get("HeadPhones", "port") - username = config.get("HeadPhones", "username") - password = config.get("HeadPhones", "password") - apikey = config.get("HeadPhones", "apikey") - delay = float(config.get("HeadPhones", "delay")) - - try: - ssl = int(config.get("HeadPhones", "ssl")) - except (ConfigParser.NoOptionError, ValueError): - ssl = 0 - - try: - web_root = config.get("HeadPhones", "web_root") - except ConfigParser.NoOptionError: - web_root = "" - - myOpener = AuthURLOpener(username, password) - - 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=" + 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)) - - time.sleep(delay) - - Logger.debug("Opening URL: %s", url) - - try: - urlObj = myOpener.openit(url) - except IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - return 1 # failure - - result = json.load(urlObj) - Logger.info("HeaPhones returned %s", result) - if result == "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 - 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. diff --git a/autoProcessTV.py b/autoProcessTV.py deleted file mode 100644 index 328f1263..00000000 --- a/autoProcessTV.py +++ /dev/null @@ -1,166 +0,0 @@ -# Author: Nic Wolfe -# URL: http://code.google.com/p/sickbeard/ -# -# This file is part of Sick Beard. -# -# Sick Beard is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Sick Beard is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Sick Beard. If not, see . - - -import sys -import urllib -import os -import ConfigParser -import logging - -import Transcoder -from nzbToMediaEnv import * -from nzbToMediaSceneExceptions import process_all_exceptions - -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 processEpisode(dirName, nzbName=None, failed=False): - - status = int(failed) - config = ConfigParser.ConfigParser() - configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - Logger.info("Loading config from %s", configFilename) - - if not os.path.isfile(configFilename): - Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") - return 1 # failure - - try: - fp = open(configFilename, "r") - config.readfp(fp) - fp.close() - except IOError, e: - Logger.error("Could not read configuration file: %s", str(e)) - return 1 # failure - - watch_dir = "" - host = config.get("SickBeard", "host") - port = config.get("SickBeard", "port") - username = config.get("SickBeard", "username") - password = config.get("SickBeard", "password") - try: - ssl = int(config.get("SickBeard", "ssl")) - except (ConfigParser.NoOptionError, ValueError): - ssl = 0 - - try: - web_root = config.get("SickBeard", "web_root") - except ConfigParser.NoOptionError: - web_root = "" - - try: - watch_dir = config.get("SickBeard", "watch_dir") - except ConfigParser.NoOptionError: - watch_dir = "" - - try: - failed_fork = int(config.get("SickBeard", "failed_fork")) - except (ConfigParser.NoOptionError, ValueError): - failed_fork = 0 - try: - transcode = int(config.get("Transcoder", "transcode")) - except (ConfigParser.NoOptionError, ValueError): - transcode = 0 - - process_all_exceptions(nzbName.lower(), dirName) - - - #allows manual call of postprocess script if we have specified a watch_dir. Check that here. - if nzbName == "Manual Run" and watch_dir == "": - Logger.error("In order to run this script manually you must specify a watch_dir in autoProcessTV.cfg") - return 1 # failure - #allows us to specify the default watch directory and call the postproecssing on another PC with different directory structure. - if watch_dir != "": - dirName = watch_dir - - params = {} - - params['quiet'] = 1 - - # if you have specified you are using development branch from fork https://github.com/Tolstyak/Sick-Beard.git - if failed_fork: - params['dirName'] = dirName - if nzbName != None: - params['nzbName'] = nzbName - params['failed'] = failed - if status == 0: - Logger.info("The download succeeded. Sending process request to SickBeard's failed branch") - else: - Logger.info("The download failed. Sending 'failed' process request to SickBeard's failed branch") - - - # this is our default behaviour to work with the standard Master branch of SickBeard - else: - params['dir'] = dirName - if nzbName != None: - params['nzbName'] = nzbName - # the standard Master bamch of SickBeard cannot process failed downloads. So Exit here. - if status == 0: - Logger.info("The download succeeded. Sending process request to SickBeard") - else: - Logger.info("The download failed. Nothing to process") - 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) - - Logger.debug("Opening URL: %s", url) - - try: - urlObj = myOpener.openit(url) - except IOError, e: - Logger.error("Unable to open URL: %s", str(e)) - return 1 # failure - - result = urlObj.readlines() - for line in result: - Logger.info("%s", line) - return 0 # Success diff --git a/migratecfg.py b/migratecfg.py deleted file mode 100644 index 68fabf96..00000000 --- a/migratecfg.py +++ /dev/null @@ -1,191 +0,0 @@ -#System imports -import ConfigParser -import sys -import os - -def migrate(): - confignew = ConfigParser.ConfigParser() - confignew.optionxform = str - configFilenamenew = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.sample") - confignew.read(configFilenamenew) - - configold = ConfigParser.ConfigParser() - confignew.optionxform = str - - section = "CouchPotato" - original = [] - configFilenameold = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - if not os.path.isfile(configFilenameold): # lets look back for an older version. - configFilenameold = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMovie.cfg") - if not os.path.isfile(configFilenameold): # no config available - configFilenameold = "" - if configFilenameold: # read our old config. - configold.read(configFilenameold) - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - 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(outputdirectory))[0] - confignew.set("Torrent", option, value) - continue - confignew.set(section, option, value) - - section = "SickBeard" - original = [] - configFilenameold = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - if not os.path.isfile(configFilenameold): # lets look back for an older version. - configFilenameold = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessTV.cfg") - if not os.path.isfile(configFilenameold): # no config available - configFilenameold = "" - if configFilenameold: # read our old config. - configold.read(configFilenameold) - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - if option == "category": # change this old format - option = "sbCategory" - if option == "outputDirectory": # move this to new location format - value = os.path.split(os.path.normpath(outputdirectory))[0] - confignew.set("Torrent", option, value) - continue - confignew.set(section, option, value) - - section = "HeadPhones" - original = [] - configFilenameold = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") - if not os.path.isfile(configFilenameold): - configFilenameold = "" - if configFilenameold: # read our old config. - configold.read(configFilenameold) - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "Mylar" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "Gamez" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "Torrent" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - if option in ["compressedExtensions", "mediaExtensions", "metaExtensions"]: - section = "Extensions" # these were moved - confignew.set(section, option, value) - section = "Torrent" # reset in case extensions out of order. - - section = "Transcoder" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "loggers" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "handlers" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "formatters" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "logger_root" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "handler_console" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - section = "formatter_generic" - original = [] - try: - original = configold.items(section) - except: - pass - for item in original: - option, value = item - confignew.set(section, option, value) - - # writing our configuration file to 'autoProcessMedia.cfg.sample' - with open(configFilenamenew, 'wb') as configFile: - confignew.write(configFile) - - # create a backup of our old config - backupname = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg.old") - if os.path.isfile(backupname): # remove older backups - os.unlink(backupname) - os.rename(configFilenameold, backupname) - - # rename our newly edited autoProcessMedia.cfg.sample to autoProcessMedia.cfg - os.rename(configFilenamenew, configFilenameold) - return diff --git a/nzbToMediaEnv.py b/nzbToMediaEnv.py deleted file mode 100644 index 00a0308c..00000000 --- a/nzbToMediaEnv.py +++ /dev/null @@ -1,10 +0,0 @@ -# Make things easy and less error prone by centralising all common values - -# Global Constants -VERSION = 'V6.1' - -# Constants pertinant to SabNzb -SABNZB_NO_OF_ARGUMENTS = 8 - -# Constants pertinant to NzbGet -NZBGET_NO_OF_ARGUMENTS = 5 diff --git a/nzbToMediaSceneExceptions.py b/nzbToMediaSceneExceptions.py deleted file mode 100644 index b05e2b93..00000000 --- a/nzbToMediaSceneExceptions.py +++ /dev/null @@ -1,35 +0,0 @@ -# System imports -import os -import logging - -# Custom imports -from nzbToMediaUtil import iterate_media_files - - -Logger = logging.getLogger() - - -def process_all_exceptions(name, dirname): - for group, exception in __customgroups__.items(): - if not (group in name or group in dirname): - continue - process_exception(exception, name, dirname) - - -def process_exception(exception, name, dirname): - for parentDir, filename in iterate_media_files(dirname): - exception(filename, parentDir) - - -def process_qoq(filename, dirname): - Logger.debug("Reversing the file name for a QoQ release %s", filename) - head, fileExtension = os.path.splitext(os.path.basename(filename)) - newname = head[::-1] - newfile = newname + fileExtension - newfilePath = os.path.join(dirname, newfile) - os.rename(filename, newfilePath) - Logger.debug("New file name is %s", newfile) - -# dict for custom groups -# we can add more to this list -__customgroups__ = {'Q o Q': process_qoq} diff --git a/nzbToMediaUtil.py b/nzbToMediaUtil.py deleted file mode 100644 index 935934c6..00000000 --- a/nzbToMediaUtil.py +++ /dev/null @@ -1,262 +0,0 @@ -import logging -import logging.config -import os -import re -import sys -import shutil - -import linktastic.linktastic as linktastic - -Logger = logging.getLogger() - - -def safeName(name): - safename = re.sub(r"[\/\\\:\*\?\"\<\>\|]", "", name) #make this name safe for use in directories for windows etc. - return safename - - -def nzbtomedia_configure_logging(dirname): - logFile = os.path.join(dirname, "postprocess.log") - logging.config.fileConfig(os.path.join(dirname, "autoProcessMedia.cfg")) - fileHandler = logging.FileHandler(logFile, encoding='utf-8', delay=True) - fileHandler.formatter = logging.Formatter('%(asctime)s|%(levelname)-7.7s %(message)s', '%H:%M:%S') - fileHandler.level = logging.DEBUG - logging.getLogger().addHandler(fileHandler) - - -def create_destination(outputDestination): - if os.path.exists(outputDestination): - return - try: - Logger.info("CREATE DESTINATION: Creating destination folder: %s", outputDestination) - os.makedirs(outputDestination) - except Exception, e: - Logger.error("CREATE DESTINATION: Not possible to create destination folder: %s. Exiting", e) - sys.exit(-1) - -def category_search(inputDirectory, inputName, inputCategory, root, categories): - categorySearch = [os.path.normpath(inputDirectory), ""] # initializie - notfound = 0 - for x in range(10): # loop up through 10 directories looking for category. - try: - categorySearch2 = os.path.split(os.path.normpath(categorySearch[0])) - except: # this might happen when we can't go higher. - if inputCategory and inputName: # if these exists, we are ok to proceed, but assume we are in a root/common directory. - Logger.info("SEARCH: Could not find a Torrent Name or category in the directory structure") - Logger.info("SEARCH: We assume the directory passed is the root directory for your downlaoder") - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 1 - break # we are done - elif inputCategory: # if this exists, we are ok to proceed, but assume we are in a root/common directory and we have to check file dates. - Logger.info("SEARCH: Could not find a Torrent Name or Category in the directory structure") - Logger.info("SEARCH: We assume the directory passed is the root directory for your downlaoder") - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 2 - break # we are done - else: - Logger.error("SEARCH: Could not identify Category of Torrent Name in the directory structure. Please check downloader settings. Exiting") - sys.exit(-1) - - if categorySearch2[1] in categories: - Logger.debug("SEARCH: Found Category: %s in directory structure", categorySearch2[1]) - if not inputCategory: - Logger.info("SEARCH: Determined Category to be: %s", categorySearch2[1]) - inputCategory = categorySearch2[1] - if inputName and categorySearch[0] != os.path.normpath(inputDirectory): # if we are not in the root directory and we have inputName we can continue. - if ('.cp(tt' in categorySearch[1]) and (not '.cp(tt' in inputName): # if the directory was created by CouchPotato, and this tag is not in Torrent name, we want to add it. - Logger.info("SEARCH: Changing Torrent Name to %s to preserve imdb id.", categorySearch[1]) - inputName = categorySearch[1] - Logger.info("SEARCH: Identified Category: %s and Torrent Name: %s. We are in a unique directory, so we can proceed.", inputCategory, inputName) - break # we are done - elif categorySearch[1] and not inputName: # assume the the next directory deep is the torrent name. - Logger.info("SEARCH: Found torrent directory %s in category directory %s", os.path.join(categorySearch[0], categorySearch[1]), categorySearch[0]) - inputName = categorySearch[1] - break # we are done - elif ('.cp(tt' in categorySearch[1]) and (not '.cp(tt' in inputName): # if the directory was created by CouchPotato, and this tag is not in Torrent name, we want to add it. - Logger.info("SEARCH: Changing Torrent Name to %s to preserve imdb id.", categorySearch[1]) - inputName = categorySearch[1] - break # we are done - elif os.path.isdir(os.path.join(categorySearch[0], inputName)) and inputName: # testing for torrent name in first sub directory - Logger.info("SEARCH: Found torrent directory %s in category directory %s", os.path.join(categorySearch[0], inputName), categorySearch[0]) - if categorySearch[0] == os.path.normpath(inputDirectory): # only true on first pass, x =0 - inputDirectory = os.path.join(categorySearch[0], inputName) # we only want to search this next dir up. - break # we are done - elif os.path.isdir(os.path.join(categorySearch[0], safeName(inputName))) and inputName: # testing for torrent name in first sub directory - Logger.info("SEARCH: Found torrent directory %s in category directory %s", os.path.join(categorySearch[0], safeName(inputName)), categorySearch[0]) - if categorySearch[0] == os.path.normpath(inputDirectory): # only true on first pass, x =0 - inputDirectory = os.path.join(categorySearch[0], safeName(inputName)) # we only want to search this next dir up. - break # we are done - elif inputName: # if these exists, we are ok to proceed, but we are in a root/common directory. - Logger.info("SEARCH: Could not find a unique torrent folder in the directory structure") - Logger.info("SEARCH: The directory passed is the root directory for category %s", categorySearch2[1]) - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 1 - break # we are done - else: # this is a problem! if we don't have Torrent name and are in the root category dir, we can't proceed. - Logger.warn("SEARCH: Could not identify a torrent name and the directory passed is common to all downloads for category %s.", categorySearch[1]) - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 2 - break - elif safeName(categorySearch2[1]) == safeName(inputName) and inputName: # we have identified a unique directory. - Logger.info("SEARCH: Files appear to be in their own directory") - if inputCategory: # we are ok to proceed. - break # we are done - else: - Logger.debug("SEARCH: Continuing scan to determin category.") - categorySearch = categorySearch2 # ready for next loop - continue # keep going - else: - if x == 9: # This is the last pass in the loop and we didn't find anything. - notfound = 1 - break # we are done - else: - categorySearch = categorySearch2 # ready for next loop - continue # keep going - - if notfound == 1: - if inputCategory and inputName: # if these exists, we are ok to proceed, but assume we are in a root/common directory. - Logger.info("SEARCH: Could not find a category in the directory structure") - Logger.info("SEARCH: We assume the directory passed is the root directory for your downlaoder") - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 1 - elif inputCategory: # if this exists, we are ok to proceed, but assume we are in a root/common directory and we have to check file dates. - Logger.info("SEARCH: Could not find a Torrent Name or Category in the directory structure") - Logger.info("SEARCH: We assume the directory passed is the root directory for your downlaoder") - Logger.warn("SEARCH: You should change settings to download torrents to their own directory if possible") - Logger.info("SEARCH: We will try and determine which files to process, individually") - root = 2 - if not inputCategory: # we didn't find this after 10 loops. This is a problem. - Logger.error("SEARCH: Could not identify category and torrent name from the directory structure. Please check downloader settings. Exiting") - sys.exit(-1) # Oh yeah.... WE ARE DONE! - - return inputDirectory, inputName, inputCategory, root - - -def is_sample(filePath, inputName, minSampleSize): - # 200 MB in bytes - SIZE_CUTOFF = minSampleSize * 1024 * 1024 - # Ignore 'sample' in files unless 'sample' in Torrent Name - return ('sample' in filePath.lower()) and (not 'sample' in inputName) and (os.path.getsize(filePath) < SIZE_CUTOFF) - - -def copy_link(filePath, targetDirectory, useLink, outputDestination): - create_destination(outputDestination) - if useLink != 0: - try: - Logger.info("COPYLINK: Linking %s to %s", filePath, targetDirectory) - linktastic.link(filePath, targetDirectory) - except: - if os.path.isfile(targetDirectory): - Logger.info("COPYLINK: Something went wrong in linktastic.link, but the destination file was created") - else: - Logger.info("COPYLINK: Something went wrong in linktastic.link, copying instead") - Logger.debug("COPYLINK: Copying %s to %s", filePath, targetDirectory) - shutil.copy(filePath, targetDirectory) - else: - Logger.debug("Copying %s to %s", filePath, targetDirectory) - shutil.copy(filePath, targetDirectory) - return True - - -def flatten(outputDestination): - Logger.info("FLATTEN: Flattening directory: %s", outputDestination) - for dirpath, dirnames, filenames in os.walk(outputDestination): # Flatten out the directory to make postprocessing easier - if dirpath == outputDestination: - continue # No need to try and move files in the root destination directory - for filename in filenames: - source = os.path.join(dirpath, filename) - target = os.path.join(outputDestination, filename) - try: - shutil.move(source, target) - except OSError: - Logger.error("FLATTEN: Could not flatten %s", source) - removeEmptyFolders(outputDestination) # Cleanup empty directories - - -def removeEmptyFolders(path): - Logger.info("REMOVER: Removing empty folders in: %s", path) - if not os.path.isdir(path): - return - - # Remove empty subfolders - files = os.listdir(path) - if len(files): - for f in files: - fullpath = os.path.join(path, f) - if os.path.isdir(fullpath): - removeEmptyFolders(fullpath) - - # If folder empty, delete it - files = os.listdir(path) - if len(files) == 0: - Logger.debug("REMOVER: Removing empty folder: %s", path) - os.rmdir(path) - -def iterate_media_files(dirname): - mediaContainer = [ '.mkv', '.avi', '.divx', '.xvid', '.mov', '.wmv', - '.mp4', '.mpg', '.mpeg', '.iso' ] - - for dirpath, dirnames, filesnames in os.walk(dirname): - for filename in filesnames: - fileExtension = os.path.splitext(filename)[1] - if not (fileExtension in mediaContainer): - continue - yield dirpath, os.path.join(dirpath, filename) - - -def parse_other(args): - return os.path.normpath(sys.argv[1]), '', '', '' - - -def parse_utorrent(args): - # uTorrent usage: call TorrentToMedia.py "%D" "%N" "%L" "%I" - inputDirectory = os.path.normpath(args[1]) - inputName = args[2] - try: - inputCategory = args[3] - except: - inputCategory = '' - try: - inputHash = args[4] - except: - inputHash = '' - - return inputDirectory, inputName, inputCategory, inputHash - - -def parse_deluge(args): - # Deluge usage: call TorrentToMedia.py TORRENT_ID TORRENT_NAME TORRENT_DIR - inputDirectory = os.path.normpath(sys.argv[3]) - inputName = sys.argv[2] - inputCategory = '' # We dont have a category yet - inputHash = '' - return inputDirectory, inputName, inputCategory, inputHash - - -def parse_transmission(args): - # Transmission usage: call TorrenToMedia.py (%TR_TORRENT_DIR% %TR_TORRENT_NAME% is passed on as environmental variables) - inputDirectory = os.path.normpath(os.getenv('TR_TORRENT_DIR')) - inputName = os.getenv('TR_TORRENT_NAME') - inputCategory = '' # We dont have a category yet - inputHash = '' - return inputDirectory, inputName, inputCategory, inputHash - - -__ARG_PARSERS__ = { - 'other': parse_other, - 'utorrent': parse_utorrent, - 'deluge': parse_deluge, - 'transmission': parse_transmission, -} - - -def parse_args(clientAgent): - parseFunc = __ARG_PARSERS__.get(clientAgent, None) - if not parseFunc: - raise RuntimeError("Could not find client-agent") - return parseFunc(sys.argv)