mirror of
https://github.com/moparisthebest/SickRage
synced 2024-11-15 13:55:05 -05:00
Auto-reloads app on code changes automatically detected from git.
Fixed issues with basicauth/cookies and login page. Parse results now displayed all the time.
This commit is contained in:
parent
088e32b117
commit
489a181cdb
21
SickBeard.py
21
SickBeard.py
@ -18,8 +18,10 @@
|
|||||||
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Check needed software dependencies to nudge users to fix their setup
|
# Check needed software dependencies to nudge users to fix their setup
|
||||||
|
import functools
|
||||||
import sys
|
import sys
|
||||||
import tornado.ioloop
|
import tornado.ioloop
|
||||||
|
import tornado.autoreload
|
||||||
|
|
||||||
if sys.version_info < (2, 6):
|
if sys.version_info < (2, 6):
|
||||||
print "Sorry, requires Python 2.6 or 2.7."
|
print "Sorry, requires Python 2.6 or 2.7."
|
||||||
@ -151,6 +153,8 @@ def main():
|
|||||||
TV for me
|
TV for me
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
io_loop = IOLoop.current()
|
||||||
|
|
||||||
# do some preliminary stuff
|
# do some preliminary stuff
|
||||||
sickbeard.MY_FULLNAME = os.path.normpath(os.path.abspath(__file__))
|
sickbeard.MY_FULLNAME = os.path.normpath(os.path.abspath(__file__))
|
||||||
sickbeard.MY_NAME = os.path.basename(sickbeard.MY_FULLNAME)
|
sickbeard.MY_NAME = os.path.basename(sickbeard.MY_FULLNAME)
|
||||||
@ -381,10 +385,21 @@ def main():
|
|||||||
sickbeard.showUpdateScheduler.action.run(force=True) # @UndefinedVariable
|
sickbeard.showUpdateScheduler.action.run(force=True) # @UndefinedVariable
|
||||||
|
|
||||||
# init startup tasks
|
# init startup tasks
|
||||||
IOLoop.current().add_timeout(datetime.timedelta(seconds=5), startup)
|
io_loop.add_timeout(datetime.timedelta(seconds=5), startup)
|
||||||
|
|
||||||
# start IOLoop
|
def autoreload_shutdown():
|
||||||
IOLoop.current().start()
|
logger.log('SickRage is now auto-reloading, please stand by ...')
|
||||||
|
webserveInit.server.stop()
|
||||||
|
sickbeard.halt()
|
||||||
|
sickbeard.saveAll()
|
||||||
|
sickbeard.cleanup_tornado_sockets(io_loop)
|
||||||
|
|
||||||
|
# autoreload.
|
||||||
|
tornado.autoreload.start(io_loop)
|
||||||
|
tornado.autoreload.add_reload_hook(autoreload_shutdown)
|
||||||
|
|
||||||
|
# start IOLoop.
|
||||||
|
io_loop.start()
|
||||||
sickbeard.saveAndShutdown()
|
sickbeard.saveAndShutdown()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1279,7 +1279,7 @@ def remove_pid_file(PIDFILE):
|
|||||||
def sig_handler(signum=None, frame=None):
|
def sig_handler(signum=None, frame=None):
|
||||||
if type(signum) != type(None):
|
if type(signum) != type(None):
|
||||||
logger.log(u"Signal %i caught, saving and exiting..." % int(signum))
|
logger.log(u"Signal %i caught, saving and exiting..." % int(signum))
|
||||||
saveAndShutdown()
|
webserveInit.shutdown()
|
||||||
|
|
||||||
def saveAll():
|
def saveAll():
|
||||||
global showList
|
global showList
|
||||||
@ -1293,10 +1293,20 @@ def saveAll():
|
|||||||
logger.log(u"Saving config file to disk")
|
logger.log(u"Saving config file to disk")
|
||||||
save_config()
|
save_config()
|
||||||
|
|
||||||
|
def cleanup_tornado_sockets(io_loop):
|
||||||
|
for fd in io_loop._handlers.keys():
|
||||||
|
try:
|
||||||
|
os.close(fd)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def saveAndShutdown():
|
def saveAndShutdown():
|
||||||
|
|
||||||
halt()
|
halt()
|
||||||
saveAll()
|
saveAll()
|
||||||
|
|
||||||
|
cleanup_tornado_sockets(IOLoop.current())
|
||||||
|
|
||||||
if CREATEPID:
|
if CREATEPID:
|
||||||
logger.log(u"Removing pidfile " + str(PIDFILE))
|
logger.log(u"Removing pidfile " + str(PIDFILE))
|
||||||
remove_pid_file(PIDFILE)
|
remove_pid_file(PIDFILE)
|
||||||
|
@ -369,6 +369,8 @@ class NameParser(object):
|
|||||||
if cache_result:
|
if cache_result:
|
||||||
name_parser_cache.add(name, final_result)
|
name_parser_cache.add(name, final_result)
|
||||||
|
|
||||||
|
logger.log(u"Parsed " + name + " into " + str(final_result).decode('utf-8', 'xmlcharrefreplace'), logger.DEBUG)
|
||||||
|
|
||||||
return final_result
|
return final_result
|
||||||
|
|
||||||
|
|
||||||
@ -547,6 +549,8 @@ class ParseResult(object):
|
|||||||
self.episode_numbers = new_episode_numbers
|
self.episode_numbers = new_episode_numbers
|
||||||
self.season_number = new_season_numbers[0]
|
self.season_number = new_season_numbers[0]
|
||||||
|
|
||||||
|
logger.log(u"Converted parsed result " + self.original_name + " into " + str(self).decode('utf-8', 'xmlcharrefreplace'), logger.DEBUG)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _is_air_by_date(self):
|
def _is_air_by_date(self):
|
||||||
|
@ -481,8 +481,6 @@ class PostProcessor(object):
|
|||||||
np = NameParser(file, useIndexers=True, convert=True)
|
np = NameParser(file, useIndexers=True, convert=True)
|
||||||
parse_result = np.parse(name)
|
parse_result = np.parse(name)
|
||||||
|
|
||||||
self._log(u"Parsed " + name + " into " + str(parse_result).decode('utf-8', 'xmlcharrefreplace'), logger.DEBUG)
|
|
||||||
|
|
||||||
# couldn't find this in our show list
|
# couldn't find this in our show list
|
||||||
if not parse_result.show:
|
if not parse_result.show:
|
||||||
return to_return
|
return to_return
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import sickbeard
|
import sickbeard
|
||||||
|
|
||||||
from tornado.httputil import HTTPHeaders
|
from tornado.web import RequestHandler
|
||||||
|
|
||||||
MESSAGE = 'notice'
|
MESSAGE = 'notice'
|
||||||
ERROR = 'error'
|
ERROR = 'error'
|
||||||
|
|
||||||
|
|
||||||
class Notifications(object):
|
class Notifications(RequestHandler):
|
||||||
"""
|
"""
|
||||||
A queue of Notification objects.
|
A queue of Notification objects.
|
||||||
"""
|
"""
|
||||||
@ -71,7 +71,7 @@ class Notifications(object):
|
|||||||
notifications = Notifications()
|
notifications = Notifications()
|
||||||
|
|
||||||
|
|
||||||
class Notification(object):
|
class Notification(RequestHandler):
|
||||||
"""
|
"""
|
||||||
Represents a single notification. Tracks its own timeout and a list of which clients have
|
Represents a single notification. Tracks its own timeout and a list of which clients have
|
||||||
seen it before.
|
seen it before.
|
||||||
|
@ -58,8 +58,8 @@ class CheckVersion():
|
|||||||
if sickbeard.AUTO_UPDATE:
|
if sickbeard.AUTO_UPDATE:
|
||||||
logger.log(u"New update found for SickRage, starting auto-updater ...")
|
logger.log(u"New update found for SickRage, starting auto-updater ...")
|
||||||
if sickbeard.versionCheckScheduler.action.update():
|
if sickbeard.versionCheckScheduler.action.update():
|
||||||
logger.log(u"Update was successfull, restarting SickRage ...")
|
logger.log(u"Update was successfull, auto-reloading SickRage ...")
|
||||||
threading.Timer(2, sickbeard.invoke_restart, [False]).start()
|
#threading.Timer(2, sickbeard.invoke_restart, [False]).start()
|
||||||
|
|
||||||
def find_install_type(self):
|
def find_install_type(self):
|
||||||
"""
|
"""
|
||||||
|
@ -105,9 +105,7 @@ def require_basic_auth(handler_class):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
auth_header = handler.request.headers.get('Authorization')
|
auth_header = handler.request.headers.get('Authorization')
|
||||||
if auth_header is None or not auth_header.startswith('Basic '):
|
if auth_header and auth_header.startswith('Basic '):
|
||||||
get_auth()
|
|
||||||
|
|
||||||
auth_decoded = base64.decodestring(auth_header[6:])
|
auth_decoded = base64.decodestring(auth_header[6:])
|
||||||
basicauth_user, basicauth_pass = auth_decoded.split(':', 2)
|
basicauth_user, basicauth_pass = auth_decoded.split(':', 2)
|
||||||
if basicauth_user == sickbeard.WEB_USERNAME and basicauth_pass == sickbeard.WEB_PASSWORD:
|
if basicauth_user == sickbeard.WEB_USERNAME and basicauth_pass == sickbeard.WEB_PASSWORD:
|
||||||
@ -128,28 +126,12 @@ def require_basic_auth(handler_class):
|
|||||||
handler_class._execute = wrap_execute(handler_class._execute)
|
handler_class._execute = wrap_execute(handler_class._execute)
|
||||||
return handler_class
|
return handler_class
|
||||||
|
|
||||||
|
@require_basic_auth
|
||||||
class RedirectHandler(RequestHandler):
|
class RedirectHandler(RequestHandler):
|
||||||
"""Redirects the client to the given URL for all GET requests.
|
|
||||||
|
|
||||||
You should provide the keyword argument ``url`` to the handler, e.g.::
|
def get(self, path, **kwargs):
|
||||||
|
|
||||||
application = web.Application([
|
|
||||||
(r"/oldpath", web.RedirectHandler, {"url": "/newpath"}),
|
|
||||||
])
|
|
||||||
"""
|
|
||||||
|
|
||||||
def get(self, path):
|
|
||||||
self.redirect(path, permanent=True)
|
self.redirect(path, permanent=True)
|
||||||
|
|
||||||
|
|
||||||
@require_basic_auth
|
|
||||||
class LoginHandler(RedirectHandler):
|
|
||||||
def get(self, path):
|
|
||||||
self.redirect(self.get_argument("next", u"/"))
|
|
||||||
|
|
||||||
|
|
||||||
@require_basic_auth
|
|
||||||
class IndexHandler(RedirectHandler):
|
class IndexHandler(RedirectHandler):
|
||||||
def __init__(self, application, request, **kwargs):
|
def __init__(self, application, request, **kwargs):
|
||||||
super(IndexHandler, self).__init__(application, request, **kwargs)
|
super(IndexHandler, self).__init__(application, request, **kwargs)
|
||||||
@ -171,10 +153,7 @@ class IndexHandler(RedirectHandler):
|
|||||||
return args
|
return args
|
||||||
|
|
||||||
def _dispatch(self):
|
def _dispatch(self):
|
||||||
"""
|
|
||||||
Load up the requested URL if it matches one of our own methods.
|
|
||||||
Skip methods that start with an underscore (_).
|
|
||||||
"""
|
|
||||||
args = None
|
args = None
|
||||||
path = self.request.uri.split('?')[0]
|
path = self.request.uri.split('?')[0]
|
||||||
|
|
||||||
@ -469,6 +448,9 @@ class IndexHandler(RedirectHandler):
|
|||||||
|
|
||||||
browser = WebFileBrowser
|
browser = WebFileBrowser
|
||||||
|
|
||||||
|
class LoginHandler(IndexHandler):
|
||||||
|
def get(self):
|
||||||
|
self.redirect(self.get_argument("next", u"/"))
|
||||||
|
|
||||||
class PageTemplate(Template):
|
class PageTemplate(Template):
|
||||||
def __init__(self, *args, **KWs):
|
def __init__(self, *args, **KWs):
|
||||||
|
@ -10,6 +10,8 @@ from sickbeard.helpers import create_https_certificates
|
|||||||
from tornado.web import Application, StaticFileHandler, RedirectHandler, HTTPError
|
from tornado.web import Application, StaticFileHandler, RedirectHandler, HTTPError
|
||||||
from tornado.httpserver import HTTPServer
|
from tornado.httpserver import HTTPServer
|
||||||
|
|
||||||
|
server = None
|
||||||
|
|
||||||
class MultiStaticFileHandler(StaticFileHandler):
|
class MultiStaticFileHandler(StaticFileHandler):
|
||||||
def initialize(self, paths, default_filename=None):
|
def initialize(self, paths, default_filename=None):
|
||||||
self.paths = paths
|
self.paths = paths
|
||||||
@ -95,10 +97,11 @@ def initWebServer(options={}):
|
|||||||
|
|
||||||
# Load the app
|
# Load the app
|
||||||
app = Application([],
|
app = Application([],
|
||||||
debug=True,
|
log_function=lambda x: None,
|
||||||
|
debug=False,
|
||||||
gzip=True,
|
gzip=True,
|
||||||
autoreload=True,
|
autoreload=True,
|
||||||
xheaders=False,
|
xheaders=True,
|
||||||
cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=',
|
cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=',
|
||||||
login_url='/login'
|
login_url='/login'
|
||||||
)
|
)
|
||||||
@ -140,9 +143,12 @@ def initWebServer(options={}):
|
|||||||
server.listen(options['port'], options['host'])
|
server.listen(options['port'], options['host'])
|
||||||
|
|
||||||
def shutdown():
|
def shutdown():
|
||||||
|
global server
|
||||||
|
|
||||||
logger.log('Shutting down tornado')
|
logger.log('Shutting down tornado')
|
||||||
try:
|
try:
|
||||||
IOLoop.current().stop()
|
IOLoop.current().stop()
|
||||||
|
server.stop()
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
|
Loading…
Reference in New Issue
Block a user