mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-12 11:02:21 -05:00
Improved async threading code for WebUI
This commit is contained in:
parent
d2b6145f8c
commit
46bd600da0
@ -17,8 +17,8 @@
|
||||
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import with_statement
|
||||
import threading
|
||||
|
||||
import threading
|
||||
import traceback
|
||||
import os
|
||||
import time
|
||||
@ -75,11 +75,31 @@ except ImportError:
|
||||
|
||||
from Cheetah.Template import Template
|
||||
|
||||
from functools import wraps
|
||||
from tornado.routes import route
|
||||
from tornado.web import RequestHandler, authenticated, asynchronous
|
||||
|
||||
from bug_tracker import BugTracker
|
||||
|
||||
route_locks = {}
|
||||
|
||||
def run_async(func):
|
||||
@wraps(func)
|
||||
def async_func(*args, **kwargs):
|
||||
func_hl = threading.Thread(target = func, args = args, kwargs = kwargs)
|
||||
func_hl.start()
|
||||
|
||||
return async_func
|
||||
|
||||
@run_async
|
||||
def run_handler(route, kwargs, callback = None):
|
||||
try:
|
||||
res = route(**kwargs)
|
||||
callback(res, route)
|
||||
except:
|
||||
logger.log('Failed doing api request "%s": %s' % (route, traceback.format_exc()), logger.ERROR)
|
||||
callback({'success': False, 'error': 'Failed returning results'}, route)
|
||||
|
||||
def page_not_found(rh):
|
||||
index_url = sickbeard.WEB_ROOT
|
||||
url = rh.request.uri[len(index_url):]
|
||||
@ -91,23 +111,6 @@ def page_not_found(rh):
|
||||
rh.set_status(404)
|
||||
rh.write('Wrong API key used')
|
||||
|
||||
class Worker(threading.Thread):
|
||||
def __init__(self, func, params=None, callback=None, *args, **kwargs):
|
||||
super(Worker, self).__init__(*args, **kwargs)
|
||||
self.callback = callback
|
||||
self.func = func
|
||||
self.params = params
|
||||
|
||||
def run(self):
|
||||
# Get response
|
||||
resp = self.func(**self.params)
|
||||
if resp:
|
||||
# Issue callback
|
||||
try:
|
||||
self.callback(ek.ss(resp).encode('utf-8', 'xmlcharrefreplace'))
|
||||
except:
|
||||
self.callback(resp)
|
||||
|
||||
class PageTemplate(Template):
|
||||
def __init__(self, rh, *args, **kwargs):
|
||||
kwargs['file'] = os.path.join(sickbeard.PROG_DIR, "gui/" + sickbeard.GUI_NAME + "/interfaces/default/", kwargs['file'])
|
||||
@ -260,31 +263,52 @@ class WebHandler(BaseHandler):
|
||||
route = route.strip('/')
|
||||
|
||||
try:
|
||||
route = getattr(self, route, self.index)
|
||||
if not callable(route):
|
||||
self.set_status(404)
|
||||
self.write('Could not load webui module')
|
||||
return
|
||||
route = getattr(self, route)
|
||||
except:
|
||||
page_not_found(self)
|
||||
return
|
||||
route = getattr(self, 'index')
|
||||
|
||||
# Sanitize argument lists:
|
||||
params = self.request.arguments
|
||||
for arg, value in params.items():
|
||||
if len(value) == 1:
|
||||
params[arg] = value[0]
|
||||
# acquire route lock
|
||||
route_locks[route] = threading.Lock()
|
||||
route_locks[route].acquire()
|
||||
|
||||
Worker(route, params, self.worker_done).start()
|
||||
|
||||
def worker_done(self, value):
|
||||
try:
|
||||
self.write(value)
|
||||
|
||||
# Sanitize argument lists:
|
||||
kwargs = self.request.arguments
|
||||
for arg, value in kwargs.items():
|
||||
if len(value) == 1:
|
||||
kwargs[arg] = value[0]
|
||||
|
||||
run_handler(route, kwargs, callback=self.taskFinished)
|
||||
except:
|
||||
route_locks[route].release()
|
||||
page_not_found(self)
|
||||
|
||||
def taskFinished(self, result, route):
|
||||
try:
|
||||
if result:
|
||||
# encode result data
|
||||
result = ek.ss(result).encode('utf-8', 'xmlcharrefreplace')
|
||||
|
||||
# Check JSONP callback
|
||||
jsonp_callback = self.get_argument('callback_func', default=None)
|
||||
|
||||
if jsonp_callback:
|
||||
self.write(str(jsonp_callback) + '(' + json.dumps(result) + ')')
|
||||
self.set_header("Content-Type", "text/javascript")
|
||||
self.finish()
|
||||
else:
|
||||
self.write(result)
|
||||
self.finish()
|
||||
except UnicodeDecodeError:
|
||||
logger.log('Failed proper encode: %s' % traceback.format_exc(), logger.ERROR)
|
||||
except:
|
||||
logger.log("Failed doing web request '%s': %s" % (route, traceback.format_exc()), logger.ERROR)
|
||||
self.write({'success': False, 'error': 'Failed returning results'})
|
||||
try:self.finish({'success': False, 'error': 'Failed returning results'})
|
||||
except:pass
|
||||
|
||||
self.finish()
|
||||
# release route lock
|
||||
route_locks[route].release()
|
||||
|
||||
# link post to get
|
||||
post = get
|
||||
|
@ -12,6 +12,7 @@ from tornado.httpserver import HTTPServer
|
||||
from tornado.ioloop import IOLoop
|
||||
from tornado.routes import route
|
||||
|
||||
|
||||
class MultiStaticFileHandler(StaticFileHandler):
|
||||
def initialize(self, paths, default_filename=None):
|
||||
self.paths = paths
|
||||
@ -76,7 +77,7 @@ class SRWebServer(threading.Thread):
|
||||
if self.enable_https:
|
||||
# If either the HTTPS certificate or key do not exist, make some self-signed ones.
|
||||
if not (self.https_cert and os.path.exists(self.https_cert)) or not (
|
||||
self.https_key and os.path.exists(self.https_key)):
|
||||
self.https_key and os.path.exists(self.https_key)):
|
||||
if not create_https_certificates(self.https_cert, self.https_key):
|
||||
logger.log(u"Unable to create CERT/KEY files, disabling HTTPS")
|
||||
sickbeard.ENABLE_HTTPS = False
|
||||
@ -101,9 +102,10 @@ class SRWebServer(threading.Thread):
|
||||
self.app.add_handlers(".*$", [
|
||||
(r'%s(/?)' % self.options['api_root'], ApiHandler),
|
||||
(r'%s/getkey(/?)' % self.options['web_root'], KeyHandler),
|
||||
(r'%s/api/builder' % self.options['web_root'], RedirectHandler, {"url": self.options['web_root'] + '/apibuilder/'}),
|
||||
(r'%s/api/builder' % self.options['web_root'], RedirectHandler,
|
||||
{"url": self.options['web_root'] + '/apibuilder/'}),
|
||||
(r'%s/login(/?)' % self.options['web_root'], LoginHandler),
|
||||
(r'%s/logout(/?)' % self.options['web_root'], LogoutHandler)
|
||||
(r'%s/logout(/?)' % self.options['web_root'], LogoutHandler),
|
||||
] + route.get_routes())
|
||||
|
||||
# Static Path Handlers
|
||||
|
Loading…
Reference in New Issue
Block a user