mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-13 11:32:20 -05:00
Improved startup/shutdown of tornado.
Fixed issues with notifications related to tornado.
This commit is contained in:
parent
04681b3297
commit
abff43f568
11
SickBeard.py
11
SickBeard.py
@ -361,12 +361,8 @@ def main():
|
|||||||
'https_key': sickbeard.HTTPS_KEY,
|
'https_key': sickbeard.HTTPS_KEY,
|
||||||
}
|
}
|
||||||
|
|
||||||
# init tornado web server
|
# init tornado server
|
||||||
sickbeard.webserveInitScheduler = sickbeard.scheduler.Scheduler(webserverInit(options),
|
sickbeard.WEBSERVER = webserverInit(options)
|
||||||
cycleTime=datetime.timedelta(seconds=3),
|
|
||||||
threadName="TORNADO",
|
|
||||||
silent=True,
|
|
||||||
runImmediately=True)
|
|
||||||
|
|
||||||
# Build from the DB to start with
|
# Build from the DB to start with
|
||||||
logger.log(u"Loading initial show list")
|
logger.log(u"Loading initial show list")
|
||||||
@ -375,6 +371,9 @@ def main():
|
|||||||
# Fire up all our threads
|
# Fire up all our threads
|
||||||
sickbeard.start()
|
sickbeard.start()
|
||||||
|
|
||||||
|
# start tornado thread
|
||||||
|
sickbeard.WEBSERVER.thread.start()
|
||||||
|
|
||||||
# Launch browser if we're supposed to
|
# Launch browser if we're supposed to
|
||||||
if sickbeard.LAUNCH_BROWSER and not noLaunch and not sickbeard.DAEMON:
|
if sickbeard.LAUNCH_BROWSER and not noLaunch and not sickbeard.DAEMON:
|
||||||
sickbeard.launchBrowser(startPort)
|
sickbeard.launchBrowser(startPort)
|
||||||
|
@ -29,7 +29,7 @@ from urllib2 import getproxies
|
|||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
# apparently py2exe won't build these unless they're imported somewhere
|
# apparently py2exe won't build these unless they're imported somewhere
|
||||||
from sickbeard import providers, metadata, config
|
from sickbeard import providers, metadata, config, webserveInit
|
||||||
from sickbeard.providers.generic import GenericProvider
|
from sickbeard.providers.generic import GenericProvider
|
||||||
from providers import ezrss, tvtorrents, btn, newznab, womble, thepiratebay, torrentleech, kat, iptorrents, \
|
from providers import ezrss, tvtorrents, btn, newznab, womble, thepiratebay, torrentleech, kat, iptorrents, \
|
||||||
omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, nextgen, speedcd, nyaatorrents, fanzub
|
omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, nextgen, speedcd, nyaatorrents, fanzub
|
||||||
@ -77,6 +77,7 @@ PIDFILE = ''
|
|||||||
|
|
||||||
DAEMON = None
|
DAEMON = None
|
||||||
NO_RESIZE = False
|
NO_RESIZE = False
|
||||||
|
WEBSERVER = None
|
||||||
|
|
||||||
maintenanceScheduler = None
|
maintenanceScheduler = None
|
||||||
dailySearchScheduler = None
|
dailySearchScheduler = None
|
||||||
@ -89,7 +90,6 @@ properFinderScheduler = None
|
|||||||
autoPostProcesserScheduler = None
|
autoPostProcesserScheduler = None
|
||||||
subtitlesFinderScheduler = None
|
subtitlesFinderScheduler = None
|
||||||
traktWatchListCheckerScheduler = None
|
traktWatchListCheckerScheduler = None
|
||||||
webserveInitScheduler = None
|
|
||||||
|
|
||||||
showList = None
|
showList = None
|
||||||
loadingShowList = None
|
loadingShowList = None
|
||||||
@ -479,7 +479,7 @@ def initialize(consoleLogging=True):
|
|||||||
USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, REMOTE_IP, TMDB_API_KEY, DEBUG, PROXY_SETTING, \
|
USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, REMOTE_IP, TMDB_API_KEY, DEBUG, PROXY_SETTING, \
|
||||||
AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
||||||
ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
|
ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
|
||||||
ANIME_SPLIT_HOME, maintenanceScheduler, SCENE_DEFAULT, WEB_DATA_ROOT, webserveInitScheduler
|
ANIME_SPLIT_HOME, maintenanceScheduler, SCENE_DEFAULT, WEB_DATA_ROOT, WEBSERVER
|
||||||
|
|
||||||
if __INITIALIZED__:
|
if __INITIALIZED__:
|
||||||
return False
|
return False
|
||||||
@ -1119,15 +1119,12 @@ def start():
|
|||||||
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
||||||
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
|
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
|
||||||
subtitlesFinderScheduler, USE_SUBTITLES,traktWatchListCheckerScheduler, \
|
subtitlesFinderScheduler, USE_SUBTITLES,traktWatchListCheckerScheduler, \
|
||||||
dailySearchScheduler, webserveInitScheduler, started
|
dailySearchScheduler, started
|
||||||
|
|
||||||
with INIT_LOCK:
|
with INIT_LOCK:
|
||||||
|
|
||||||
if __INITIALIZED__:
|
if __INITIALIZED__:
|
||||||
|
|
||||||
# start tornado web server
|
|
||||||
webserveInitScheduler.thread.start()
|
|
||||||
|
|
||||||
# start the maintenance scheduler
|
# start the maintenance scheduler
|
||||||
maintenanceScheduler.thread.start()
|
maintenanceScheduler.thread.start()
|
||||||
logger.log(u"Performing initial maintenance tasks, please wait ...")
|
logger.log(u"Performing initial maintenance tasks, please wait ...")
|
||||||
@ -1173,7 +1170,7 @@ def halt():
|
|||||||
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
||||||
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
|
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
|
||||||
subtitlesFinderScheduler, traktWatchListCheckerScheduler, \
|
subtitlesFinderScheduler, traktWatchListCheckerScheduler, \
|
||||||
dailySearchScheduler, webserveInitScheduler, started
|
dailySearchScheduler, started
|
||||||
|
|
||||||
with INIT_LOCK:
|
with INIT_LOCK:
|
||||||
|
|
||||||
@ -1183,13 +1180,6 @@ def halt():
|
|||||||
|
|
||||||
# abort all the threads
|
# abort all the threads
|
||||||
|
|
||||||
webserveInitScheduler.about = True
|
|
||||||
logger.log(u"Waiting for the TORNADO thread to exit")
|
|
||||||
try:
|
|
||||||
webserveInitScheduler.thread.join(10)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
maintenanceScheduler.abort = True
|
maintenanceScheduler.abort = True
|
||||||
logger.log(u"Waiting for the MAINTENANCE scheduler thread to exit")
|
logger.log(u"Waiting for the MAINTENANCE scheduler thread to exit")
|
||||||
try:
|
try:
|
||||||
@ -1197,13 +1187,6 @@ def halt():
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
dailySearchScheduler.abort = True
|
|
||||||
logger.log(u"Waiting for the DAILYSEARCHER thread to exit")
|
|
||||||
try:
|
|
||||||
dailySearchScheduler.thread.join(10)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
backlogSearchScheduler.abort = True
|
backlogSearchScheduler.abort = True
|
||||||
logger.log(u"Waiting for the BACKLOG thread to exit")
|
logger.log(u"Waiting for the BACKLOG thread to exit")
|
||||||
try:
|
try:
|
||||||
@ -1310,16 +1293,12 @@ def saveAll():
|
|||||||
|
|
||||||
|
|
||||||
def saveAndShutdown(restart=False):
|
def saveAndShutdown(restart=False):
|
||||||
|
global WEBSERVER
|
||||||
|
|
||||||
halt()
|
halt()
|
||||||
saveAll()
|
saveAll()
|
||||||
|
|
||||||
logger.log(u"Killing tornado")
|
IOLoop.instance().add_callback(WEBSERVER.shutdown)
|
||||||
try:
|
|
||||||
IOLoop.current().stop()
|
|
||||||
except RuntimeError:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
logger.log('Failed shutting down the server: %s' % traceback.format_exc(), logger.ERROR)
|
|
||||||
|
|
||||||
if CREATEPID:
|
if CREATEPID:
|
||||||
logger.log(u"Removing pidfile " + str(PIDFILE))
|
logger.log(u"Removing pidfile " + str(PIDFILE))
|
||||||
|
@ -163,7 +163,7 @@ def change_AUTOPOSTPROCESSER_FREQUENCY(freq):
|
|||||||
if sickbeard.AUTOPOSTPROCESSER_FREQUENCY < sickbeard.MIN_AUTOPOSTPROCESSER_FREQUENCY:
|
if sickbeard.AUTOPOSTPROCESSER_FREQUENCY < sickbeard.MIN_AUTOPOSTPROCESSER_FREQUENCY:
|
||||||
sickbeard.AUTOPOSTPROCESSER_FREQUENCY = sickbeard.MIN_AUTOPOSTPROCESSER_FREQUENCY
|
sickbeard.AUTOPOSTPROCESSER_FREQUENCY = sickbeard.MIN_AUTOPOSTPROCESSER_FREQUENCY
|
||||||
|
|
||||||
sickbeard.autoPostProcessorScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.AUTOPOSTPROCESSER_FREQUENCY)
|
sickbeard.autoPostProcesserScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.AUTOPOSTPROCESSER_FREQUENCY)
|
||||||
|
|
||||||
def change_DAILYSEARCH_FREQUENCY(freq):
|
def change_DAILYSEARCH_FREQUENCY(freq):
|
||||||
sickbeard.DAILYSEARCH_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_DAILYSEARCH_FREQUENCY)
|
sickbeard.DAILYSEARCH_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_DAILYSEARCH_FREQUENCY)
|
||||||
|
@ -190,6 +190,7 @@ class IndexHandler(RedirectHandler):
|
|||||||
args[arg] = value[0]
|
args[arg] = value[0]
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
@asynchronous
|
||||||
def _dispatch(self):
|
def _dispatch(self):
|
||||||
"""
|
"""
|
||||||
Load up the requested URL if it matches one of our own methods.
|
Load up the requested URL if it matches one of our own methods.
|
||||||
@ -235,12 +236,10 @@ class IndexHandler(RedirectHandler):
|
|||||||
def get_current_user(self):
|
def get_current_user(self):
|
||||||
return self.get_secure_cookie("user")
|
return self.get_secure_cookie("user")
|
||||||
|
|
||||||
@asynchronous
|
|
||||||
@authenticated
|
@authenticated
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
return self._dispatch()
|
return self._dispatch()
|
||||||
|
|
||||||
@asynchronous
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
return self._dispatch()
|
return self._dispatch()
|
||||||
|
|
||||||
@ -1065,7 +1064,7 @@ class Manage(IndexHandler):
|
|||||||
|
|
||||||
exceptions_list = []
|
exceptions_list = []
|
||||||
|
|
||||||
curErrors += Home().editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list,
|
curErrors += self.editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list,
|
||||||
new_flatten_folders, new_paused, subtitles=new_subtitles, anime=new_anime,
|
new_flatten_folders, new_paused, subtitles=new_subtitles, anime=new_anime,
|
||||||
scene=new_scene, directCall=True)
|
scene=new_scene, directCall=True)
|
||||||
|
|
||||||
@ -1602,9 +1601,9 @@ class ConfigPostProcessing(IndexHandler):
|
|||||||
config.change_AUTOPOSTPROCESSER_FREQUENCY(autopostprocesser_frequency)
|
config.change_AUTOPOSTPROCESSER_FREQUENCY(autopostprocesser_frequency)
|
||||||
|
|
||||||
if sickbeard.PROCESS_AUTOMATICALLY:
|
if sickbeard.PROCESS_AUTOMATICALLY:
|
||||||
sickbeard.autoPostProcessorScheduler.silent = False
|
sickbeard.autoPostProcesserScheduler.silent = False
|
||||||
else:
|
else:
|
||||||
sickbeard.autoPostProcessorScheduler.silent = True
|
sickbeard.autoPostProcesserScheduler.silent = True
|
||||||
|
|
||||||
if unpack:
|
if unpack:
|
||||||
if self.isRarSupported() != 'not supported':
|
if self.isRarSupported() != 'not supported':
|
||||||
@ -3281,8 +3280,7 @@ class Home(IndexHandler):
|
|||||||
title = "Shutting down"
|
title = "Shutting down"
|
||||||
message = "SickRage is shutting down..."
|
message = "SickRage is shutting down..."
|
||||||
|
|
||||||
return _genericMessage(title, message)
|
return self.finish(_genericMessage(title, message))
|
||||||
|
|
||||||
|
|
||||||
def restart(self, pid=None):
|
def restart(self, pid=None):
|
||||||
|
|
||||||
@ -3311,8 +3309,8 @@ class Home(IndexHandler):
|
|||||||
t = PageTemplate(file="restart_bare.tmpl")
|
t = PageTemplate(file="restart_bare.tmpl")
|
||||||
return self.finish(_munge(t))
|
return self.finish(_munge(t))
|
||||||
else:
|
else:
|
||||||
return _genericMessage("Update Failed",
|
return self.finish(_genericMessage("Update Failed",
|
||||||
"Update wasn't successful, not restarting. Check your log for more information.")
|
"Update wasn't successful, not restarting. Check your log for more information."))
|
||||||
|
|
||||||
|
|
||||||
def displayShow(self, show=None):
|
def displayShow(self, show=None):
|
||||||
@ -3477,7 +3475,7 @@ class Home(IndexHandler):
|
|||||||
if directCall:
|
if directCall:
|
||||||
return [errString]
|
return [errString]
|
||||||
else:
|
else:
|
||||||
return _genericMessage("Error", errString)
|
return self.finish(_genericMessage("Error", errString))
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
@ -3486,7 +3484,7 @@ class Home(IndexHandler):
|
|||||||
if directCall:
|
if directCall:
|
||||||
return [errString]
|
return [errString]
|
||||||
else:
|
else:
|
||||||
return _genericMessage("Error", errString)
|
return self.finish(_genericMessage("Error", errString))
|
||||||
|
|
||||||
showObj.exceptions = scene_exceptions.get_scene_exceptions(showObj.indexerid)
|
showObj.exceptions = scene_exceptions.get_scene_exceptions(showObj.indexerid)
|
||||||
|
|
||||||
@ -3727,16 +3725,16 @@ class Home(IndexHandler):
|
|||||||
def deleteShow(self, show=None):
|
def deleteShow(self, show=None):
|
||||||
|
|
||||||
if show is None:
|
if show is None:
|
||||||
return _genericMessage("Error", "Invalid show ID")
|
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
if showObj is None:
|
if showObj is None:
|
||||||
return _genericMessage("Error", "Unable to find the specified show")
|
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||||
|
|
||||||
if sickbeard.showQueueScheduler.action.isBeingAdded(
|
if sickbeard.showQueueScheduler.action.isBeingAdded(
|
||||||
showObj) or sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): # @UndefinedVariable
|
showObj) or sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): # @UndefinedVariable
|
||||||
return _genericMessage("Error", "Shows can't be deleted while they're being added or updated.")
|
return self.finish(_genericMessage("Error", "Shows can't be deleted while they're being added or updated."))
|
||||||
|
|
||||||
showObj.deleteShow()
|
showObj.deleteShow()
|
||||||
|
|
||||||
@ -3747,12 +3745,12 @@ class Home(IndexHandler):
|
|||||||
def refreshShow(self, show=None):
|
def refreshShow(self, show=None):
|
||||||
|
|
||||||
if show is None:
|
if show is None:
|
||||||
return _genericMessage("Error", "Invalid show ID")
|
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
if showObj is None:
|
if showObj is None:
|
||||||
return _genericMessage("Error", "Unable to find the specified show")
|
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||||
|
|
||||||
# force the update from the DB
|
# force the update from the DB
|
||||||
try:
|
try:
|
||||||
@ -3769,12 +3767,12 @@ class Home(IndexHandler):
|
|||||||
def updateShow(self, show=None, force=0):
|
def updateShow(self, show=None, force=0):
|
||||||
|
|
||||||
if show is None:
|
if show is None:
|
||||||
return _genericMessage("Error", "Invalid show ID")
|
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
if showObj is None:
|
if showObj is None:
|
||||||
return _genericMessage("Error", "Unable to find the specified show")
|
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||||
|
|
||||||
# force the update
|
# force the update
|
||||||
try:
|
try:
|
||||||
@ -3792,12 +3790,12 @@ class Home(IndexHandler):
|
|||||||
def subtitleShow(self, show=None, force=0):
|
def subtitleShow(self, show=None, force=0):
|
||||||
|
|
||||||
if show is None:
|
if show is None:
|
||||||
return _genericMessage("Error", "Invalid show ID")
|
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
if showObj is None:
|
if showObj is None:
|
||||||
return _genericMessage("Error", "Unable to find the specified show")
|
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||||
|
|
||||||
# search and download subtitles
|
# search and download subtitles
|
||||||
sickbeard.showQueueScheduler.action.downloadSubtitles(showObj, bool(force)) # @UndefinedVariable
|
sickbeard.showQueueScheduler.action.downloadSubtitles(showObj, bool(force)) # @UndefinedVariable
|
||||||
@ -3840,7 +3838,7 @@ class Home(IndexHandler):
|
|||||||
ui.notifications.error('Error', errMsg)
|
ui.notifications.error('Error', errMsg)
|
||||||
return json.dumps({'result': 'error'})
|
return json.dumps({'result': 'error'})
|
||||||
else:
|
else:
|
||||||
return _genericMessage("Error", errMsg)
|
return self.finish(_genericMessage("Error", errMsg))
|
||||||
|
|
||||||
if not statusStrings.has_key(int(status)):
|
if not statusStrings.has_key(int(status)):
|
||||||
errMsg = "Invalid status"
|
errMsg = "Invalid status"
|
||||||
@ -3848,7 +3846,7 @@ class Home(IndexHandler):
|
|||||||
ui.notifications.error('Error', errMsg)
|
ui.notifications.error('Error', errMsg)
|
||||||
return json.dumps({'result': 'error'})
|
return json.dumps({'result': 'error'})
|
||||||
else:
|
else:
|
||||||
return _genericMessage("Error", errMsg)
|
return self.finish(_genericMessage("Error", errMsg))
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
@ -3858,7 +3856,7 @@ class Home(IndexHandler):
|
|||||||
ui.notifications.error('Error', errMsg)
|
ui.notifications.error('Error', errMsg)
|
||||||
return json.dumps({'result': 'error'})
|
return json.dumps({'result': 'error'})
|
||||||
else:
|
else:
|
||||||
return _genericMessage("Error", errMsg)
|
return self.finish(_genericMessage("Error", errMsg))
|
||||||
|
|
||||||
segment = {}
|
segment = {}
|
||||||
if eps is not None:
|
if eps is not None:
|
||||||
@ -3873,7 +3871,7 @@ class Home(IndexHandler):
|
|||||||
epObj = showObj.getEpisode(int(epInfo[0]), int(epInfo[1]))
|
epObj = showObj.getEpisode(int(epInfo[0]), int(epInfo[1]))
|
||||||
|
|
||||||
if epObj is None:
|
if epObj is None:
|
||||||
return _genericMessage("Error", "Episode couldn't be retrieved")
|
return self.finish(_genericMessage("Error", "Episode couldn't be retrieved"))
|
||||||
|
|
||||||
if int(status) in [WANTED, FAILED]:
|
if int(status) in [WANTED, FAILED]:
|
||||||
# figure out what episodes are wanted so we can backlog them
|
# figure out what episodes are wanted so we can backlog them
|
||||||
@ -3949,17 +3947,17 @@ class Home(IndexHandler):
|
|||||||
def testRename(self, show=None):
|
def testRename(self, show=None):
|
||||||
|
|
||||||
if show is None:
|
if show is None:
|
||||||
return _genericMessage("Error", "You must specify a show")
|
return self.finish(_genericMessage("Error", "You must specify a show"))
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
if showObj is None:
|
if showObj is None:
|
||||||
return _genericMessage("Error", "Show not in show list")
|
return self.finish(_genericMessage("Error", "Show not in show list"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
show_loc = showObj.location # @UnusedVariable
|
show_loc = showObj.location # @UnusedVariable
|
||||||
except exceptions.ShowDirNotFoundException:
|
except exceptions.ShowDirNotFoundException:
|
||||||
return _genericMessage("Error", "Can't rename episodes when the show dir is missing.")
|
return self.finish(_genericMessage("Error", "Can't rename episodes when the show dir is missing."))
|
||||||
|
|
||||||
ep_obj_rename_list = []
|
ep_obj_rename_list = []
|
||||||
|
|
||||||
@ -3996,18 +3994,18 @@ class Home(IndexHandler):
|
|||||||
|
|
||||||
if show is None or eps is None:
|
if show is None or eps is None:
|
||||||
errMsg = "You must specify a show and at least one episode"
|
errMsg = "You must specify a show and at least one episode"
|
||||||
return _genericMessage("Error", errMsg)
|
return self.finish(_genericMessage("Error", errMsg))
|
||||||
|
|
||||||
show_obj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
show_obj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||||
|
|
||||||
if show_obj is None:
|
if show_obj is None:
|
||||||
errMsg = "Error", "Show not in show list"
|
errMsg = "Error", "Show not in show list"
|
||||||
return _genericMessage("Error", errMsg)
|
return self.finish(_genericMessage("Error", errMsg))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
show_loc = show_obj.location # @UnusedVariable
|
show_loc = show_obj.location # @UnusedVariable
|
||||||
except exceptions.ShowDirNotFoundException:
|
except exceptions.ShowDirNotFoundException:
|
||||||
return _genericMessage("Error", "Can't rename episodes when the show dir is missing.")
|
return self.finish(_genericMessage("Error", "Can't rename episodes when the show dir is missing."))
|
||||||
|
|
||||||
if eps is None:
|
if eps is None:
|
||||||
self.redirect("/home/displayShow?show=" + show)
|
self.redirect("/home/displayShow?show=" + show)
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import os
|
import os
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
import datetime
|
||||||
import sickbeard
|
import sickbeard
|
||||||
import webserve
|
import webserve
|
||||||
import tornado.httpserver
|
from sickbeard.exceptions import ex
|
||||||
import tornado.ioloop
|
|
||||||
from sickbeard import logger
|
from sickbeard import logger
|
||||||
from sickbeard.helpers import create_https_certificates
|
from sickbeard.helpers import create_https_certificates
|
||||||
from tornado.web import Application, StaticFileHandler, HTTPError, RedirectHandler
|
from tornado.web import Application, StaticFileHandler, RedirectHandler, HTTPError
|
||||||
|
from tornado.httpserver import HTTPServer
|
||||||
|
from tornado.ioloop import IOLoop
|
||||||
|
|
||||||
|
|
||||||
class MultiStaticFileHandler(StaticFileHandler):
|
class MultiStaticFileHandler(StaticFileHandler):
|
||||||
def initialize(self, paths, default_filename=None):
|
def initialize(self, paths, default_filename=None):
|
||||||
@ -27,17 +33,27 @@ class MultiStaticFileHandler(StaticFileHandler):
|
|||||||
# Oops file not found anywhere!
|
# Oops file not found anywhere!
|
||||||
raise HTTPError(404)
|
raise HTTPError(404)
|
||||||
|
|
||||||
|
|
||||||
class webserverInit():
|
class webserverInit():
|
||||||
def __init__(self, options):
|
def __init__(self, options, cycleTime=datetime.timedelta(seconds=3)):
|
||||||
|
|
||||||
self.amActive = False
|
self.amActive = False
|
||||||
options.setdefault('port', 8081)
|
self.lastRun = datetime.datetime.fromordinal(1)
|
||||||
options.setdefault('host', '0.0.0.0')
|
self.cycleTime = cycleTime
|
||||||
options.setdefault('log_dir', None)
|
self.abort = False
|
||||||
options.setdefault('username', '')
|
|
||||||
options.setdefault('password', '')
|
self.server = None
|
||||||
options.setdefault('web_root', '/')
|
self.thread = None
|
||||||
assert isinstance(options['port'], int)
|
|
||||||
assert 'data_root' in options
|
self.options = options
|
||||||
|
self.options.setdefault('port', 8081)
|
||||||
|
self.options.setdefault('host', '0.0.0.0')
|
||||||
|
self.options.setdefault('log_dir', None)
|
||||||
|
self.options.setdefault('username', '')
|
||||||
|
self.options.setdefault('password', '')
|
||||||
|
self.options.setdefault('web_root', '/')
|
||||||
|
assert isinstance(self.options['port'], int)
|
||||||
|
assert 'data_root' in self.options
|
||||||
|
|
||||||
def http_error_401_hander(status, message, traceback, version):
|
def http_error_401_hander(status, message, traceback, version):
|
||||||
""" Custom handler for 401 error """
|
""" Custom handler for 401 error """
|
||||||
@ -72,12 +88,12 @@ class webserverInit():
|
|||||||
<br/>
|
<br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
''' % options['web_root']
|
''' % self.options['web_root']
|
||||||
|
|
||||||
# tornado setup
|
# tornado setup
|
||||||
enable_https = options['enable_https']
|
enable_https = self.options['enable_https']
|
||||||
https_cert = options['https_cert']
|
https_cert = self.options['https_cert']
|
||||||
https_key = options['https_key']
|
https_key = self.options['https_key']
|
||||||
|
|
||||||
if enable_https:
|
if enable_https:
|
||||||
# If either the HTTPS certificate or key do not exist, make some self-signed ones.
|
# If either the HTTPS certificate or key do not exist, make some self-signed ones.
|
||||||
@ -103,42 +119,84 @@ class webserverInit():
|
|||||||
|
|
||||||
# Index Handler
|
# Index Handler
|
||||||
app.add_handlers(".*$", [
|
app.add_handlers(".*$", [
|
||||||
(r"/", tornado.web.RedirectHandler, {'url': '/home/'}),
|
(r"/", RedirectHandler, {'url': '/home/'}),
|
||||||
(r'/login', webserve.LoginHandler),
|
(r'/login', webserve.LoginHandler),
|
||||||
(r'%s(.*)(/?)' % options['web_root'], webserve.IndexHandler)
|
(r'%s(.*)(/?)' % self.options['web_root'], webserve.IndexHandler)
|
||||||
])
|
])
|
||||||
|
|
||||||
# Static Path Handler
|
# Static Path Handler
|
||||||
app.add_handlers(".*$", [
|
app.add_handlers(".*$", [
|
||||||
('%s/%s/(.*)([^/]*)' % (options['web_root'], 'images'), MultiStaticFileHandler,
|
('%s/%s/(.*)([^/]*)' % (self.options['web_root'], 'images'), MultiStaticFileHandler,
|
||||||
{'paths': [os.path.join(options['data_root'], 'images'),
|
{'paths': [os.path.join(self.options['data_root'], 'images'),
|
||||||
os.path.join(sickbeard.CACHE_DIR, 'images'),
|
os.path.join(sickbeard.CACHE_DIR, 'images'),
|
||||||
os.path.join(sickbeard.CACHE_DIR, 'images', 'thumbnails')]}),
|
os.path.join(sickbeard.CACHE_DIR, 'images', 'thumbnails')]}),
|
||||||
('%s/%s/(.*)([^/]*)' % (options['web_root'], 'css'), MultiStaticFileHandler,
|
('%s/%s/(.*)([^/]*)' % (self.options['web_root'], 'css'), MultiStaticFileHandler,
|
||||||
{'paths': [os.path.join(options['data_root'], 'css')]}),
|
{'paths': [os.path.join(self.options['data_root'], 'css')]}),
|
||||||
('%s/%s/(.*)([^/]*)' % (options['web_root'], 'js'), MultiStaticFileHandler,
|
('%s/%s/(.*)([^/]*)' % (self.options['web_root'], 'js'), MultiStaticFileHandler,
|
||||||
{'paths': [os.path.join(options['data_root'], 'js')]})
|
{'paths': [os.path.join(self.options['data_root'], 'js')]})
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
if enable_https:
|
if enable_https:
|
||||||
protocol = "https"
|
protocol = "https"
|
||||||
server = tornado.httpserver.HTTPServer(app, no_keep_alive=True,
|
self.server = HTTPServer(app, no_keep_alive=True,
|
||||||
ssl_options={"certfile": https_cert, "keyfile": https_key})
|
ssl_options={"certfile": https_cert, "keyfile": https_key})
|
||||||
else:
|
else:
|
||||||
protocol = "http"
|
protocol = "http"
|
||||||
server = tornado.httpserver.HTTPServer(app, no_keep_alive=True)
|
self.server = HTTPServer(app, no_keep_alive=True)
|
||||||
|
|
||||||
logger.log(u"Starting SickRage on " + protocol + "://" + str(options['host']) + ":" + str(
|
logger.log(u"Starting SickRage on " + protocol + "://" + str(self.options['host']) + ":" + str(
|
||||||
options['port']) + "/")
|
self.options['port']) + "/")
|
||||||
|
|
||||||
server.listen(options['port'], options['host'])
|
self.server.listen(self.options['port'], self.options['host'])
|
||||||
|
|
||||||
|
if self.thread == None or not self.thread.isAlive():
|
||||||
|
self.thread = threading.Thread(None, self.monitor, 'TORNADO')
|
||||||
|
|
||||||
|
def monitor(self):
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
currentTime = datetime.datetime.now()
|
||||||
|
|
||||||
|
if currentTime - self.lastRun > self.cycleTime:
|
||||||
|
self.lastRun = currentTime
|
||||||
|
try:
|
||||||
|
logger.log(u"Starting tornado", logger.DEBUG)
|
||||||
|
|
||||||
|
IOLoop.instance().start()
|
||||||
|
except Exception, e:
|
||||||
|
logger.log(u"Exception generated in tornado: " + ex(e), logger.ERROR)
|
||||||
|
logger.log(repr(traceback.format_exc()), logger.DEBUG)
|
||||||
|
|
||||||
|
if self.abort:
|
||||||
|
self.abort = False
|
||||||
|
self.thread = None
|
||||||
|
return
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
|
||||||
|
logger.logging.info('Shutting down tornado')
|
||||||
|
|
||||||
def run(self, force=False):
|
|
||||||
try:
|
try:
|
||||||
self.amActive = True
|
self.abort = True
|
||||||
tornado.ioloop.IOLoop.instance().start()
|
self.server.stop()
|
||||||
|
|
||||||
|
deadline = time.time() + 10
|
||||||
|
|
||||||
|
io_loop = IOLoop.instance()
|
||||||
|
def stop_loop():
|
||||||
|
now = time.time()
|
||||||
|
|
||||||
|
if now < deadline:
|
||||||
|
if io_loop._callbacks:
|
||||||
|
io_loop.add_timeout(now + 1, stop_loop)
|
||||||
|
return
|
||||||
|
stop_loop()
|
||||||
|
self.thread.join(10)
|
||||||
except:
|
except:
|
||||||
self.amActive = False
|
pass
|
||||||
raise
|
|
||||||
|
logger.logging.info('Tornado is now shutdown')
|
Loading…
Reference in New Issue
Block a user