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:
echel0n 2014-06-16 03:44:33 -07:00
parent 088e32b117
commit 489a181cdb
8 changed files with 59 additions and 44 deletions

View file

@ -18,8 +18,10 @@
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
# Check needed software dependencies to nudge users to fix their setup
import functools
import sys
import tornado.ioloop
import tornado.autoreload
if sys.version_info < (2, 6):
print "Sorry, requires Python 2.6 or 2.7."
@ -151,6 +153,8 @@ 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)
@ -381,10 +385,21 @@ def main():
sickbeard.showUpdateScheduler.action.run(force=True) # @UndefinedVariable
# init startup tasks
IOLoop.current().add_timeout(datetime.timedelta(seconds=5), startup)
io_loop.add_timeout(datetime.timedelta(seconds=5), startup)
# start IOLoop
IOLoop.current().start()
def autoreload_shutdown():
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()
return

View file

@ -1279,7 +1279,7 @@ def remove_pid_file(PIDFILE):
def sig_handler(signum=None, frame=None):
if type(signum) != type(None):
logger.log(u"Signal %i caught, saving and exiting..." % int(signum))
saveAndShutdown()
webserveInit.shutdown()
def saveAll():
global showList
@ -1293,10 +1293,20 @@ def saveAll():
logger.log(u"Saving config file to disk")
save_config()
def cleanup_tornado_sockets(io_loop):
for fd in io_loop._handlers.keys():
try:
os.close(fd)
except Exception:
pass
def saveAndShutdown():
halt()
saveAll()
cleanup_tornado_sockets(IOLoop.current())
if CREATEPID:
logger.log(u"Removing pidfile " + str(PIDFILE))
remove_pid_file(PIDFILE)

View file

@ -369,6 +369,8 @@ class NameParser(object):
if cache_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
@ -547,6 +549,8 @@ class ParseResult(object):
self.episode_numbers = new_episode_numbers
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
def _is_air_by_date(self):

View file

@ -481,8 +481,6 @@ class PostProcessor(object):
np = NameParser(file, useIndexers=True, convert=True)
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
if not parse_result.show:
return to_return

View file

@ -19,13 +19,13 @@
import datetime
import sickbeard
from tornado.httputil import HTTPHeaders
from tornado.web import RequestHandler
MESSAGE = 'notice'
ERROR = 'error'
class Notifications(object):
class Notifications(RequestHandler):
"""
A queue of Notification objects.
"""
@ -71,7 +71,7 @@ class Notifications(object):
notifications = Notifications()
class Notification(object):
class Notification(RequestHandler):
"""
Represents a single notification. Tracks its own timeout and a list of which clients have
seen it before.

View file

@ -58,8 +58,8 @@ class CheckVersion():
if sickbeard.AUTO_UPDATE:
logger.log(u"New update found for SickRage, starting auto-updater ...")
if sickbeard.versionCheckScheduler.action.update():
logger.log(u"Update was successfull, restarting SickRage ...")
threading.Timer(2, sickbeard.invoke_restart, [False]).start()
logger.log(u"Update was successfull, auto-reloading SickRage ...")
#threading.Timer(2, sickbeard.invoke_restart, [False]).start()
def find_install_type(self):
"""

View file

@ -105,15 +105,13 @@ def require_basic_auth(handler_class):
return True
auth_header = handler.request.headers.get('Authorization')
if auth_header is None or not auth_header.startswith('Basic '):
get_auth()
auth_decoded = base64.decodestring(auth_header[6:])
basicauth_user, basicauth_pass = auth_decoded.split(':', 2)
if basicauth_user == sickbeard.WEB_USERNAME and basicauth_pass == sickbeard.WEB_PASSWORD:
if not handler.get_secure_cookie("user"):
handler.set_secure_cookie("user", str(time.time()))
return True
if auth_header and auth_header.startswith('Basic '):
auth_decoded = base64.decodestring(auth_header[6:])
basicauth_user, basicauth_pass = auth_decoded.split(':', 2)
if basicauth_user == sickbeard.WEB_USERNAME and basicauth_pass == sickbeard.WEB_PASSWORD:
if not handler.get_secure_cookie("user"):
handler.set_secure_cookie("user", str(time.time()))
return True
handler.clear_cookie("user")
get_auth()
@ -128,28 +126,12 @@ def require_basic_auth(handler_class):
handler_class._execute = wrap_execute(handler_class._execute)
return handler_class
@require_basic_auth
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.::
application = web.Application([
(r"/oldpath", web.RedirectHandler, {"url": "/newpath"}),
])
"""
def get(self, path):
def get(self, path, **kwargs):
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):
def __init__(self, application, request, **kwargs):
super(IndexHandler, self).__init__(application, request, **kwargs)
@ -171,10 +153,7 @@ class IndexHandler(RedirectHandler):
return args
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
path = self.request.uri.split('?')[0]
@ -469,6 +448,9 @@ class IndexHandler(RedirectHandler):
browser = WebFileBrowser
class LoginHandler(IndexHandler):
def get(self):
self.redirect(self.get_argument("next", u"/"))
class PageTemplate(Template):
def __init__(self, *args, **KWs):

View file

@ -10,6 +10,8 @@ from sickbeard.helpers import create_https_certificates
from tornado.web import Application, StaticFileHandler, RedirectHandler, HTTPError
from tornado.httpserver import HTTPServer
server = None
class MultiStaticFileHandler(StaticFileHandler):
def initialize(self, paths, default_filename=None):
self.paths = paths
@ -95,10 +97,11 @@ def initWebServer(options={}):
# Load the app
app = Application([],
debug=True,
log_function=lambda x: None,
debug=False,
gzip=True,
autoreload=True,
xheaders=False,
xheaders=True,
cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=',
login_url='/login'
)
@ -140,9 +143,12 @@ def initWebServer(options={}):
server.listen(options['port'], options['host'])
def shutdown():
global server
logger.log('Shutting down tornado')
try:
IOLoop.current().stop()
server.stop()
except RuntimeError:
pass
except: