mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 00:43:37 +00: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
8 changed files with 59 additions and 44 deletions
21
SickBeard.py
21
SickBeard.py
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue