def __init__(self, config, log = None): self.config = config if log is not None: warnings.warn("the UI's log parameter is deprecated, instead use\n" "use import logging; logging.getLogger('ui').info('blah')\n" "The self.log attribute will be removed in the next version") self.log = LoggingAdapter.getLogger(__name__)
def __init__(self, settings=None, logger=None): if logger: self.log = logger else: self.log = LoggingAdapter.getLogger(__name__) if settings is None: raise ValueError("Settings not supplied") self.settings = settings self.converter = MkvtoMp4(settings)
def __init__(self, files, logger=None): # Setup Logging if logger: self.log = logger else: self.log = LoggingAdapter.getLogger(__name__) self.log.debug("Output: %s" % files) self.set_script_environment(files) self.scripts = self.gather_scripts()
def refreshPlex(settings, source_type, logger=None): if logger: log = logger else: log = LoggingAdapter.getLogger(__name__) host = settings.Plex['host'] port = settings.Plex['port'] token = settings.Plex['token'] log.debug("Host: %s." % host) log.debug("Port: %s." % port) log.debug("Token: %s." % token) approved_sources = ['movie', 'show'] if settings.Plex['refresh'] and source_type in approved_sources: base_url = 'http://%s:%s/library/sections' % (host, port) refresh_url = '%s/%%s/refresh' % base_url if token: refresh_url = refresh_url + "?X-Plex-Token=" + token base_url = base_url + "?X-Plex-Token=" + token log.debug("Plex home token detected.") log.debug("Refresh URL: %s." % refresh_url) log.debug("Base URL: %s." % base_url) try: xml_sections = minidom.parse(urlopen(base_url)) sections = xml_sections.getElementsByTagName('Directory') for s in sections: if s.getAttribute('type') == source_type: url = refresh_url % s.getAttribute('key') x = urlopen(url) except Exception: log.exception("Unable to refresh plex, check your settings.")
def processEpisode(dirName, settings, nzbGet=False, logger=None): if nzbGet: errorprefix = "[ERROR] " infoprefix = "[INFO] " else: errorprefix = "" infoprefix = "" # Setup logging if logger: log = logger else: log = LoggingAdapter.getLogger(__name__) log.info("%sSonarr notifier started." % infoprefix) # Import Requests try: import requests except ImportError: log.exception( "%sPython module REQUESTS is required. Install with 'pip install requests' then try again." % errorprefix) log.error("%sPython executable path is %s" % (errorprefix, sys.executable)) return False host = settings.Sonarr['host'] port = settings.Sonarr['port'] apikey = settings.Sonarr['apikey'] if apikey == '': log.error( "%sYour Sonarr API Key can not be blank. Update autoProcess.ini." % errorprefix) return False try: ssl = int(settings.Sonarr['ssl']) except: ssl = 0 if ssl: protocol = "https://" else: protocol = "http://" url = protocol + host + ":" + port + "/api/command" payload = {'name': 'downloadedepisodesscan', 'path': dirName} headers = {'X-Api-Key': apikey} log.debug("Sonarr host: %s." % host) log.debug("Sonarr port: %s." % port) log.debug("Sonarr apikey: %s." % apikey) log.debug("Sonarr protocol: %s." % protocol) log.debug("URL '%s' with payload '%s.'" % (url, payload)) log.info("%sRequesting Sonarr to scan directory '%s'." % (infoprefix, dirName)) try: r = requests.post(url, data=json.dumps(payload), headers=headers) rstate = r.json() log.info("%sSonarr response: %s." % (infoprefix, rstate['state'])) return True except: log.exception( "%sUpdate to Sonarr failed, check if Sonarr is running, autoProcess.ini settings and make sure your Sonarr settings are correct (apikey?), or check install of python modules requests." % errorprefix) return False
#!/usr/bin/env python import os.path import os import re import signal from subprocess import Popen, PIPE import logging import locale from _utils import LoggingAdapter logger = LoggingAdapter.getLogger(__name__) console_encoding = locale.getdefaultlocale()[1] or 'UTF-8' class FFMpegError(Exception): pass class FFMpegConvertError(Exception): def __init__(self, message, cmd, output, details=None, pid=0): """ @param message: Error message. @type message: C{str} @param cmd: Full command string used to spawn ffmpeg. @type cmd: C{str} @param output: Full stdout output from the ffmpeg command. @type output: C{str}
def processEpisode(dir_to_process, settings, org_NZB_name=None, status=None, logger=None): # Setup logging if logger: log = logger else: log = LoggingAdapter.getLogger(__name__) try: import requests except ImportError: log.exception("You need to install python requests library.") sys.exit(1) # Try importing Python 2 modules using new names try: from urllib import urlencode # On error import Python 3 modules except ImportError: from urllib.parse import urlencode host = settings.Sickrage['host'] port = settings.Sickrage['port'] username = settings.Sickrage['user'] password = settings.Sickrage['pass'] try: ssl = int(settings.Sickrage['ssl']) except: ssl = 0 try: web_root = settings.Sickrage['web_root'] if not web_root.startswith("/"): web_root = "/" + web_root if not web_root.endswith("/"): web_root = web_root + "/" except: web_root = "" params = {} params['quiet'] = 1 params['dir'] = dir_to_process if org_NZB_name is not None: params['nzbName'] = org_NZB_name if status is not None: params['failed'] = status if ssl: protocol = "https://" else: protocol = "http://" url = protocol + host + ":" + port + web_root + "home/postprocess/processEpisode" login_url = protocol + host + ":" + port + web_root + "login" log.debug('Host: %s.' % host) log.debug('Port: %s.' % port) log.debug('Username: %s.' % username) log.debug('Password: %s.' % password) log.debug('Protocol: %s.' % protocol) log.debug('Web Root: %s.' % web_root) log.debug('URL: %s.' % url) log.debug('Login URL: %s.' % login_url) log.info("Opening URL: %s." % url) try: sess = requests.Session() sess.post(login_url, data={'username': username, 'password': password}, stream=True, verify=False) result = sess.get(url, params=params, stream=True, verify=False) lastline = None for line in result.iter_lines(): if line: log.debug(line.strip()) lastline = line.strip() if lastline: log.info(lastline) except IOError: e = sys.exc_info()[1] log.exception("Unable to open URL: %s." % str(e)) sys.exit(1)
#!/usr/bin/env python import os import sys import json import urllib sys.path.append(os.path.join(os.path.dirname(__file__), "..")) from readSettings import settingsProvider from _utils import LoggingAdapter srconfig = settingsProvider( config_file=os.environ.get('MH_CONFIG')).defaultSettings.Sickrage log = LoggingAdapter.getLogger() def apiPostProcess(): log.info("Triggering Sickrage Post Process") api_url = getApiUrl() + "cmd=postprocess&is_priority=1&force_replace=1" refresh = json.load(urllib.urlopen(api_url)) if resultToBool(refresh["result"]): log.debug("Post Process was initiated.") return True else: log.error("Something went wrong, output was:") log.error(json.dumps(refresh, indent=4)) return False def getApiUrl(): protocol = "http://" # SSL try:
#!/usr/bin/env python import os import sys import json import urllib import struct from _utils import LoggingAdapter log = LoggingAdapter.getLogger("MANUAL", {}) log.info("Sickbeard extra script post processing started") from readSettings import ReadSettings from autoprocess import plex from tvdb_mp4 import Tvdb_mp4 #from mkvtomp4 import MkvtoMp4 #from post_processor import PostProcessor from processor import fileProcessor settings = settingsProvider().defaultSettings processor = fileProcessor(settings) if len(sys.argv) > 4: inputfile = sys.argv[1] original = sys.argv[2] tvdb_id = int(sys.argv[3]) season = int(sys.argv[4]) episode = int(sys.argv[5]) log.debug("Input file: %s" % inputfile) log.debug("Original name: %s" % original) log.debug("TvDB ID: %s" % tvdb_id)
def processEpisode(dirName, settings, nzbName=None, logger=None): # Setup logging if logger: log = logger else: log = LoggingAdapter.getLogger(__name__) host = settings.Sickbeard['host'] port = settings.Sickbeard['port'] username = settings.Sickbeard['user'] password = settings.Sickbeard['pass'] try: ssl = int(settings.Sickbeard['ssl']) except: ssl = 0 try: web_root = settings.Sickbeard['web_root'] except: web_root = "" params = {} params['quiet'] = 1 params['dir'] = dirName if nzbName is not None: params['nzbName'] = nzbName myOpener = AuthURLOpener(username, password) if ssl: protocol = "https://" else: protocol = "http://" url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urlencode( params) log.debug('Host: %s.' % host) log.debug('Port: %s.' % port) log.debug('Username: %s.' % username) log.debug('Password: %s.' % password) log.debug('Protocol: %s.' % protocol) log.debug('Web Root: %s.' % web_root) log.debug('URL: %s.' % url) log.info("Opening URL: %s." % url) try: urlObj = myOpener.openit(url) except IOError: log.exception("Unable to open URL") sys.exit(1) result = urlObj.readlines() lastline = None for line in result: if line: log.debug(line.strip()) lastline = line.strip() if lastline: log.info(lastline)
def process(dirName, settings, nzbName=None, status=0, logger=None): # Setup logging if logger: log = logger else: log = LoggingAdapter.getLogger(__name__) status = int(status) host = settings.CP['host'] port = settings.CP['port'] username = settings.CP['username'] password = settings.CP['password'] apikey = settings.CP['apikey'] delay = settings.CP['delay'] method = settings.CP['method'] delete_failed = settings.CP['delete_failed'] protocol = settings.CP['protocol'] web_root = settings.CP['web_root'] if web_root != "" and not web_root.startswith("/"): web_root = "/" + web_root myOpener = AuthURLOpener(username, password) nzbName1 = str(nzbName) # Don't delay when we are calling this script manually. if nzbName == "Manual Run": delay = 0 log.debug("Host: %s." % host) log.debug("Port: %s." % port) log.debug("Username: %s." % username) log.debug("Password: %s." % password) log.debug("APIKey: %s." % apikey) log.debug("Delay: %s." % delay) log.debug("Method: %s." % method) log.debug("Delete Failed: %s." % delete_failed) log.debug("Protocol: %s." % protocol) log.debug("Web Root: %s." % web_root) if status == 0: if method == "manage": command = "manage.update" else: command = "renamer.scan" url = protocol + host + ":" + port + web_root + "/api/" + apikey + "/" + command params = {'media_folder': dirName, 'downloader': 'manual'} log.info( "Waiting for %s seconds to allow CPS to process newly extracted files." % str(delay)) time.sleep(delay) log.info("Opening URL: %s." % url) r = requests.get(url, params=params) rstate = r.json() log.info("CouchPotatoServer returned %s." % rstate) if rstate['success']: log.info("%s started on CouchPotatoServer for %s." % (command, nzbName1)) else: log.error("%s has NOT started on CouchPotatoServer for %s." % (command, nzbName1)) else: log.info("Download of %s has failed." % nzbName1) log.info("Trying to re-cue the next highest ranked release.") try: a = nzbName1.find('.cp(') + 4 b = nzbName1[a:].find(')') + a imdbid = nzbName1[a:b] log.debug("Attempt to determine IMDBID resulted in '%s'." % imdbid) except: log.exception( "Unable to determine release IMDB ID for requeueing.") sys.exit() url = protocol + host + ":" + port + web_root + "/api/" + apikey + "/movie.list" log.info("Opening URL: %s." % url) try: urlObj = myOpener.openit(url) except IOError: log.exception("Unable to open URL.") sys.exit(1) n = 0 result = json.load(urlObj) movieid = [item["info"]["imdb"] for item in result["movies"]] log.debug("Movie ID: %s." % movieid) for index in range(len(movieid)): if movieid[index] == imdbid: movid = str(movieid[index]) log.info("Found movie id %s in database for release %s." % (movid, nzbName1)) n = n + 1 break if n == 0: log.error( "Cound not find a movie in the database for release %s." % nzbName1) log.error( "Please manually ignore this release and refresh the wanted movie." ) log.error("Exiting postprocessing script") sys.exit(1) url = protocol + host + ":" + port + web_root + "/api/" + apikey + "/movie.searcher.try_next/?media_id=" + movid log.info("Opening URL: %s." % url) try: urlObj = myOpener.openit(url) except IOError: log.exception("Unable to open URL.") sys.exit(1) result = urlObj.readlines() for line in result: log.info(line) log.info( "Movie %s set to try the next best release on CouchPotatoServer." % movid) if delete_failed: log.error("Deleting failed files and folder %s." % dirName) shutil.rmtree(dirName)
if IS_PY2: int_types = (int, long) text_type = unicode else: int_types = int text_type = str from .tvdb_ui import BaseUI, ConsoleUI from .tvdb_exceptions import (tvdb_error, tvdb_userabort, tvdb_shownotfound, tvdb_seasonnotfound, tvdb_episodenotfound, tvdb_attributenotfound) lastTimeout = None log = logger = LoggingAdapter.getLogger("tvdb_api") #def log(): # return logger class ShowContainer(dict): """Simple dict that holds a series of Show instances """ def __init__(self): self._stack = [] self._lastgc = time.time() def __setitem__(self, key, value): self._stack.append(key) #keep only the 100th latest results
def __init__(self, directory, filename, logger=None): # Setup logging if logger: log = logger else: log = LoggingAdapter.getLogger(__name__) # Setup encoding to avoid UTF-8 errors if sys.version[0] == '2': SYS_ENCODING = None try: locale.setlocale(locale.LC_ALL, "") SYS_ENCODING = locale.getpreferredencoding() except (locale.Error, IOError): pass # For OSes that are poorly configured just force UTF-8 if not SYS_ENCODING or SYS_ENCODING in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'): SYS_ENCODING = 'UTF-8' if not hasattr(sys, "setdefaultencoding"): reload(sys) try: # pylint: disable=E1101 # On non-unicode builds this will raise an AttributeError, if encoding type is not valid it throws a LookupError sys.setdefaultencoding(SYS_ENCODING) except: log.exception("Sorry, your environment is not setup correctly for utf-8 support. Please fix your setup and try again") sys.exit("Sorry, your environment is not setup correctly for utf-8 support. Please fix your setup and try again") #log.info(sys.executable) # Default settings for SickBeard sb_defaults = {'host': 'localhost', 'port': '8081', 'ssl': "False", 'api_key': '', 'web_root': '', 'username': '', 'password': ''} # Default MP4 conversion settings mp4_defaults = {'ffmpeg': 'ffmpeg.exe', 'ffprobe': 'ffprobe.exe', 'output_directory': '', 'copy_to': '', 'move_to': 'True', 'output_extension': 'mp4', 'output_format': 'mp4', 'delete_original': 'True', 'relocate_moov': 'True', 'ios-audio': 'True', 'ios-first-track-only': 'False', 'ios-audio-filter': '', 'max-audio-channels': '', 'audio-language': '', 'audio-default-language': '', 'audio-codec': 'ac3', 'audio-filter': '', 'audio-channel-bitrate': '256', 'video-codec': 'h264, x264', 'video-bitrate': '', 'video-max-width': '', 'h264-max-level': '', 'use-qsv-decoder-with-encoder': 'False', 'subtitle-codec': 'mov_text', 'subtitle-language': '', 'subtitle-default-language': '', 'subtitle-encoding': '', 'convert-mp4': 'False', 'meks-video-quality': '', 'meks-h264-preset': 'medium', 'meks-staging': 'True', 'meks-staging-extension': 'part', 'meks-metadata': '', 'meks-nfosearch': 'True', 'meks-nfopaths': '..', 'meks-walk-ignore': 'ignore.part,ignore.skip,recode.ignore,recode.skip', 'meks-walk-ignore-self': 'True', 'meks-transcode-ignore-names': 'sample', 'meks-transcode-ignore-size': '0', 'meks-qsv-lookahead': '1', 'meks-same-vcodec-copy': 'True', 'meks-same-acodec-copy': 'True', 'meks-aac-adtstoasc': 'False', 'meks-id3v2vers': '3', 'meks-tag-rename': 'False', 'meks-tag-language-auto' : 'False', 'meks-tag-mandatory': 'False', 'fullpathguess': 'True', 'tagfile': 'True', 'tag-language': 'en', 'download-artwork': 'poster', 'download-subs': 'False', 'embed-subs': 'True', 'sub-providers': 'addic7ed, podnapisi, thesubdb, opensubtitles', 'permissions': '777', 'post-process': 'False', 'pix-fmt': ''} # Default settings for CouchPotato cp_defaults = {'host': 'localhost', 'port': '5050', 'username': '', 'password': '', 'apikey': '', 'delay': '65', 'method': 'renamer', 'delete_failed': 'False', 'ssl': 'False', 'web_root': ''} # Default settings for Sonarr sonarr_defaults = {'host': 'localhost', 'port': '8989', 'apikey': '', 'ssl': 'False', 'web_root': ''} # Default uTorrent settings utorrent_defaults = {'couchpotato-label': 'couchpotato', 'sickbeard-label': 'sickbeard', 'sickrage-label': 'sickrage', 'sonarr-label': 'sonarr', 'bypass-label': 'bypass', 'convert': 'True', 'webui': 'False', 'action_before': 'stop', 'action_after': 'removedata', 'host': 'http://localhost:8080/', 'username': '', 'password': ''} # Default SAB settings sab_defaults = {'convert': 'True', 'Sickbeard-category': 'sickbeard', 'Sickrage-category': 'sickrage', 'Couchpotato-category': 'couchpotato', 'Sonarr-category': 'sonarr', 'Bypass-category': 'bypass'} # Default Sickrage Settings sr_defaults = {'host': 'localhost', 'port': '8081', 'ssl': "False", 'api_key': '', 'web_root': '', 'username': '', 'password': ''} # Default deluge settings deluge_defaults = {'couchpotato-label': 'couchpotato', 'sickbeard-label': 'sickbeard', 'sickrage-label': 'sickrage', 'sonarr-label': 'sonarr', 'bypass-label': 'bypass', 'convert': 'True', 'host': 'localhost', 'port': '58846', 'username': '', 'password': ''} # Default Plex Settings plex_defaults = {'host': 'localhost', 'port': '32400', 'refresh': 'true', 'token': ''} defaults = {'SickBeard': sb_defaults, 'CouchPotato': cp_defaults, 'Sonarr': sonarr_defaults, 'MP4': mp4_defaults, 'uTorrent': utorrent_defaults, 'SABNZBD': sab_defaults, 'Sickrage': sr_defaults, 'Deluge': deluge_defaults, 'Plex': plex_defaults} write = False # Will be changed to true if a value is missing from the config file and needs to be written config = configparser.SafeConfigParser() configFile = os.path.join(directory, filename) if os.path.isfile(configFile): config.read(configFile) else: log.error("Config file not found, creating %s" % configFile) # config.filename = filename write = True # Make sure all sections and all keys for each section are present for s in defaults: if not config.has_section(s): config.add_section(s) write = True for k in defaults[s]: if not config.has_option(s, k): config.set(s, k, defaults[s][k]) write = True # If any keys are missing from the config file, write them if write: self.writeConfig(config, configFile) # Read relevant MP4 section information section = "MP4" self.ffmpeg = os.path.normpath(self.raw(config.get(section, "ffmpeg"))) # Location of FFMPEG.exe self.ffprobe = os.path.normpath(self.raw(config.get(section, "ffprobe"))) # Location of FFPROBE.exe self.output_dir = config.get(section, "output_directory") if self.output_dir == '': self.output_dir = None else: self.output_dir = os.path.normpath(self.raw(self.output_dir)) # Output directory cptod = {'movie':[], 'tv':[], 'all':[]} for cptol in ['copy_to']: cpto = config.get(section, cptol) if not cpto == '': cpto = cpto.split('|') for kv in cpto: if kv[:6] == 'movie:': cptok = kv[:5] cptop = kv[6:] elif kv[:3] == 'tv:': cptok = kv[:2] cptop = kv[3:] else: cptok = "all" cptop = kv cptop = os.path.normpath(cptop) if not os.path.isdir(cptop): try: os.makedirs(cptop) except: log.exception("Error making directory %s" % cptop) continue #log.debug("%s path for type '%s' added: %s" % (cptol, cptok, cptop)) cptod[cptok].append(cptop) self.copyto = cptod # Directories to copy the final file to self.moveto = config.getboolean(section, "move_to") # Move instead of copy self.output_extension = config.get(section, "output_extension") # Output extension self.output_format = config.get(section, "output_format") # Output format if self.output_format not in valid_formats: self.output_format = 'mov' self.delete = config.getboolean(section, "delete_original") # Delete original file self.relocate_moov = config.getboolean(section, "relocate_moov") # Relocate MOOV atom to start of file if self.relocate_moov: try: import qtfaststart except: log.error("Please install QTFastStart via PIP, relocate_moov will be disabled without this module") self.relocate_moov = False self.acodec = config.get(section, "audio-codec").lower() # Gets the desired audio codec, if no valid codec selected, default to AC3 if self.acodec == '': self.acodec == ['ac3'] else: self.acodec = self.acodec.lower().replace(' ', '').split(',') self.abitrate = config.get(section, "audio-channel-bitrate") try: self.abitrate = int(self.abitrate) except: self.abitrate = 256 log.warning("Audio bitrate was invalid, defaulting to 256 per channel") if self.abitrate > 256: log.warning("Audio bitrate >256 may create errors with common codecs") self.afilter = config.get(section, "audio-filter").lower().strip() # Audio filter if self.afilter == '': self.afilter = None self.iOS = config.get(section, "ios-audio") # Creates a second audio channel if the standard output methods are different from this for iOS compatability if self.iOS == "" or self.iOS.lower() in ['false', 'no', 'f', '0']: self.iOS = False else: if self.iOS.lower() in ['true', 'yes', 't', '1']: self.iOS = ['aac'] else: self.iOS = self.iOS.lower().replace(' ', '').split(',') self.iOSFirst = config.getboolean(section, "ios-first-track-only") # Enables the iOS audio option only for the first track self.iOSfilter = config.get(section, "ios-audio-filter").lower().strip() # iOS audio filter if self.iOSfilter == '': self.iOSfilter = None self.downloadsubs = config.getboolean(section, "download-subs") # Enables downloading of subtitles from the internet sources using subliminal if self.downloadsubs: try: import subliminal except Exception as e: self.downloadsubs = False log.exception("Subliminal is not installed, automatically downloading of subs has been disabled") self.subproviders = config.get(section, 'sub-providers').lower() if self.subproviders == '': self.downloadsubs = False log.warning("You must specifiy at least one subtitle provider to download subs automatically, subtitle downloading disabled") else: self.subproviders = self.subproviders.lower().replace(' ', '').split(',') self.embedsubs = config.getboolean(section, 'embed-subs') self.permissions = config.get(section, 'permissions') try: self.permissions = int(self.permissions, 8) except: self.log.exception("Invalid permissions, defaulting to 777") self.permissions = int("0777", 8) try: self.postprocess = config.getboolean(section, 'post-process') except: self.postprocess = False # Setup variable for maximum audio channels self.maxchannels = config.get(section, 'max-audio-channels') if self.maxchannels == "": self.maxchannels = None else: try: self.maxchannels = int(self.maxchannels) except: log.exception("Invalid number of audio channels specified") self.maxchannels = None if self.maxchannels is not None and self.maxchannels < 1: log.warning("Must have at least 1 audio channel") self.maxchannels = None self.vcodec = config.get(section, "video-codec") if self.vcodec == '': self.vcodec == ['h264', 'x264'] else: self.vcodec = self.vcodec.lower().replace(' ', '').split(',') self.vbitrate = config.get(section, "video-bitrate") if self.vbitrate == '': self.vbitrate = None else: try: self.vbitrate = int(self.vbitrate) if not (self.vbitrate > 0): self.vbitrate = None log.warning("Video bitrate must be greater than 0, defaulting to no video bitrate cap") except: log.exception("Invalid video bitrate, defaulting to no video bitrate cap") self.vbitrate = None try: self.meks_staging = config.getboolean(section, 'meks-staging') self.meks_stageext = config.get(section, "meks-staging-extension") except: self.meks_staging = False self.meks_h264_preset = config.get(section, "meks-h264-preset") if self.meks_h264_preset not in ["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"]: self.meks_h264_preset = "medium" self.meks_metadata = config.get(section, "meks-metadata") self.meks_video_quality = config.get(section, "meks-video-quality") if self.meks_video_quality == '': self.meks_video_quality = 23 else: try: self.meks_video_quality = int(self.meks_video_quality) except: log.exception("Invalid h264 cfr quality, using default quality") self.meks_video_quality = 23 self.meks_walk_noself = config.getboolean(section, 'meks-walk-ignore-self') self.meks_walk_ignore = config.get(section, 'meks-walk-ignore').strip() if self.meks_walk_ignore == '': self.meks_walk_ignore = None else: self.meks_walk_ignore = self.meks_walk_ignore.split(',') self.meks_trans_ignore_n = config.get(section, 'meks-transcode-ignore-names').strip() if self.meks_trans_ignore_n == '': self.meks_trans_ignore_n = None else: self.meks_trans_ignore_n = self.meks_trans_ignore_n.split(',') self.meks_trans_ignore_s = config.get(section, "meks-transcode-ignore-size") if self.meks_trans_ignore_s == '': self.meks_trans_ignore_s = 0 else: try: self.meks_trans_ignore_s = int(self.meks_trans_ignore_s) except: log.exception("Invalid transcode ignore size value, using default (0)") self.meks_trans_ignore_s = 0 self.meks_copysamevcodec = config.getboolean(section, "meks-same-vcodec-copy") self.meks_copysameacodec = config.getboolean(section, "meks-same-acodec-copy") self.meks_adtstoasc = config.getboolean(section, 'meks-aac-adtstoasc') self.meks_nfosearch = config.getboolean(section, "meks-nfosearch") self.meks_tagrename = config.getboolean(section, "meks-tag-rename") self.meks_nfopaths = config.get(section, 'meks-nfopaths').split('|') self.meks_taglangauto = config.get(section, "meks-tag-language-auto") self.meks_tagmandatory = config.get(section, "meks-tag-mandatory") self.meks_qsv_lookahead = config.get(section, "meks-qsv-lookahead") if self.meks_qsv_lookahead == '': self.meks_qsv_lookahead = 0 else: try: self.meks_qsv_lookahead = int(self.meks_qsv_lookahead) except: log.exception("Invalid qsv lookahead value, using default (0)") self.meks_qsv_lookahead = 0 if self.meks_qsv_lookahead > 0: self.meks_video_quality = None self.meks_id3v2vers = config.get(section, "meks-id3v2vers") if self.meks_id3v2vers == '': self.meks_id3v2vers = 3 else: try: self.meks_id3v2vers = float(self.meks_id3v2vers) except: log.exception("Invalid ID3v2 version, defaulting to 3") self.meks_id3v2vers = 3 self.vwidth = config.get(section, "video-max-width") if self.vwidth == '': self.vwidth = None else: try: self.vwidth = int(self.vwidth) except: log.exception("Invalid video width, defaulting to none") self.vwidth = None self.h264_level = config.get(section, "h264-max-level") if self.h264_level == '': self.h264_level = None else: try: self.h264_level = float(self.h264_level) except: log.exception("Invalid h264 level, defaulting to none") self.h264_level = None self.qsv_decoder = config.getboolean(section, "use-qsv-decoder-with-encoder") # Use Intel QuickSync Decoder when using QuickSync Encoder self.pix_fmt = config.get(section, "pix-fmt").strip().lower() if self.pix_fmt == '': self.pix_fmt = None else: self.pix_fmt = self.pix_fmt.replace(' ', '').split(',') self.awl = config.get(section, 'audio-language').strip().lower() # List of acceptable languages for audio streams to be carried over from the original file, separated by a comma. Blank for all if self.awl == '': self.awl = None else: self.awl = self.awl.replace(' ', '').split(',') self.scodec = config.get(section, 'subtitle-codec').strip().lower() if not self.scodec or self.scodec == "": if self.embedsubs: self.scodec = ['mov_text'] else: self.scodec = ['srt'] log.warning("Invalid subtitle codec, defaulting to '%s'" % self.scodec) else: self.scodec = self.scodec.replace(' ', '').split(',') if self.embedsubs: if len(self.scodec) > 1: log.warning("Can only embed one subtitle type, defaulting to 'mov_text'") self.scodec = ['mov_text'] if self.scodec[0] not in valid_internal_subcodecs: log.warning("Invalid interal subtitle codec %s, defaulting to 'mov_text'" % self.scodec[0]) self.scodec = ['mov_text'] else: for codec in self.scodec: if codec not in valid_external_subcodecs: log.warning("Invalid external subtitle codec %s, ignoring" % codec) self.scodec.remove(codec) if len(self.scodec) == 0: log.warning("No valid subtitle formats found, defaulting to 'srt'") self.scodec = ['srt'] self.swl = config.get(section, 'subtitle-language').strip().lower() # List of acceptable languages for subtitle streams to be carried over from the original file, separated by a comma. Blank for all if self.swl == '': self.swl = None else: self.swl = self.swl.replace(' ', '').split(',') self.subencoding = config.get(section, 'subtitle-encoding').strip().lower() if self.subencoding == '': self.subencoding = None self.adl = config.get(section, 'audio-default-language').strip().lower() # What language to default an undefinied audio language tag to. If blank, it will remain undefined. This is useful for single language releases which tend to leave things tagged as und if self.adl == "" or len(self.adl) > 3: self.adl = None self.sdl = config.get(section, 'subtitle-default-language').strip().lower() # What language to default an undefinied subtitle language tag to. If blank, it will remain undefined. This is useful for single language releases which tend to leave things tagged as und if self.sdl == ""or len(self.sdl) > 3: self.sdl = None # Prevent incompatible combination of settings if self.output_dir == "" and self.delete is False: log.error("You must specify an alternate output directory if you aren't going to delete the original file") sys.exit() # Create output directory if it does not exist if self.output_dir is not None: if not os.path.isdir(self.output_dir): os.makedirs(self.output_dir) self.processMP4 = config.getboolean(section, "convert-mp4") # Determine whether or not to reprocess mp4 files or just tag them self.fullpathguess = config.getboolean(section, "fullpathguess") # Guess using the full path or not self.tagfile = config.getboolean(section, "tagfile") # Tag files with metadata self.taglanguage = config.get(section, "tag-language").strip().lower() # Language to tag files if len(self.taglanguage) > 2: try: babel = Language(self.taglanguage) self.taglanguage = babel.alpha2 except: log.exception("Unable to set tag language, defaulting to English") self.taglanguage = 'en' elif len(self.taglanguage) < 2: log.exception("Unable to set tag language, defaulting to English") self.taglanguage = 'en' self.artwork = config.get(section, "download-artwork").lower() # Download and embed artwork if self.artwork == "poster": self.artwork = True self.thumbnail = False elif self.artwork == "thumb" or self.artwork == "thumbnail": self.artwork = True self.thumbnail = True else: self.thumbnail = False try: self.artwork = config.getboolean(section, "download-artwork") except: self.artwork = True self.log.error("Invalid download-artwork value, defaulting to 'poster'") # Read relevant CouchPotato section information section = "CouchPotato" self.CP = {} self.CP['host'] = config.get(section, "host") self.CP['port'] = config.get(section, "port") self.CP['username'] = config.get(section, "username") self.CP['password'] = config.get(section, "password") self.CP['apikey'] = config.get(section, "apikey") self.CP['delay'] = config.get(section, "delay") self.CP['method'] = config.get(section, "method") self.CP['web_root'] = config.get(section, "web_root") try: self.CP['delay'] = float(self.CP['delay']) except ValueError: self.CP['delay'] = 60 try: self.CP['delete_failed'] = config.getboolean(section, "delete_failed") except (configparser.NoOptionError, ValueError): self.CP['delete_failed'] = False try: if config.getboolean(section, 'ssl'): self.CP['protocol'] = "https://" else: self.CP['protocol'] = "http://" except (configparser.NoOptionError, ValueError): self.CP['protocol'] = "http://" # Read relevant uTorrent section information section = "uTorrent" self.uTorrent = {} self.uTorrent['cp'] = config.get(section, "couchpotato-label").lower() self.uTorrent['sb'] = config.get(section, "sickbeard-label").lower() self.uTorrent['sr'] = config.get(section, "sickrage-label").lower() self.uTorrent['sonarr'] = config.get(section, "sonarr-label").lower() self.uTorrent['bypass'] = config.get(section, "bypass-label").lower() try: self.uTorrent['convert'] = config.getboolean(section, "convert") except: self.uTorrent['convert'] = False self.uTorrentWebUI = config.getboolean(section, "webui") self.uTorrentActionBefore = config.get(section, "action_before").lower() self.uTorrentActionAfter = config.get(section, "action_after").lower() self.uTorrentHost = config.get(section, "host").lower() self.uTorrentUsername = config.get(section, "username") self.uTorrentPassword = config.get(section, "password") # Read relevant Deluge section information section = "Deluge" self.deluge = {} self.deluge['cp'] = config.get(section, "couchpotato-label").lower() self.deluge['sb'] = config.get(section, "sickbeard-label").lower() self.deluge['sr'] = config.get(section, "sickrage-label").lower() self.deluge['sonarr'] = config.get(section, "sonarr-label").lower() self.deluge['bypass'] = config.get(section, "bypass-label").lower() try: self.deluge['convert'] = config.getboolean(section, "convert") except: self.deluge['convert'] = False self.deluge['host'] = config.get(section, "host").lower() self.deluge['port'] = config.get(section, "port") self.deluge['user'] = config.get(section, "username") self.deluge['pass'] = config.get(section, "password") # Read relevant Sonarr section information section = "Sonarr" self.Sonarr = {} self.Sonarr['host'] = config.get(section, "host") self.Sonarr['port'] = config.get(section, "port") self.Sonarr['apikey'] = config.get(section, "apikey") self.Sonarr['ssl'] = config.get(section, "ssl") self.Sonarr['web_root'] = config.get(section, "web_root") # Read Sickbeard section information section = "SickBeard" self.Sickbeard = {} self.Sickbeard['host'] = config.get(section, "host") # Server Address self.Sickbeard['port'] = config.get(section, "port") # Server Port self.Sickbeard['api_key'] = config.get(section, "api_key") # Sickbeard API key self.Sickbeard['web_root'] = config.get(section, "web_root") # Sickbeard webroot self.Sickbeard['ssl'] = config.getboolean(section, "ssl") # SSL self.Sickbeard['user'] = config.get(section, "username") self.Sickbeard['pass'] = config.get(section, "password") # Read Sickrage section information section = "Sickrage" self.Sickrage = {} self.Sickrage['host'] = config.get(section, "host") # Server Address self.Sickrage['port'] = config.get(section, "port") # Server Port self.Sickrage['api_key'] = config.get(section, "api_key") # Sickbeard API key self.Sickrage['web_root'] = config.get(section, "web_root") # Sickbeard webroot self.Sickrage['ssl'] = config.getboolean(section, "ssl") # SSL self.Sickrage['user'] = config.get(section, "username") self.Sickrage['pass'] = config.get(section, "password") # Read SAB section information section = "SABNZBD" self.SAB = {} try: self.SAB['convert'] = config.getboolean(section, "convert") # Convert except: self.SAB['convert'] = False self.SAB['cp'] = config.get(section, "Couchpotato-category").lower() self.SAB['sb'] = config.get(section, "Sickbeard-category").lower() self.SAB['sr'] = config.get(section, "Sickrage-category").lower() self.SAB['sonarr'] = config.get(section, "Sonarr-category").lower() self.SAB['bypass'] = config.get(section, "Bypass-category").lower() # Read Plex section information section = "Plex" self.Plex = {} self.Plex['host'] = config.get(section, "host") self.Plex['port'] = config.get(section, "port") try: self.Plex['refresh'] = config.getboolean(section, "refresh") except: self.Plex['refresh'] = False self.Plex['token'] = config.get(section, "token") if self.Plex['token'] == '': self.Plex['token'] = None # Pass the values on self.config = config self.configFile = configFile
def log(): return LoggingAdapter.getLogger(__name__)