diff --git a/autoProcessTV/autoProcessTV.cfg.sample b/autoProcessTV/autoProcessTV.cfg.sample index 15dc900c2d..9d1d99f19a 100644 --- a/autoProcessTV/autoProcessTV.cfg.sample +++ b/autoProcessTV/autoProcessTV.cfg.sample @@ -1,7 +1,24 @@ +# Sick Beard autoProcessTV configuration file +# Used in combination with scripts like sabToSickBeard that call autoProcessTV +# +# Rename (or copy) autoProcessTV.cfg.sample to autoProcessTV.cfg +# Change the host, port, username, and password values +# to the appropriate settings for your Sick Beard server. +# +# Example: Sick Beard can be accessed on http://localhost:8081 +# without username/password +# +# host=localhost # Sick Beard host (localhost or IP address) +# port=8081 # Sick Beard port +# username= # Credentials for logging into Sick Beard +# password= # Credentials for logging into Sick Beard (don't use special characters) +# web_root= # Sick Beard web_root +# ssl=0 # http (ssl=0) (for https use ssl=1) + [SickBeard] host=localhost port=8081 username= password= -web_root= -ssl=0 \ No newline at end of file +web_root=/ +ssl=0 diff --git a/autoProcessTV/autoProcessTV.py b/autoProcessTV/autoProcessTV.py index 77d1f79500..3c940d936b 100644 --- a/autoProcessTV/autoProcessTV.py +++ b/autoProcessTV/autoProcessTV.py @@ -1,104 +1,152 @@ -# 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.path -import ConfigParser - -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): - - config = ConfigParser.ConfigParser() - configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessTV.cfg") - print "Loading config from", configFilename - - if not os.path.isfile(configFilename): - print "ERROR: You need an autoProcessTV.cfg file - did you rename and edit the .sample?" - sys.exit(-1) - - try: - fp = open(configFilename, "r") - config.readfp(fp) - fp.close() - except IOError, e: - print "Could not read configuration file: ", str(e) - sys.exit(1) - - 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 = "" - - params = {} - - params['quiet'] = 1 - - params['dir'] = dirName - if nzbName != None: - params['nzbName'] = nzbName - - myOpener = AuthURLOpener(username, password) - - if ssl: - protocol = "https://" - else: - protocol = "http://" - - url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(params) - - print "Opening URL:", url - - try: - urlObj = myOpener.openit(url) - except IOError, e: - print "Unable to open URL: ", str(e) - sys.exit(1) - - result = urlObj.readlines() - for line in result: - print line - +#!/usr/bin/env python + +# 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 . + +from __future__ import with_statement + +import os.path +import sys + +# Try importing Python 2 modules using new names +try: + import ConfigParser as configparser + import urllib2 + from urllib import urlencode + +# On error import Python 3 modules +except ImportError: + import configparser + import urllib.request as urllib2 + from urllib.parse import urlencode + +# workaround for broken urllib2 in python 2.6.5: wrong credentials lead to an infinite recursion +if sys.version_info >= (2, 6, 5) and sys.version_info < (2, 6, 6): + class HTTPBasicAuthHandler(urllib2.HTTPBasicAuthHandler): + def retry_http_basic_auth(self, host, req, realm): + # don't retry if auth failed + if req.get_header(self.auth_header, None) is not None: + return None + + return urllib2.HTTPBasicAuthHandler.retry_http_basic_auth(self, host, req, realm) + +else: + HTTPBasicAuthHandler = urllib2.HTTPBasicAuthHandler + + +def processEpisode(dir_to_process, org_NZB_name=None): + + # Default values + host = "localhost" + port = "8081" + username = "" + password = "" + ssl = 0 + web_root = "/" + + default_url = host + ":" + port + web_root + if ssl: + default_url = "https://" + default_url + else: + default_url = "http://" + default_url + + # Get values from config_file + config = configparser.RawConfigParser() + config_filename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessTV.cfg") + + if not os.path.isfile(config_filename): + print ("ERROR: " + config_filename + " doesn\'t exist") + print ("copy /rename " + config_filename + ".sample and edit\n") + print ("Trying default url: " + default_url + "\n") + + else: + try: + print ("Loading config from " + config_filename + "\n") + + with open(config_filename, "r") as fp: + config.readfp(fp) + + # Replace default values with config_file values + 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): + pass + + try: + web_root = config.get("SickBeard", "web_root") + if not web_root.startswith("/"): + web_root = "/" + web_root + + if not web_root.endswith("/"): + web_root = web_root + "/" + + except configparser.NoOptionError: + pass + + except EnvironmentError: + e = sys.exc_info()[1] + print ("Could not read configuration file: " + str(e)) + # There was a config_file, don't use default values but exit + sys.exit(1) + + params = {} + + params['quiet'] = 1 + + params['dir'] = dir_to_process + if org_NZB_name != None: + params['nzbName'] = org_NZB_name + + if ssl: + protocol = "https://" + else: + protocol = "http://" + + url = protocol + host + ":" + port + web_root + "home/postprocess/processEpisode?" + urlencode(params) + + print ("Opening URL: " + url) + + try: + password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() + password_mgr.add_password(None, url, username, password) + handler = HTTPBasicAuthHandler(password_mgr) + opener = urllib2.build_opener(handler) + urllib2.install_opener(opener) + + result = opener.open(url).readlines() + + for line in result: + if line: + print (line.strip()) + + except IOError: + e = sys.exc_info()[1] + print ("Unable to open URL: " + str(e)) + sys.exit(1) + + +if __name__ == "__main__": + print ("This module is supposed to be used as import in other scripts and not run standalone.") + print ("Use sabToSickBeard instead.") + sys.exit(1) diff --git a/autoProcessTV/hellaToSickBeard.py b/autoProcessTV/hellaToSickBeard.py index 5b73da7eb3..f2ef00a7a2 100755 --- a/autoProcessTV/hellaToSickBeard.py +++ b/autoProcessTV/hellaToSickBeard.py @@ -21,10 +21,14 @@ import sys -import autoProcessTV +try: + import autoProcessTV +except: + print ("Can't import autoProcessTV.py, make sure it's in the same folder as " + sys.argv[0]) + sys.exit(1) if len(sys.argv) < 4: - print "No folder supplied - is this being called from HellaVCR?" - sys.exit() + print ("No folder supplied - is this being called from HellaVCR?") + sys.exit(1) else: autoProcessTV.processEpisode(sys.argv[3], sys.argv[2]) diff --git a/autoProcessTV/sabToSickBeard.py b/autoProcessTV/sabToSickBeard.py index 8df7b1cc2e..12d36cb079 100755 --- a/autoProcessTV/sabToSickBeard.py +++ b/autoProcessTV/sabToSickBeard.py @@ -14,18 +14,47 @@ # 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 autoProcessTV +try: + import autoProcessTV +except: + print ("Can't import autoProcessTV.py, make sure it's in the same folder as " + sys.argv[0]) + sys.exit(1) + +# SABnzbd user script parameters - see: http://wiki.sabnzbd.org/user-scripts + +# 0 sys.argv[0] is the name of this script + +# 1 The final directory of the job (full path) if len(sys.argv) < 2: - print "No folder supplied - is this being called from SABnzbd?" - sys.exit() -elif len(sys.argv) >= 3: - autoProcessTV.processEpisode(sys.argv[1], sys.argv[2]) + print ("No folder supplied - is this being called from SABnzbd?") + sys.exit(1) else: - autoProcessTV.processEpisode(sys.argv[1]) + download_final_dir = sys.argv[1] + +# 2 The original name of the NZB file +org_NZB_name = sys.argv[2] if len(sys.argv) > 3 else None + +# 3 Clean version of the job name (no path info and ".nzb" removed) +clean_NZB_file = sys.argv[3] if len(sys.argv) > 4 else None + +# 4 Indexer's report number (if supported) +indexer_report = sys.argv[4] if len(sys.argv) > 5 else None + +# 5 User-defined category +sab_user_category = sys.argv[5] if len(sys.argv) > 6 else None + +# 6 Group that the NZB was posted in e.g. alt.binaries.x +group_NZB = sys.argv[6] if len(sys.argv) > 7 else None + +# 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2 +sab_post_processing_status = sys.argv[7] if len(sys.argv) > 8 else None + +# Only final_dir and org_NZB_name are being used to process episodes +autoProcessTV.processEpisode(download_final_dir, org_NZB_name) diff --git a/data/css/lib/jquery-ui-1.10.3.custom.css b/data/css/lib/jquery-ui-1.10.4.custom.css similarity index 88% rename from data/css/lib/jquery-ui-1.10.3.custom.css rename to data/css/lib/jquery-ui-1.10.4.custom.css index 9ecd744f06..55170ddb9d 100644 --- a/data/css/lib/jquery-ui-1.10.3.custom.css +++ b/data/css/lib/jquery-ui-1.10.4.custom.css @@ -1,8 +1,8 @@ -/*! jQuery UI - v1.10.3 - 2013-08-21 +/*! jQuery UI - v1.10.4 - 2014-02-03 * http://jqueryui.com -* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.tabs.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=ffffff&bgTextureHeader=flat&bgImgOpacityHeader=0&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=dcdcdc&bgTextureContent=highlight_soft&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=efefef&bgTextureDefault=highlight_soft&bgImgOpacityDefault=75&borderColorDefault=aaaaaa&fcDefault=222222&iconColorDefault=8c291d&bgColorHover=dddddd&bgTextureHover=highlight_soft&bgImgOpacityHover=75&borderColorHover=999999&fcHover=222222&iconColorHover=222222&bgColorActive=dfdfdf&bgTextureActive=inset_soft&bgImgOpacityActive=75&borderColorActive=aaaaaa&fcActive=140f06&iconColorActive=8c291d&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=aaaaaa&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=aaaaaa&fcError=8c291d&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=35&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=35&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px&ctl=themeroller&zThemeParams=5d000001000106000000000000003d8888d844329a8dfe02723de3e5701fa198449035fc0613ff729a37dd818cf92b1f6938fefa90282d04ae436ba7bfb585bb638a1b642d97ebef778aaeb4159564db1eb76c399d9edf5ecada7b989dd85176284d0f5ba61a62e1029c3923df828563c5ec299b3ad62ddbcffffa3b54d59215498cdf923e75d0d9db1ab69beb6d73c00be43fe56ea5311994de4e505cae88adadbc27b4bdb531517e996cb84d3deadb659ace9ad36a00436066afe333dfc3d5eb0367c49f75c466bdd8841046a7d900563641a2abb39f39e8cd73dcedd911e027b347d8650823223718cf3a30aba29b76d978b32b77e5a5ad9644d88b510c3f0eeca30e3a1cff012a99b3a4931827f7d0e8361eb46c6891c70bea4f4087a62a3bf0c67b740981d972edcde4ca2a056c2ff365dac17893255dae1c46cbe60398c3ffa4a4814830b3851e4b9532eb1cf40248c4057ba9a211e8f716d2713a004fe96a37942697322a2eabf335ad82dc0af5d87c7ced64067270337cad781365cd1781f735be4efba5992db191f97cc0333177f633e0c5d96310904d5bef4d14f934f30823c112d2092bd9e72f35ef450d3031d66ace88026d77699eb5a37eb28b5472571af0cd8de338c2671d02d53a031b3ab981c8be0422edabae4c6673ddbafcfc4e2928 -* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.tabs.css, jquery.ui.theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=%23ffffff&bgTextureHeader=flat&bgImgOpacityHeader=0&borderColorHeader=%23aaaaaa&fcHeader=%23222222&iconColorHeader=%23222222&bgColorContent=%23dcdcdc&bgTextureContent=highlight_soft&bgImgOpacityContent=75&borderColorContent=%23aaaaaa&fcContent=%23222222&iconColorContent=%23222222&bgColorDefault=%23efefef&bgTextureDefault=highlight_soft&bgImgOpacityDefault=75&borderColorDefault=%23aaaaaa&fcDefault=%23222222&iconColorDefault=%238c291d&bgColorHover=%23dddddd&bgTextureHover=highlight_soft&bgImgOpacityHover=75&borderColorHover=%23999999&fcHover=%23222222&iconColorHover=%23222222&bgColorActive=%23dfdfdf&bgTextureActive=inset_soft&bgImgOpacityActive=75&borderColorActive=%23aaaaaa&fcActive=%23140f06&iconColorActive=%238c291d&bgColorHighlight=%23fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%23aaaaaa&fcHighlight=%23363636&iconColorHighlight=%232e83ff&bgColorError=%23fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=%23aaaaaa&fcError=%238c291d&iconColorError=%23cd0a0a&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=35&bgColorShadow=%23000000&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=35&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px&ctl=themeroller +* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ /* Layout helpers ----------------------------------*/ @@ -270,6 +270,7 @@ button.ui-button::-moz-focus-inner { padding: 0; } .ui-dialog { + overflow: hidden; position: absolute; top: 0; left: 0; @@ -292,7 +293,7 @@ button.ui-button::-moz-focus-inner { position: absolute; right: .3em; top: 50%; - width: 21px; + width: 20px; margin: -10px 0 0 0; padding: 1px; height: 20px; @@ -433,7 +434,7 @@ button.ui-button::-moz-focus-inner { padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { +.ui-tabs .ui-tabs-nav .ui-tabs-anchor { float: left; padding: .5em 1em; text-decoration: none; @@ -442,13 +443,12 @@ button.ui-button::-moz-focus-inner { margin-bottom: -1px; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-active a, -.ui-tabs .ui-tabs-nav li.ui-state-disabled a, -.ui-tabs .ui-tabs-nav li.ui-tabs-loading a { +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { cursor: text; } -.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { cursor: pointer; } .ui-tabs .ui-tabs-panel { @@ -522,7 +522,11 @@ button.ui-button::-moz-focus-inner { .ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, -.ui-state-hover a:visited { +.ui-state-hover a:visited, +.ui-state-focus a, +.ui-state-focus a:hover, +.ui-state-focus a:link, +.ui-state-focus a:visited { color: #222222; text-decoration: none; } @@ -530,7 +534,7 @@ button.ui-button::-moz-focus-inner { .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; - /* background: #dfdfdf url(images/ui-bg_inset-soft_75_dfdfdf_1x100.png) 50% 50% repeat-x; */ + background: #dfdfdf url(images/ui-bg_inset-soft_75_dfdfdf_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #140f06; } @@ -840,7 +844,7 @@ button.ui-button::-moz-focus-inner { /* Overlays */ .ui-widget-overlay { - /* background: #6e4f1c url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; */ + /* background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; */ opacity: .35; filter: Alpha(Opacity=35); } @@ -852,4 +856,3 @@ button.ui-button::-moz-focus-inner { filter: Alpha(Opacity=35); border-radius: 8px; } - diff --git a/data/interfaces/default/config_hidden.tmpl b/data/interfaces/default/config_hidden.tmpl index cacef4653c..a65fb4110c 100644 --- a/data/interfaces/default/config_hidden.tmpl +++ b/data/interfaces/default/config_hidden.tmpl @@ -75,17 +75,6 @@ -
- - -
- diff --git a/data/interfaces/default/config_postProcessing.tmpl b/data/interfaces/default/config_postProcessing.tmpl index 6556f948dc..910a35c723 100644 --- a/data/interfaces/default/config_postProcessing.tmpl +++ b/data/interfaces/default/config_postProcessing.tmpl @@ -44,11 +44,7 @@ - @@ -88,7 +84,11 @@ + diff --git a/data/interfaces/default/config_search.tmpl b/data/interfaces/default/config_search.tmpl index 1104a7508f..905efaa4c1 100644 --- a/data/interfaces/default/config_search.tmpl +++ b/data/interfaces/default/config_search.tmpl @@ -57,6 +57,17 @@ +
+ + +
+

@@ -86,7 +97,7 @@ NZB Method: - + +
+ + + +
+