mirror of
https://github.com/moparisthebest/SickRage
synced 2024-11-16 14:25:02 -05:00
Merge branch 'dev' of https://github.com/echel0n/SickRage into pushover-custom_api_key
This commit is contained in:
commit
03c9b303e0
68
SickBeard.py
68
SickBeard.py
@ -18,6 +18,8 @@
|
||||
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Check needed software dependencies to nudge users to fix their setup
|
||||
from __future__ import with_statement
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info < (2, 6):
|
||||
@ -95,35 +97,27 @@ def loadShowsFromDB():
|
||||
|
||||
# TODO: update the existing shows if the showlist has something in it
|
||||
|
||||
|
||||
def daemonize():
|
||||
"""
|
||||
Fork off as a daemon
|
||||
"""
|
||||
|
||||
# pylint: disable=E1101
|
||||
# Make a non-session-leader child process
|
||||
try:
|
||||
pid = os.fork() # @UndefinedVariable - only available in UNIX
|
||||
if pid != 0:
|
||||
os._exit(0)
|
||||
except OSError, e:
|
||||
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
sys.exit(0)
|
||||
except OSError:
|
||||
print "fork() failed"
|
||||
sys.exit(1)
|
||||
|
||||
os.setsid() # unix
|
||||
|
||||
os.chdir(sickbeard.PROG_DIR)
|
||||
os.setsid()
|
||||
# Make sure I can read my own files and shut out others
|
||||
prev = os.umask(0)
|
||||
os.umask(prev and int('077', 8))
|
||||
prev= os.umask(0)
|
||||
os.umask(prev and int('077',8))
|
||||
|
||||
# Make the child a session-leader by detaching from the terminal
|
||||
try:
|
||||
pid = os.fork() # @UndefinedVariable - only available in UNIX
|
||||
if pid != 0:
|
||||
os._exit(0)
|
||||
except OSError, e:
|
||||
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
sys.exit(0)
|
||||
except OSError:
|
||||
print "fork() failed"
|
||||
sys.exit(1)
|
||||
|
||||
# Write pid
|
||||
@ -137,25 +131,14 @@ def daemonize():
|
||||
u"Unable to write PID file: " + sickbeard.PIDFILE + " Error: " + str(e.strerror) + " [" + str(
|
||||
e.errno) + "]")
|
||||
|
||||
# Redirect all output
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
devnull = getattr(os, 'devnull', '/dev/null')
|
||||
stdin = file(devnull, 'r')
|
||||
stdout = file(devnull, 'a+')
|
||||
stderr = file(devnull, 'a+')
|
||||
os.dup2(stdin.fileno(), sys.stdin.fileno())
|
||||
os.dup2(stdout.fileno(), sys.stdout.fileno())
|
||||
os.dup2(stderr.fileno(), sys.stderr.fileno())
|
||||
dev_null = file('/dev/null', 'r')
|
||||
os.dup2(dev_null.fileno(), sys.stdin.fileno())
|
||||
|
||||
def main():
|
||||
"""
|
||||
TV for me
|
||||
"""
|
||||
|
||||
io_loop = IOLoop.current()
|
||||
|
||||
# do some preliminary stuff
|
||||
sickbeard.MY_FULLNAME = os.path.normpath(os.path.abspath(__file__))
|
||||
sickbeard.MY_NAME = os.path.basename(sickbeard.MY_FULLNAME)
|
||||
@ -325,12 +308,6 @@ def main():
|
||||
|
||||
sickbeard.showList = []
|
||||
|
||||
if sickbeard.DAEMON:
|
||||
daemonize()
|
||||
|
||||
# Use this PID for everything
|
||||
sickbeard.PID = os.getpid()
|
||||
|
||||
if forcedPort:
|
||||
logger.log(u"Forcing web server to port " + str(forcedPort))
|
||||
startPort = forcedPort
|
||||
@ -385,6 +362,9 @@ def main():
|
||||
if forceUpdate or sickbeard.UPDATE_SHOWS_ON_START:
|
||||
sickbeard.showUpdateScheduler.action.run(force=True) # @UndefinedVariable
|
||||
|
||||
# get ioloop
|
||||
io_loop = IOLoop.current()
|
||||
|
||||
# init startup tasks
|
||||
io_loop.add_timeout(datetime.timedelta(seconds=5), startup)
|
||||
|
||||
@ -393,6 +373,12 @@ def main():
|
||||
if sickbeard.AUTO_UPDATE:
|
||||
tornado.autoreload.start(io_loop)
|
||||
|
||||
if sickbeard.DAEMON:
|
||||
daemonize()
|
||||
|
||||
# Use this PID for everything
|
||||
sickbeard.PID = os.getpid()
|
||||
|
||||
# start IOLoop.
|
||||
io_loop.start()
|
||||
sickbeard.saveAndShutdown()
|
||||
|
28242
lib/adba/anime-list.xml
28242
lib/adba/anime-list.xml
File diff suppressed because it is too large
Load Diff
49085
lib/adba/animetitles.xml
49085
lib/adba/animetitles.xml
File diff suppressed because it is too large
Load Diff
@ -97,18 +97,8 @@ def change_LOG_DIR(log_dir, web_log):
|
||||
return False
|
||||
|
||||
if sickbeard.WEB_LOG != web_log_value or log_dir_changed == True:
|
||||
|
||||
sickbeard.WEB_LOG = web_log_value
|
||||
|
||||
if sickbeard.WEB_LOG:
|
||||
cherry_log = os.path.join(sickbeard.LOG_DIR, "cherrypy.log")
|
||||
logger.log(u"Change cherry log file to " + cherry_log)
|
||||
else:
|
||||
cherry_log = None
|
||||
logger.log(u"Disable cherry logging")
|
||||
|
||||
#cherrypy.config.update({'log.access_file': cherry_log})
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -76,11 +76,13 @@ class SBRotatingLogHandler(object):
|
||||
sub_logger = logging.getLogger('subliminal')
|
||||
imdb_logger = logging.getLogger('imdbpy')
|
||||
tornado_logger = logging.getLogger('tornado')
|
||||
feedcache_logger = logging.getLogger('feedcache')
|
||||
|
||||
sb_logger.removeHandler(handler)
|
||||
sub_logger.removeHandler(handler)
|
||||
imdb_logger.removeHandler(handler)
|
||||
tornado_logger.removeHandler(handler)
|
||||
feedcache_logger.removeHandler(handler)
|
||||
|
||||
handler.flush()
|
||||
handler.close()
|
||||
@ -116,7 +118,9 @@ class SBRotatingLogHandler(object):
|
||||
'%H:%M:%S'),
|
||||
'imdbpy': logging.Formatter('%(asctime)s %(levelname)s::IMDBPY :: %(message)s', '%H:%M:%S'),
|
||||
'tornado.general': logging.Formatter('%(asctime)s %(levelname)s::TORNADO :: %(message)s', '%H:%M:%S'),
|
||||
'tornado.application': logging.Formatter('%(asctime)s %(levelname)s::TORNADO :: %(message)s', '%H:%M:%S')
|
||||
'tornado.application': logging.Formatter('%(asctime)s %(levelname)s::TORNADO :: %(message)s', '%H:%M:%S'),
|
||||
'feedcache.cache': logging.Formatter('%(asctime)s %(levelname)s::FEEDCACHE :: %(message)s',
|
||||
'%H:%M:%S')
|
||||
},
|
||||
logging.Formatter('%(message)s'), ))
|
||||
|
||||
@ -126,15 +130,18 @@ class SBRotatingLogHandler(object):
|
||||
logging.getLogger('tornado.application').addHandler(console)
|
||||
logging.getLogger('subliminal').addHandler(console)
|
||||
logging.getLogger('imdbpy').addHandler(console)
|
||||
logging.getLogger('feedcache').addHandler(console)
|
||||
|
||||
self.log_file_path = os.path.join(sickbeard.LOG_DIR, self.log_file)
|
||||
|
||||
self.cur_handler = self._config_handler()
|
||||
logging.getLogger('sickbeard').addHandler(self.cur_handler)
|
||||
logging.getLogger('tornado.access').addHandler(NullHandler())
|
||||
logging.getLogger('tornado.general').addHandler(self.cur_handler)
|
||||
logging.getLogger('tornado.application').addHandler(self.cur_handler)
|
||||
logging.getLogger('subliminal').addHandler(self.cur_handler)
|
||||
logging.getLogger('imdbpy').addHandler(self.cur_handler)
|
||||
logging.getLogger('feedcache').addHandler(self.cur_handler)
|
||||
|
||||
logging.getLogger('sickbeard').setLevel(DB)
|
||||
|
||||
@ -146,8 +153,8 @@ class SBRotatingLogHandler(object):
|
||||
logging.getLogger('tornado.application').setLevel(log_level)
|
||||
logging.getLogger('subliminal').setLevel(log_level)
|
||||
logging.getLogger('imdbpy').setLevel(log_level)
|
||||
logging.getLogger('feedcache').setLevel(log_level)
|
||||
|
||||
logging.getLogger('tornado.access').addHandler(NullHandler())
|
||||
|
||||
# already logging in new log folder, close the old handler
|
||||
if old_handler:
|
||||
@ -174,7 +181,9 @@ class SBRotatingLogHandler(object):
|
||||
'%Y-%m-%d %H:%M:%S'),
|
||||
'imdbpy': logging.Formatter('%(asctime)s %(levelname)-8s IMDBPY :: %(message)s', '%Y-%m-%d %H:%M:%S'),
|
||||
'tornado.general': logging.Formatter('%(asctime)s %(levelname)-8s TORNADO :: %(message)s', '%Y-%m-%d %H:%M:%S'),
|
||||
'tornado.application': logging.Formatter('%(asctime)s %(levelname)-8s TORNADO :: %(message)s', '%Y-%m-%d %H:%M:%S')
|
||||
'tornado.application': logging.Formatter('%(asctime)s %(levelname)-8s TORNADO :: %(message)s', '%Y-%m-%d %H:%M:%S'),
|
||||
'feedcache.cache': logging.Formatter('%(asctime)s %(levelname)-8s FEEDCACHE :: %(message)s',
|
||||
'%Y-%m-%d %H:%M:%S')
|
||||
},
|
||||
logging.Formatter('%(message)s'), ))
|
||||
|
||||
@ -208,6 +217,7 @@ class SBRotatingLogHandler(object):
|
||||
sub_logger = logging.getLogger('subliminal')
|
||||
imdb_logger = logging.getLogger('imdbpy')
|
||||
tornado_logger = logging.getLogger('tornado')
|
||||
feedcache_logger = logging.getLogger('feedcache')
|
||||
|
||||
# delete the old handler
|
||||
if self.cur_handler:
|
||||
@ -233,6 +243,7 @@ class SBRotatingLogHandler(object):
|
||||
sub_logger.addHandler(new_file_handler)
|
||||
imdb_logger.addHandler(new_file_handler)
|
||||
tornado_logger.addHandler(new_file_handler)
|
||||
feedcache_logger.addHandler(new_file_handler)
|
||||
|
||||
def log(self, toLog, logLevel=MESSAGE):
|
||||
|
||||
@ -257,6 +268,7 @@ class SBRotatingLogHandler(object):
|
||||
sub_logger = logging.getLogger('subliminal')
|
||||
imdb_logger = logging.getLogger('imdbpy')
|
||||
tornado_logger = logging.getLogger('tornado')
|
||||
feedcache_logger = logging.getLogger('feedcache')
|
||||
|
||||
try:
|
||||
if logLevel == DEBUG:
|
||||
|
@ -160,7 +160,6 @@ class Api(webserve.IndexHandler):
|
||||
return webserve._munge(t)
|
||||
|
||||
def _out_as_json(self, dict):
|
||||
""" set cherrypy response to json """
|
||||
self.set_header("Content-Type", "application/json")
|
||||
try:
|
||||
out = json.dumps(dict, indent=self.intent, sort_keys=True)
|
||||
@ -297,10 +296,11 @@ def filter_params(cmd, args, kwargs):
|
||||
return curArgs, curKwargs
|
||||
|
||||
|
||||
class ApiCall(Api):
|
||||
class ApiCall(webserve.IndexHandler):
|
||||
_help = {"desc": "No help message available. Please tell the devs that a help msg is missing for this cmd"}
|
||||
|
||||
def __init__(self, args, kwargs):
|
||||
|
||||
# missing
|
||||
try:
|
||||
if self._missing:
|
||||
@ -2104,7 +2104,7 @@ class CMD_ShowGetPoster(ApiCall):
|
||||
|
||||
def run(self):
|
||||
""" get the poster for a show in sickbeard """
|
||||
return {'outputType': 'image', 'image': webserve.IndexHandler.showPoster(self.indexerid, 'poster')}
|
||||
return {'outputType': 'image', 'image': self.showPoster(self.indexerid, 'poster')}
|
||||
|
||||
|
||||
class CMD_ShowGetBanner(ApiCall):
|
||||
@ -2122,7 +2122,7 @@ class CMD_ShowGetBanner(ApiCall):
|
||||
|
||||
def run(self):
|
||||
""" get the banner for a show in sickbeard """
|
||||
return {'outputType': 'image', 'image': webserve.IndexHandler.showPoster(self.indexerid, 'banner')}
|
||||
return {'outputType': 'image', 'image': self.showPoster(self.indexerid, 'banner')}
|
||||
|
||||
|
||||
class CMD_ShowPause(ApiCall):
|
||||
|
@ -80,26 +80,16 @@ except ImportError:
|
||||
from lib import adba
|
||||
|
||||
from Cheetah.Template import Template
|
||||
from tornado import gen, autoreload
|
||||
from tornado import gen
|
||||
from tornado.web import RequestHandler, HTTPError, asynchronous
|
||||
from tornado.ioloop import IOLoop
|
||||
|
||||
# def _handle_reverse_proxy():
|
||||
# if sickbeard.HANDLE_REVERSE_PROXY:
|
||||
# cherrypy.lib.cptools.proxy()
|
||||
|
||||
|
||||
# cherrypy.tools.handle_reverse_proxy = cherrypy.Tool('before_handler', _handle_reverse_proxy)
|
||||
|
||||
req_headers = None
|
||||
|
||||
|
||||
def authenticated(handler_class):
|
||||
def wrap_execute(handler_execute):
|
||||
def basicauth(handler, transforms, *args, **kwargs):
|
||||
def _request_basic_auth(handler):
|
||||
handler.set_status(401)
|
||||
handler.set_header('WWW-Authenticate', 'Basic realm=Restricted')
|
||||
handler.set_header('WWW-Authenticate', 'Basic realm="SickRage"')
|
||||
handler._transforms = []
|
||||
handler.finish()
|
||||
return False
|
||||
@ -107,6 +97,9 @@ def authenticated(handler_class):
|
||||
try:
|
||||
if not (sickbeard.WEB_USERNAME and sickbeard.WEB_PASSWORD):
|
||||
return True
|
||||
elif handler.request.uri.startswith('/calendar') or (
|
||||
handler.request.uri.startswith('/api') and '/api/builder' not in handler.request.uri):
|
||||
return True
|
||||
|
||||
auth_hdr = handler.request.headers.get('Authorization')
|
||||
|
||||
@ -135,13 +128,8 @@ def authenticated(handler_class):
|
||||
return handler_class
|
||||
|
||||
|
||||
class RedirectHandler(RequestHandler):
|
||||
def get(self, path, **kwargs):
|
||||
self.redirect(path, permanent=True)
|
||||
|
||||
|
||||
@authenticated
|
||||
class IndexHandler(RedirectHandler):
|
||||
class IndexHandler(RequestHandler):
|
||||
def __init__(self, application, request, **kwargs):
|
||||
super(IndexHandler, self).__init__(application, request, **kwargs)
|
||||
global req_headers
|
||||
@ -149,22 +137,35 @@ class IndexHandler(RedirectHandler):
|
||||
sickbeard.REMOTE_IP = self.request.remote_ip
|
||||
req_headers = self.request.headers
|
||||
|
||||
def delist_arguments(self, args):
|
||||
"""
|
||||
Takes a dictionary, 'args' and de-lists any single-item lists then
|
||||
returns the resulting dictionary.
|
||||
def http_error_401_handler(self):
|
||||
""" Custom handler for 401 error """
|
||||
return r'''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>%s</title>
|
||||
</head>
|
||||
<body>
|
||||
<br/>
|
||||
<font color="#0000FF">Error %s: You need to provide a valid username and password.</font>
|
||||
</body>
|
||||
</html>
|
||||
''' % ('Access denied', 401)
|
||||
|
||||
In other words, {'foo': ['bar']} would become {'foo': 'bar'}
|
||||
"""
|
||||
for arg, value in args.items():
|
||||
if len(value) == 1:
|
||||
args[arg] = value[0]
|
||||
return args
|
||||
def http_error_404_handler(self):
|
||||
""" Custom handler for 404 error, redirect back to main page """
|
||||
self.redirect('/home/')
|
||||
|
||||
def write_error(self, status_code, **kwargs):
|
||||
if status_code == 404:
|
||||
self.redirect('/home/')
|
||||
elif status_code == 401:
|
||||
self.finish(self.http_error_401_handler())
|
||||
else:
|
||||
super(IndexHandler, self).write_error(status_code, **kwargs)
|
||||
|
||||
def _dispatch(self):
|
||||
|
||||
args = None
|
||||
path = self.request.uri.split('?')[0]
|
||||
path = self.request.uri.replace(sickbeard.WEB_ROOT, '').split('?')[0]
|
||||
|
||||
method = path.strip('/').split('/')[-1]
|
||||
if path.startswith('/api'):
|
||||
@ -185,8 +186,10 @@ class IndexHandler(RedirectHandler):
|
||||
|
||||
if klass and not method.startswith('_'):
|
||||
# Sanitize argument lists:
|
||||
if self.request.arguments:
|
||||
args = self.delist_arguments(self.request.arguments)
|
||||
args = self.request.arguments
|
||||
for arg, value in args.items():
|
||||
if len(value) == 1:
|
||||
args[arg] = value[0]
|
||||
|
||||
# Regular method handler for classes
|
||||
func = getattr(klass, method, None)
|
||||
@ -199,30 +202,29 @@ class IndexHandler(RedirectHandler):
|
||||
func = getattr(klass, 'index', None)
|
||||
|
||||
if func:
|
||||
if args:
|
||||
return func(**args)
|
||||
else:
|
||||
return func()
|
||||
|
||||
raise HTTPError(404)
|
||||
|
||||
@asynchronous
|
||||
def get(self, *args, **kwargs):
|
||||
try:
|
||||
resp = self._dispatch()
|
||||
if resp:
|
||||
self.finish(resp)
|
||||
except Exception as e:
|
||||
logger.log(ex(e), logger.ERROR)
|
||||
logger.log(u"Traceback: " + traceback.format_exc(), logger.DEBUG)
|
||||
def redirect(self, url, permanent=False, status=None):
|
||||
self._transforms = []
|
||||
super(IndexHandler, self).redirect(sickbeard.WEB_ROOT + url, permanent, status)
|
||||
|
||||
@asynchronous
|
||||
@gen.engine
|
||||
def get(self, *args, **kwargs):
|
||||
response = yield gen.Task(self.getresponse, self._dispatch)
|
||||
self.finish(response)
|
||||
|
||||
@asynchronous
|
||||
@gen.engine
|
||||
def post(self, *args, **kwargs):
|
||||
try:
|
||||
self.finish(self._dispatch())
|
||||
except Exception as e:
|
||||
logger.log(ex(e), logger.ERROR)
|
||||
logger.log(u"Traceback: " + traceback.format_exc(), logger.DEBUG)
|
||||
response = yield gen.Task(self.getresponse, self._dispatch)
|
||||
self.finish(response)
|
||||
|
||||
def getresponse(self, func, callback):
|
||||
response = func()
|
||||
callback(response)
|
||||
|
||||
def robots_txt(self, *args, **kwargs):
|
||||
""" Keep web crawlers out """
|
||||
@ -264,7 +266,7 @@ class IndexHandler(RedirectHandler):
|
||||
|
||||
sickbeard.HOME_LAYOUT = layout
|
||||
|
||||
self.redirect("/home/")
|
||||
return self.redirect("/home/")
|
||||
|
||||
def setHistoryLayout(self, layout):
|
||||
|
||||
@ -273,13 +275,13 @@ class IndexHandler(RedirectHandler):
|
||||
|
||||
sickbeard.HISTORY_LAYOUT = layout
|
||||
|
||||
self.redirect("/history/")
|
||||
return self.redirect("/history/")
|
||||
|
||||
def toggleDisplayShowSpecials(self, show):
|
||||
|
||||
sickbeard.DISPLAY_SHOW_SPECIALS = not sickbeard.DISPLAY_SHOW_SPECIALS
|
||||
|
||||
self.redirect("/home/displayShow?show=" + show)
|
||||
return self.redirect("/home/displayShow?show=" + show)
|
||||
|
||||
def setComingEpsLayout(self, layout):
|
||||
if layout not in ('poster', 'banner', 'list'):
|
||||
@ -287,13 +289,13 @@ class IndexHandler(RedirectHandler):
|
||||
|
||||
sickbeard.COMING_EPS_LAYOUT = layout
|
||||
|
||||
self.redirect("/comingEpisodes/")
|
||||
return self.redirect("/comingEpisodes/")
|
||||
|
||||
def toggleComingEpsDisplayPaused(self, *args, **kwargs):
|
||||
|
||||
sickbeard.COMING_EPS_DISPLAY_PAUSED = not sickbeard.COMING_EPS_DISPLAY_PAUSED
|
||||
|
||||
self.redirect("/comingEpisodes/")
|
||||
return self.redirect("/comingEpisodes/")
|
||||
|
||||
def setComingEpsSort(self, sort):
|
||||
if sort not in ('date', 'network', 'show'):
|
||||
@ -301,7 +303,7 @@ class IndexHandler(RedirectHandler):
|
||||
|
||||
sickbeard.COMING_EPS_SORT = sort
|
||||
|
||||
self.redirect("/comingEpisodes/")
|
||||
return self.redirect("/comingEpisodes/")
|
||||
|
||||
def comingEpisodes(self, layout="None"):
|
||||
|
||||
@ -454,7 +456,6 @@ class IndexHandler(RedirectHandler):
|
||||
|
||||
browser = WebFileBrowser
|
||||
|
||||
|
||||
class PageTemplate(Template):
|
||||
def __init__(self, *args, **KWs):
|
||||
KWs['file'] = os.path.join(sickbeard.PROG_DIR, "gui/" + sickbeard.GUI_NAME + "/interfaces/default/",
|
||||
@ -506,7 +507,7 @@ class IndexerWebUI(IndexHandler):
|
||||
showDirList = ""
|
||||
for curShowDir in self.config['_showDir']:
|
||||
showDirList += "showDir=" + curShowDir + "&"
|
||||
self.redirect("/home/addShows/addShow?" + showDirList + "seriesList=" + searchList)
|
||||
return self.redirect("/home/addShows/addShow?" + showDirList + "seriesList=" + searchList)
|
||||
|
||||
|
||||
def _munge(string):
|
||||
@ -585,7 +586,7 @@ class ManageSearches(IndexHandler):
|
||||
logger.log(u"Backlog search forced")
|
||||
ui.notifications.message('Backlog search started')
|
||||
|
||||
self.redirect("/manage/manageSearches/")
|
||||
return self.redirect("/manage/manageSearches/")
|
||||
|
||||
|
||||
def forceSearch(self, *args, **kwargs):
|
||||
@ -596,7 +597,7 @@ class ManageSearches(IndexHandler):
|
||||
logger.log(u"Daily search forced")
|
||||
ui.notifications.message('Daily search started')
|
||||
|
||||
self.redirect("/manage/manageSearches/")
|
||||
return self.redirect("/manage/manageSearches/")
|
||||
|
||||
|
||||
def forceFindPropers(self, *args, **kwargs):
|
||||
@ -607,7 +608,7 @@ class ManageSearches(IndexHandler):
|
||||
logger.log(u"Find propers search forced")
|
||||
ui.notifications.message('Find propers search started')
|
||||
|
||||
self.redirect("/manage/manageSearches/")
|
||||
return self.redirect("/manage/manageSearches/")
|
||||
|
||||
|
||||
def pauseBacklog(self, paused=None):
|
||||
@ -616,7 +617,7 @@ class ManageSearches(IndexHandler):
|
||||
else:
|
||||
sickbeard.searchQueueScheduler.action.unpause_backlog() # @UndefinedVariable
|
||||
|
||||
self.redirect("/manage/manageSearches/")
|
||||
return self.redirect("/manage/manageSearches/")
|
||||
|
||||
|
||||
class Manage(IndexHandler):
|
||||
@ -729,7 +730,7 @@ class Manage(IndexHandler):
|
||||
|
||||
Home.setStatus(cur_indexer_id, '|'.join(to_change[cur_indexer_id]), newStatus, direct=True)
|
||||
|
||||
self.redirect('/manage/episodeStatuses/')
|
||||
return self.redirect('/manage/episodeStatuses/')
|
||||
|
||||
|
||||
def showSubtitleMissed(self, indexer_id, whichSubs):
|
||||
@ -837,7 +838,7 @@ class Manage(IndexHandler):
|
||||
show = sickbeard.helpers.findCertainShow(sickbeard.showList, int(cur_indexer_id))
|
||||
subtitles = show.getEpisode(int(season), int(episode)).downloadSubtitles()
|
||||
|
||||
self.redirect('/manage/subtitleMissed/')
|
||||
return self.redirect('/manage/subtitleMissed/')
|
||||
|
||||
|
||||
def backlogShow(self, indexer_id):
|
||||
@ -847,7 +848,7 @@ class Manage(IndexHandler):
|
||||
if show_obj:
|
||||
sickbeard.backlogSearchScheduler.action.searchBacklog([show_obj]) # @UndefinedVariable
|
||||
|
||||
self.redirect("/manage/backlogOverview/")
|
||||
return self.redirect("/manage/backlogOverview/")
|
||||
|
||||
|
||||
def backlogOverview(self, *args, **kwargs):
|
||||
@ -897,7 +898,7 @@ class Manage(IndexHandler):
|
||||
t.submenu = ManageMenu()
|
||||
|
||||
if not toEdit:
|
||||
self.redirect("/manage/")
|
||||
return self.redirect("/manage/")
|
||||
|
||||
showIDs = toEdit.split("|")
|
||||
showList = []
|
||||
@ -1062,7 +1063,7 @@ class Manage(IndexHandler):
|
||||
ui.notifications.error('%d error%s while saving changes:' % (len(errors), "" if len(errors) == 1 else "s"),
|
||||
" ".join(errors))
|
||||
|
||||
self.redirect("/manage/")
|
||||
return self.redirect("/manage/")
|
||||
|
||||
|
||||
def massUpdate(self, toUpdate=None, toRefresh=None, toRename=None, toDelete=None, toMetadata=None, toSubtitle=None):
|
||||
@ -1171,7 +1172,7 @@ class Manage(IndexHandler):
|
||||
ui.notifications.message("The following actions were queued:",
|
||||
messageDetail)
|
||||
|
||||
self.redirect("/manage/")
|
||||
return self.redirect("/manage/")
|
||||
|
||||
|
||||
def manageTorrents(self, *args, **kwargs):
|
||||
@ -1303,7 +1304,7 @@ class History(IndexHandler):
|
||||
myDB.action("DELETE FROM history WHERE 1=1")
|
||||
|
||||
ui.notifications.message('History cleared')
|
||||
self.redirect("/history/")
|
||||
return self.redirect("/history/")
|
||||
|
||||
|
||||
def trimHistory(self, *args, **kwargs):
|
||||
@ -1313,7 +1314,7 @@ class History(IndexHandler):
|
||||
(datetime.datetime.today() - datetime.timedelta(days=30)).strftime(history.dateFormat)))
|
||||
|
||||
ui.notifications.message('Removed history entries greater than 30 days old')
|
||||
self.redirect("/history/")
|
||||
return self.redirect("/history/")
|
||||
|
||||
|
||||
ConfigMenu = [
|
||||
@ -2461,7 +2462,7 @@ class HomePostProcess(IndexHandler):
|
||||
if sickbeard.versionCheckScheduler.action.check_for_new_version(force=True):
|
||||
logger.log(u"Forcing version check")
|
||||
|
||||
self.redirect("/home/")
|
||||
return self.redirect("/home/")
|
||||
|
||||
def processEpisode(self, dir=None, nzbName=None, jobName=None, quiet=None, process_method=None, force=None,
|
||||
is_priority=None, failed="0", type="auto"):
|
||||
@ -2482,7 +2483,7 @@ class HomePostProcess(IndexHandler):
|
||||
is_priority = False
|
||||
|
||||
if not dir:
|
||||
self.redirect("/home/postprocess/")
|
||||
return self.redirect("/home/postprocess/")
|
||||
else:
|
||||
result = processTV.processDir(dir, nzbName, process_method=process_method, force=force,
|
||||
is_priority=is_priority, failed=failed, type=type)
|
||||
@ -2703,7 +2704,7 @@ class NewHomeAddShows(IndexHandler):
|
||||
def finishAddShow():
|
||||
# if there are no extra shows then go home
|
||||
if not other_shows:
|
||||
self.redirect('/home/')
|
||||
return self.redirect('/home/')
|
||||
|
||||
# peel off the next one
|
||||
next_show_dir = other_shows[0]
|
||||
@ -2728,7 +2729,7 @@ class NewHomeAddShows(IndexHandler):
|
||||
logger.log("Unable to add show due to show selection. Not anough arguments: %s" % (repr(series_pieces)),
|
||||
logger.ERROR)
|
||||
ui.notifications.error("Unknown error. Unable to add show due to problem with show selection.")
|
||||
self.redirect('/home/addShows/existingShows/')
|
||||
return self.redirect('/home/addShows/existingShows/')
|
||||
indexer = int(series_pieces[1])
|
||||
indexer_id = int(series_pieces[3])
|
||||
show_name = series_pieces[4]
|
||||
@ -2750,7 +2751,7 @@ class NewHomeAddShows(IndexHandler):
|
||||
# blanket policy - if the dir exists you should have used "add existing show" numbnuts
|
||||
if ek.ek(os.path.isdir, show_dir) and not fullShowPath:
|
||||
ui.notifications.error("Unable to add show", "Folder " + show_dir + " exists already")
|
||||
self.redirect('/home/addShows/existingShows/')
|
||||
return self.redirect('/home/addShows/existingShows/')
|
||||
|
||||
# don't create show dir if config says not to
|
||||
if sickbeard.ADD_SHOWS_WO_DIR:
|
||||
@ -2761,7 +2762,7 @@ class NewHomeAddShows(IndexHandler):
|
||||
logger.log(u"Unable to create the folder " + show_dir + ", can't add the show", logger.ERROR)
|
||||
ui.notifications.error("Unable to add show",
|
||||
"Unable to create the folder " + show_dir + ", can't add the show")
|
||||
self.redirect("/home/")
|
||||
return self.redirect("/home/")
|
||||
else:
|
||||
helpers.chmodAsParent(show_dir)
|
||||
|
||||
@ -2866,7 +2867,7 @@ class NewHomeAddShows(IndexHandler):
|
||||
|
||||
# if we're done then go home
|
||||
if not dirs_only:
|
||||
self.redirect('/home/')
|
||||
return self.redirect('/home/')
|
||||
|
||||
# for the remaining shows we need to prompt for each one, so forward this on to the newShow page
|
||||
return self.newShow(dirs_only[0], dirs_only[1:])
|
||||
@ -2889,7 +2890,7 @@ class ErrorLogs(IndexHandler):
|
||||
|
||||
def clearerrors(self, *args, **kwargs):
|
||||
classes.ErrorViewer.clear()
|
||||
self.redirect("/errorlogs/")
|
||||
return self.redirect("/errorlogs/")
|
||||
|
||||
|
||||
def viewlog(self, minLevel=logger.MESSAGE, maxLines=500):
|
||||
@ -3260,7 +3261,7 @@ class Home(IndexHandler):
|
||||
def shutdown(self, pid=None):
|
||||
|
||||
if str(pid) != str(sickbeard.PID):
|
||||
self.redirect("/home/")
|
||||
return self.redirect("/home/")
|
||||
|
||||
threading.Timer(2, sickbeard.invoke_shutdown).start()
|
||||
|
||||
@ -3272,7 +3273,7 @@ class Home(IndexHandler):
|
||||
def restart(self, pid=None):
|
||||
|
||||
if str(pid) != str(sickbeard.PID):
|
||||
self.redirect("/home/")
|
||||
return self.redirect("/home/")
|
||||
|
||||
t = PageTemplate(file="restart.tmpl")
|
||||
t.submenu = HomeMenu()
|
||||
@ -3286,16 +3287,14 @@ class Home(IndexHandler):
|
||||
def update(self, pid=None):
|
||||
|
||||
if str(pid) != str(sickbeard.PID):
|
||||
self.redirect("/home/")
|
||||
|
||||
# auto-reload
|
||||
tornado.autoreload.start(IOLoop.current())
|
||||
return self.redirect("/home/")
|
||||
|
||||
updated = sickbeard.versionCheckScheduler.action.update() # @UndefinedVariable
|
||||
|
||||
if updated:
|
||||
# do a hard restart
|
||||
#threading.Timer(2, sickbeard.invoke_restart, [False]).start()
|
||||
if not sickbeard.AUTO_UPDATE:
|
||||
threading.Timer(2, sickbeard.invoke_restart, [False]).start()
|
||||
|
||||
t = PageTemplate(file="restart_bare.tmpl")
|
||||
return _munge(t)
|
||||
else:
|
||||
@ -3709,7 +3708,7 @@ class Home(IndexHandler):
|
||||
ui.notifications.error('%d error%s while saving changes:' % (len(errors), "" if len(errors) == 1 else "s"),
|
||||
'<ul>' + '\n'.join(['<li>%s</li>' % error for error in errors]) + "</ul>")
|
||||
|
||||
self.redirect("/home/displayShow?show=" + show)
|
||||
return self.redirect("/home/displayShow?show=" + show)
|
||||
|
||||
|
||||
def deleteShow(self, show=None):
|
||||
@ -3729,7 +3728,7 @@ class Home(IndexHandler):
|
||||
showObj.deleteShow()
|
||||
|
||||
ui.notifications.message('<b>%s</b> has been deleted' % showObj.name)
|
||||
self.redirect("/home/")
|
||||
return self.redirect("/home/")
|
||||
|
||||
|
||||
def refreshShow(self, show=None):
|
||||
@ -3751,7 +3750,7 @@ class Home(IndexHandler):
|
||||
|
||||
time.sleep(cpu_presets[sickbeard.CPU_PRESET])
|
||||
|
||||
self.redirect("/home/displayShow?show=" + str(showObj.indexerid))
|
||||
return self.redirect("/home/displayShow?show=" + str(showObj.indexerid))
|
||||
|
||||
|
||||
def updateShow(self, show=None, force=0):
|
||||
@ -3774,7 +3773,7 @@ class Home(IndexHandler):
|
||||
# just give it some time
|
||||
time.sleep(cpu_presets[sickbeard.CPU_PRESET])
|
||||
|
||||
self.redirect("/home/displayShow?show=" + str(showObj.indexerid))
|
||||
return self.redirect("/home/displayShow?show=" + str(showObj.indexerid))
|
||||
|
||||
|
||||
def subtitleShow(self, show=None, force=0):
|
||||
@ -3792,7 +3791,7 @@ class Home(IndexHandler):
|
||||
|
||||
time.sleep(cpu_presets[sickbeard.CPU_PRESET])
|
||||
|
||||
self.redirect("/home/displayShow?show=" + str(showObj.indexerid))
|
||||
return self.redirect("/home/displayShow?show=" + str(showObj.indexerid))
|
||||
|
||||
|
||||
def updateXBMC(self, showName=None):
|
||||
@ -3808,7 +3807,7 @@ class Home(IndexHandler):
|
||||
ui.notifications.message("Library update command sent to XBMC host(s): " + host)
|
||||
else:
|
||||
ui.notifications.error("Unable to contact one or more XBMC host(s): " + host)
|
||||
self.redirect('/home/')
|
||||
return self.redirect('/home/')
|
||||
|
||||
|
||||
def updatePLEX(self, *args, **kwargs):
|
||||
@ -3817,7 +3816,7 @@ class Home(IndexHandler):
|
||||
"Library update command sent to Plex Media Server host: " + sickbeard.PLEX_SERVER_HOST)
|
||||
else:
|
||||
ui.notifications.error("Unable to contact Plex Media Server host: " + sickbeard.PLEX_SERVER_HOST)
|
||||
self.redirect('/home/')
|
||||
return self.redirect('/home/')
|
||||
|
||||
|
||||
def setStatus(self, show=None, eps=None, status=None, direct=False):
|
||||
@ -3931,7 +3930,7 @@ class Home(IndexHandler):
|
||||
if direct:
|
||||
return json.dumps({'result': 'success'})
|
||||
else:
|
||||
self.redirect("/home/displayShow?show=" + show)
|
||||
return self.redirect("/home/displayShow?show=" + show)
|
||||
|
||||
|
||||
def testRename(self, show=None):
|
||||
@ -3998,7 +3997,7 @@ class Home(IndexHandler):
|
||||
return _genericMessage("Error", "Can't rename episodes when the show dir is missing.")
|
||||
|
||||
if eps is None:
|
||||
self.redirect("/home/displayShow?show=" + show)
|
||||
return self.redirect("/home/displayShow?show=" + show)
|
||||
|
||||
with db.DBConnection() as myDB:
|
||||
for curEp in eps.split('|'):
|
||||
@ -4025,7 +4024,7 @@ class Home(IndexHandler):
|
||||
|
||||
root_ep_obj.rename()
|
||||
|
||||
self.redirect("/home/displayShow?show=" + show)
|
||||
return self.redirect("/home/displayShow?show=" + show)
|
||||
|
||||
|
||||
def searchEpisode(self, show=None, season=None, episode=None):
|
||||
|
@ -16,6 +16,7 @@ server = None
|
||||
class MultiStaticFileHandler(StaticFileHandler):
|
||||
def initialize(self, paths, default_filename=None):
|
||||
self.paths = paths
|
||||
self.default_filename = default_filename
|
||||
|
||||
def get(self, path, include_body=True):
|
||||
for p in self.paths:
|
||||
@ -44,41 +45,6 @@ def initWebServer(options={}):
|
||||
assert isinstance(options['port'], int)
|
||||
assert 'data_root' in options
|
||||
|
||||
def http_error_401_hander(status, message, traceback, version):
|
||||
""" Custom handler for 401 error """
|
||||
if status != "401 Unauthorized":
|
||||
logger.log(u"Tornado caught an error: %s %s" % (status, message), logger.ERROR)
|
||||
logger.log(traceback, logger.DEBUG)
|
||||
return r'''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>%s</title>
|
||||
</head>
|
||||
<body>
|
||||
<br/>
|
||||
<font color="#0000FF">Error %s: You need to provide a valid username and password.</font>
|
||||
</body>
|
||||
</html>
|
||||
''' % ('Access denied', status)
|
||||
|
||||
def http_error_404_hander(status, message, traceback, version):
|
||||
""" Custom handler for 404 error, redirect back to main page """
|
||||
return r'''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>404</title>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
<!--
|
||||
location.href = "%s/home/"
|
||||
//-->
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<br/>
|
||||
</body>
|
||||
</html>
|
||||
''' % options['web_root']
|
||||
|
||||
# tornado setup
|
||||
enable_https = options['enable_https']
|
||||
https_cert = options['https_cert']
|
||||
@ -101,25 +67,24 @@ def initWebServer(options={}):
|
||||
app = Application([],
|
||||
debug=sickbeard.DEBUG,
|
||||
gzip=True,
|
||||
xheaders=True,
|
||||
xheaders=sickbeard.HANDLE_REVERSE_PROXY,
|
||||
cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo='
|
||||
)
|
||||
|
||||
# Index Handler
|
||||
# Main Handler
|
||||
app.add_handlers(".*$", [
|
||||
(r"/", RedirectHandler, {'url': '/home/'}),
|
||||
(r'/api/(.*)(/?)', webapi.Api),
|
||||
(r'%s(.*)(/?)' % options['web_root'], webserve.IndexHandler)
|
||||
(r"/", RedirectHandler, {'url': '%s/home/' % options['web_root']}),
|
||||
(r'%s/api/(.*)(/?)' % options['web_root'], webapi.Api),
|
||||
(r'%s/(.*)(/?)' % options['web_root'], webserve.IndexHandler)
|
||||
])
|
||||
|
||||
# Static Path Handler
|
||||
app.add_handlers(".*$", [
|
||||
(r'/(favicon\.ico)', MultiStaticFileHandler,
|
||||
{'paths': '%s/%s' % (options['web_root'], 'images/ico/favicon.ico')}),
|
||||
(r'%s/(favicon\.ico)' % options['web_root'], MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(options['data_root'], 'images/ico/favicon.ico')]}),
|
||||
(r'%s/%s/(.*)(/?)' % (options['web_root'], 'images'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(options['data_root'], 'images'),
|
||||
os.path.join(sickbeard.CACHE_DIR, 'images'),
|
||||
os.path.join(sickbeard.CACHE_DIR, 'images', 'thumbnails')]}),
|
||||
os.path.join(sickbeard.CACHE_DIR, 'images')]}),
|
||||
(r'%s/%s/(.*)(/?)' % (options['web_root'], 'css'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(options['data_root'], 'css')]}),
|
||||
(r'%s/%s/(.*)(/?)' % (options['web_root'], 'js'), MultiStaticFileHandler,
|
||||
|
@ -630,6 +630,7 @@ class RequestHandler(object):
|
||||
self.set_status(status)
|
||||
self.set_header("Location", urlparse.urljoin(utf8(self.request.uri),
|
||||
utf8(url)))
|
||||
|
||||
self.finish()
|
||||
|
||||
def write(self, chunk):
|
||||
|
Loading…
Reference in New Issue
Block a user