Fixed issues with network timezone downloads crashing on a empty return.

Changed version checker url and moved code to Home class.
Fixed WebUI issues caused by calling redirect method.
Fixed update checking issues.
This commit is contained in:
echel0n 2014-12-12 11:45:32 -08:00
parent 35af9acadb
commit 979bf70f5c
4 changed files with 115 additions and 265 deletions

View File

@ -213,7 +213,7 @@
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><img src="$sbRoot/images/menu/system18-2.png" class="navbaricon hidden-xs" /><b class="caret hidden-xs"></b><span class="visible-xs">System <b class="caret"></b></span></a>
<ul class="dropdown-menu">
<li><a href="$sbRoot/home/forceVersionCheck"><i class="menu-icon-update"></i>&nbsp;Force Version Check</a></li>
<li><a href="$sbRoot/home/updateCheck?pid=$sbPID"><i class="menu-icon-update"></i>&nbsp;Check For Updates</a></li>
<li><a href="$sbRoot/home/restart/?pid=$sbPID" class="confirm restart"><i class="menu-icon-restart"></i>&nbsp;Restart</a></li>
<li><a href="$sbRoot/home/shutdown/?pid=$sbPID" class="confirm shutdown"><i class="menu-icon-shutdown"></i>&nbsp;Shutdown</a></li>
<li><a href="$sbRoot/logout" class="confirm logout"><i class="menu-icon-shutdown"></i>&nbsp;Logout</a></li>

View File

@ -1,4 +1,4 @@
var search_status_url = sbRoot + '/getManualSearchStatus';
var search_status_url = sbRoot + '/home/getManualSearchStatus';
PNotify.prototype.options.maxonscreen = 5;
$.fn.manualSearches = [];

View File

@ -22,13 +22,12 @@ import shutil
import subprocess
import re
import urllib
import zipfile
import tarfile
import stat
import traceback
import sickbeard
from sickbeard import helpers, notifiers
from sickbeard import notifiers
from sickbeard import ui
from sickbeard import logger
from sickbeard.exceptions import ex
@ -44,9 +43,7 @@ class CheckVersion():
if sickbeard.gh:
self.install_type = self.find_install_type()
if self.install_type == 'win':
self.updater = WindowsUpdateManager()
elif self.install_type == 'git':
if self.install_type == 'git':
self.updater = GitUpdateManager()
elif self.install_type == 'source':
self.updater = SourceUpdateManager()
@ -98,17 +95,26 @@ class CheckVersion():
logger.log(u"Version checking is disabled, not checking for the newest version")
return False
# checking for updates
if not sickbeard.AUTO_UPDATE:
logger.log(u"Checking if " + self.install_type + " needs an update")
logger.log(u"Checking for updates using " + self.install_type.upper())
if force:
ui.notifications.message("Checking for updates using " + self.install_type.upper())
if not self.updater.need_update():
sickbeard.NEWEST_VERSION_STRING = None
if not sickbeard.AUTO_UPDATE:
logger.log(u"No update needed")
if force:
ui.notifications.message('No update needed')
if force:
ui.notifications.message('No update needed')
# no updates needed
return False
# found updates
self.updater.set_newest_text()
return True
@ -140,159 +146,6 @@ class UpdateManager():
def get_update_url(self):
return sickbeard.WEB_ROOT + "/home/update/?pid=" + str(sickbeard.PID)
class WindowsUpdateManager(UpdateManager):
def __init__(self):
self.github_org = self.get_github_org()
self.github_repo = self.get_github_repo()
self.branch = sickbeard.BRANCH
if sickbeard.BRANCH == '':
self.branch = self._find_installed_branch()
self._cur_version = None
self._cur_commit_hash = None
self._newest_version = None
self.gc_url = 'http://code.google.com/p/sickbeard/downloads/list'
self.version_url = 'https://raw.github.com/' + self.github_org + '/' + self.github_repo + '/' + self.branch + '/updates.txt'
def _find_installed_version(self):
version = ''
try:
version = sickbeard.BRANCH
return int(version[6:])
except ValueError:
logger.log(u"Unknown SickRage Windows binary release: " + version, logger.ERROR)
return None
def _find_installed_branch(self):
return 'windows_binaries'
def _find_newest_version(self, whole_link=False):
"""
Checks git for the newest Windows binary build. Returns either the
build number or the entire build URL depending on whole_link's value.
whole_link: If True, returns the entire URL to the release. If False, it returns
only the build number. default: False
"""
regex = ".*SickRage\-win32\-alpha\-build(\d+)(?:\.\d+)?\.zip"
version_url_data = helpers.getURL(self.version_url)
if not version_url_data:
return
for curLine in version_url_data.splitlines():
logger.log(u"checking line " + curLine, logger.DEBUG)
match = re.match(regex, curLine)
if match:
logger.log(u"found a match", logger.DEBUG)
if whole_link:
return curLine.strip()
else:
return int(match.group(1))
def need_update(self):
if self.branch != self._find_installed_branch():
logger.log(u"Branch checkout: " + self._find_installed_branch() + "->" + self.branch, logger.DEBUG)
return True
self._cur_version = self._find_installed_version()
self._newest_version = self._find_newest_version()
logger.log(u"newest version: " + repr(self._newest_version), logger.DEBUG)
if self._newest_version and self._newest_version > self._cur_version:
return True
return False
def set_newest_text(self):
sickbeard.NEWEST_VERSION_STRING = None
if not self._cur_version:
newest_text = "Unknown SickRage Windows binary version. Not updating with original version."
else:
newest_text = 'There is a <a href="' + self.gc_url + '" onclick="window.open(this.href); return false;">newer version available</a> (build ' + str(
self._newest_version) + ')'
newest_text += "&mdash; <a href=\"" + self.get_update_url() + "\">Update Now</a>"
sickbeard.NEWEST_VERSION_STRING = newest_text
def update(self):
zip_download_url = self._find_newest_version(True)
logger.log(u"new_link: " + repr(zip_download_url), logger.DEBUG)
if not zip_download_url:
logger.log(u"Unable to find a new version link on google code, not updating")
return False
try:
# prepare the update dir
sr_update_dir = ek.ek(os.path.join, sickbeard.PROG_DIR, u'sr-update')
if os.path.isdir(sr_update_dir):
logger.log(u"Clearing out update folder " + sr_update_dir + " before extracting")
shutil.rmtree(sr_update_dir)
logger.log(u"Creating update folder " + sr_update_dir + " before extracting")
os.makedirs(sr_update_dir)
# retrieve file
logger.log(u"Downloading update from " + zip_download_url)
zip_download_path = os.path.join(sr_update_dir, u'sr-update.zip')
urllib.urlretrieve(zip_download_url, zip_download_path)
if not ek.ek(os.path.isfile, zip_download_path):
logger.log(u"Unable to retrieve new version from " + zip_download_url + ", can't update", logger.ERROR)
return False
if not ek.ek(zipfile.is_zipfile, zip_download_path):
logger.log(u"Retrieved version from " + zip_download_url + " is corrupt, can't update", logger.ERROR)
return False
# extract to sr-update dir
logger.log(u"Unzipping from " + str(zip_download_path) + " to " + sr_update_dir)
update_zip = zipfile.ZipFile(zip_download_path, 'r')
update_zip.extractall(sr_update_dir)
update_zip.close()
# delete the zip
logger.log(u"Deleting zip file from " + str(zip_download_path))
os.remove(zip_download_path)
# find update dir name
update_dir_contents = [x for x in os.listdir(sr_update_dir) if
os.path.isdir(os.path.join(sr_update_dir, x))]
if len(update_dir_contents) != 1:
logger.log(u"Invalid update data, update failed. Maybe try deleting your sr-update folder?",
logger.ERROR)
return False
content_dir = os.path.join(sr_update_dir, update_dir_contents[0])
old_update_path = os.path.join(content_dir, u'updater.exe')
new_update_path = os.path.join(sickbeard.PROG_DIR, u'updater.exe')
logger.log(u"Copying new update.exe file from " + old_update_path + " to " + new_update_path)
shutil.move(old_update_path, new_update_path)
# Notify update successful
notifiers.notify_git_update(sickbeard.NEWEST_VERSION_STRING)
except Exception, e:
logger.log(u"Error while trying to update: " + ex(e), logger.ERROR)
return False
return True
def list_remote_branches(self):
return ['windows_binaries']
class GitUpdateManager(UpdateManager):
def __init__(self):
self._git_path = self._find_working_git()

View File

@ -77,6 +77,7 @@ from Cheetah.Template import Template
from tornado.routes import route
from tornado.web import RequestHandler, HTTPError, authenticated, asynchronous, addslash
from tornado.gen import coroutine
from tornado.ioloop import IOLoop
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor
@ -84,6 +85,24 @@ from bug_tracker import BugTracker
route_locks = {}
class AsyncRunner(object):
@run_on_executor
def call(self, function, callback=None, **kwargs):
try:
result = function(**kwargs)
if callback:
callback(result)
return result
except:
logger.log('Failed doing webui callback: %s' % (traceback.format_exc()), logger.ERROR)
class ThreadedRunner(AsyncRunner):
def __init__(self, executor=ThreadPoolExecutor, max_workers=10):
self.io_loop = IOLoop.current()
self.executor = executor(max_workers)
def shutdown(self, wait=True):
self.executor.shutdown(wait)
class PageTemplate(Template):
def __init__(self, rh, *args, **kwargs):
@ -169,7 +188,7 @@ class BaseHandler(RequestHandler):
trace_info, request_info))
def redirect(self, url, permanent=True, status=None):
super(BaseHandler, self).redirect(sickbeard.WEB_ROOT + url, permanent, status)
return super(BaseHandler, self).redirect(sickbeard.WEB_ROOT + url, permanent, status)
def get_current_user(self, *args, **kwargs):
if not isinstance(self, UI) and sickbeard.WEB_USERNAME and sickbeard.WEB_PASSWORD:
@ -178,7 +197,7 @@ class BaseHandler(RequestHandler):
return True
class WebHandler(BaseHandler):
executor = ThreadPoolExecutor(10)
tr = ThreadedRunner(max_workers=50)
@coroutine
@asynchronous
@ -188,15 +207,23 @@ class WebHandler(BaseHandler):
route = route.strip('/').replace('.', '_') or 'index'
# get route
subclasses = self.__class__.__subclasses__()
#try:
method = getattr(self, route)
#except:
#try:
# subclasses = self.__class__.__subclasses__()
# method = [getattr(cls, route) for cls in subclasses if getattr(cls, route, None)][0]
#except:
# raise
try:
method = getattr(self, route)
except:
method = [getattr(cls, route) for cls in subclasses if getattr(cls, route, None)][0]
# query params
params = self.request.arguments
for arg, value in params.items():
if len(value) == 1:
params[arg] = value[0]
# process request async
self.async_worker(method, self.async_done)
self.tr.call(method, callback=self.finished, **params)
except:
logger.log('Failed doing webui request "%s": %s' % (route, traceback.format_exc()), logger.ERROR)
raise HTTPError(404)
@ -204,33 +231,19 @@ class WebHandler(BaseHandler):
def post(self, route, *args, **kwargs):
super(WebHandler, self).get(route, *args, **kwargs)
@run_on_executor
def async_worker(self, method, callback):
kwargs = self.request.arguments
for arg, value in kwargs.items():
if len(value) == 1:
kwargs[arg] = value[0]
def finished(self, results):
try:
res = method(**kwargs)
callback(res)
except:
logger.log('Failed doing webui callback: %s' % (traceback.format_exc()), logger.ERROR)
callback()
if results is not None:
try:
results = ek.ss(results).encode('utf-8', 'xmlcharrefreplace')
except:
results = str(results)
def async_done(self, result=None):
try:
result = ek.ss(result).encode('utf-8', 'xmlcharrefreplace')
except:
result = str(result)
try:
self.write(result)
self.finish()
self.write(results)
self.finish()
except:
logger.log('Failed sending webui reponse: %s' % (traceback.format_exc()), logger.DEBUG)
try:self.finish()
except:pass
self.finish()
def _genericMessage(self, subject, message):
t = PageTemplate(rh=self, file="genericMessage.tmpl")
@ -330,15 +343,15 @@ class KeyHandler(RequestHandler):
@route('(.*)(/?)')
class WebRoot(WebHandler):
def index(self, *args, **kwargs):
def index(self):
self.redirect('/home/')
def robots_txt(self, *args, **kwargs):
def robots_txt(self):
""" Keep web crawlers out """
self.set_header('Content-Type', 'text/plain')
return "User-agent: *\nDisallow: /"
def apibuilder(self, *args, **kwargs):
def apibuilder(self):
t = PageTemplate(rh=self, file="apiBuilder.tmpl")
def titler(x):
@ -453,7 +466,7 @@ class WebRoot(WebHandler):
self.redirect("/comingEpisodes/")
def toggleComingEpsDisplayPaused(self, *args, **kwargs):
def toggleComingEpsDisplayPaused(self):
sickbeard.COMING_EPS_DISPLAY_PAUSED = not sickbeard.COMING_EPS_DISPLAY_PAUSED
@ -557,7 +570,7 @@ class WebRoot(WebHandler):
#
# iCalendar (iCal) - Standard RFC 5545 <http://tools.ietf.org/html/rfc5546>
# Works with iCloud, Google Calendar and Outlook.
def calendar(self, *args, **kwargs):
def calendar(self):
""" Provides a subscribeable URL for iCal subscriptions
"""
@ -621,13 +634,13 @@ class WebRoot(WebHandler):
@route('/ui/(.*)(/?)')
class UI(WebRoot):
def add_message(self, *args, **kwargs):
def add_message(self):
ui.notifications.message('Test 1', 'This is test number 1')
ui.notifications.error('Test 2', 'This is test number 2')
return "ok"
def get_messages(self, *args, **kwargs):
def get_messages(self):
messages = {}
cur_notification_num = 1
for cur_notification in ui.notifications.get_notifications(self.request.remote_ip):
@ -661,12 +674,12 @@ class Home(WebRoot):
{'title': 'Manual Post-Processing', 'path': 'home/postprocess/'},
{'title': 'Update KODI', 'path': 'home/updateKODI/', 'requires': self.haveKODI},
{'title': 'Update Plex', 'path': 'home/updatePLEX/', 'requires': self.havePLEX},
{'title': 'Manage Torrents', 'path': 'manage/manageTorrents', 'requires': self.haveTORRENT},
{'title': 'Manage Torrents', 'path': 'manage/manageTorrents/', 'requires': self.haveTORRENT},
]
return menu
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="home.tmpl")
if sickbeard.ANIME_SPLIT_HOME:
shows = []
@ -787,7 +800,7 @@ class Home(WebRoot):
return "Error sending Pushover notification"
def twitterStep1(self, *args, **kwargs):
def twitterStep1(self):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
return notifiers.twitter_notifier._get_authorization()
@ -804,7 +817,7 @@ class Home(WebRoot):
return "Unable to verify key"
def testTwitter(self, *args, **kwargs):
def testTwitter(self):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
result = notifiers.twitter_notifier.test_notify()
@ -845,7 +858,7 @@ class Home(WebRoot):
return finalResult
def testLibnotify(self, *args, **kwargs):
def testLibnotify(self):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
if notifiers.libnotify_notifier.test_notify():
@ -906,7 +919,7 @@ class Home(WebRoot):
return notifiers.trakt_notifier.test_notify(api, username, password)
def loadShowNotifyLists(self, *args, **kwargs):
def loadShowNotifyLists(self):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
myDB = db.DBConnection()
@ -984,7 +997,6 @@ class Home(WebRoot):
return self._genericMessage(title, message)
def restart(self, pid=None):
if str(pid) != str(sickbeard.PID):
self.redirect("/home/")
return
@ -997,27 +1009,28 @@ class Home(WebRoot):
return t
def update(self, pid=None):
def updateCheck(self, pid=None):
if str(pid) != str(sickbeard.PID):
self.redirect("/home/")
return
self.redirect('/home/')
updated = sickbeard.versionCheckScheduler.action.update() # @UndefinedVariable
if updated:
sickbeard.versionCheckScheduler.action.check_for_new_version(force=True)
self.redirect('/home/')
def update(self, pid=None):
if str(pid) != str(sickbeard.PID):
self.redirect('/home/')
if sickbeard.versionCheckScheduler.action.update():
# do a hard restart
sickbeard.events.put(sickbeard.events.SystemEvent.RESTART)
t = PageTemplate(rh=self, file="restart_bare.tmpl")
return t
else:
if do_update:
return self._genericMessage("Update Failed",
"Update wasn't successful, not restarting. Check your log for more information.")
if force:
self.redirect("/home/")
def branchCheckout(self, branch):
sickbeard.BRANCH = branch
ui.notifications.message('Checking out branch: ', branch)
@ -1518,7 +1531,7 @@ class Home(WebRoot):
self.redirect('/home/')
def updatePLEX(self, *args, **kwargs):
def updatePLEX(self):
if notifiers.plex_notifier.update_library():
ui.notifications.message(
"Library update command sent to Plex Media Server host: " + sickbeard.PLEX_SERVER_HOST)
@ -1712,7 +1725,6 @@ class Home(WebRoot):
if eps is None:
self.redirect("/home/displayShow?show=" + show)
return
myDB = db.DBConnection()
for curEp in eps.split('|'):
@ -1963,7 +1975,7 @@ class Home(WebRoot):
@route('/home/postprocess/(.*)(/?)')
class HomePostProcess(Home):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="home_postprocess.tmpl")
t.submenu = self.HomeMenu()
return t
@ -2000,12 +2012,12 @@ class HomePostProcess(Home):
@route('/home/addShows/(.*)(/?)')
class HomeAddShows(Home):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="home_addShows.tmpl")
t.submenu = self.HomeMenu()
return t
def getIndexerLanguages(self, *args, **kwargs):
def getIndexerLanguages(self):
result = sickbeard.indexerApi().config['valid_languages']
# Make sure list is sorted alphabetically but 'en' is in front
@ -2182,7 +2194,7 @@ class HomeAddShows(Home):
return t
def recommendedShows(self, *args, **kwargs):
def recommendedShows(self):
"""
Display the new show page which collects a tvdb id, folder, and extra options and
posts them to addNewShow
@ -2192,7 +2204,7 @@ class HomeAddShows(Home):
return t
def getRecommendedShows(self, *args, **kwargs):
def getRecommendedShows(self):
final_results = []
logger.log(u"Getting recommended shows from Trakt.tv", logger.DEBUG)
@ -2232,7 +2244,7 @@ class HomeAddShows(Home):
anyQualities, bestQualities, flatten_folders, subtitles, fullShowPath, other_shows,
skipShow, providedIndexer, anime, scene)
def trendingShows(self, *args, **kwargs):
def trendingShows(self):
"""
Display the new show page which collects a tvdb id, folder, and extra options and
posts them to addNewShow
@ -2242,7 +2254,7 @@ class HomeAddShows(Home):
return t
def getTrendingShows(self, *args, **kwargs):
def getTrendingShows(self):
"""
Display the new show page which collects a tvdb id, folder, and extra options and
posts them to addNewShow
@ -2268,7 +2280,7 @@ class HomeAddShows(Home):
return t
def existingShows(self, *args, **kwargs):
def existingShows(self):
"""
Prints out the page to add existing shows from a root dir
"""
@ -2331,7 +2343,6 @@ class HomeAddShows(Home):
# if there are no extra shows then go home
if not other_shows:
self.redirect('/home/')
return
# peel off the next one
next_show_dir = other_shows[0]
@ -2357,7 +2368,6 @@ class HomeAddShows(Home):
logger.ERROR)
ui.notifications.error("Unknown error. Unable to add show due to problem with show selection.")
self.redirect('/home/addShows/existingShows/')
return
indexer = int(series_pieces[1])
indexer_id = int(series_pieces[3])
@ -2381,7 +2391,6 @@ class HomeAddShows(Home):
if ek.ek(os.path.isdir, show_dir) and not fullShowPath:
ui.notifications.error("Unable to add show", "Folder " + show_dir + " exists already")
self.redirect('/home/addShows/existingShows/')
return
# don't create show dir if config says not to
if sickbeard.ADD_SHOWS_WO_DIR:
@ -2393,7 +2402,6 @@ class HomeAddShows(Home):
ui.notifications.error("Unable to add show",
"Unable to create the folder " + show_dir + ", can't add the show")
self.redirect("/home/")
return
else:
helpers.chmodAsParent(show_dir)
@ -2499,7 +2507,6 @@ class HomeAddShows(Home):
# if we're done then go home
if not dirs_only:
self.redirect('/home/')
return
# for the remaining shows we need to prompt for each one, so forward this on to the newShow page
return self.newShow(dirs_only[0], dirs_only[1:])
@ -2526,7 +2533,7 @@ class Manage(WebRoot):
return menu
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="manage.tmpl")
t.submenu = self.ManageMenu()
return t
@ -2756,7 +2763,7 @@ class Manage(WebRoot):
self.redirect("/manage/backlogOverview/")
def backlogOverview(self, *args, **kwargs):
def backlogOverview(self):
t = PageTemplate(rh=self, file="manage_backlogOverview.tmpl")
t.submenu = self.ManageMenu()
@ -2805,7 +2812,6 @@ class Manage(WebRoot):
if not toEdit:
self.redirect("/manage/")
return
showIDs = toEdit.split("|")
showList = []
@ -3149,7 +3155,7 @@ class Manage(WebRoot):
self.redirect("/manage/")
def manageTorrents(self, *args, **kwargs):
def manageTorrents(self):
t = PageTemplate(rh=self, file="manage_torrents.tmpl")
t.info_download_station = ''
@ -3191,7 +3197,6 @@ class Manage(WebRoot):
if toRemove:
self.redirect('/manage/failedDownloads/')
return
t = PageTemplate(rh=self, file="manage_failedDownloads.tmpl")
t.failedResults = sqlResults
@ -3203,7 +3208,7 @@ class Manage(WebRoot):
@route('/manage/manageSearches/(.*)(/?)')
class ManageSearches(Manage):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="manage_manageSearches.tmpl")
# t.backlogPI = sickbeard.backlogSearchScheduler.action.getProgressIndicator()
t.backlogPaused = sickbeard.searchQueueScheduler.action.is_backlog_paused() # @UndefinedVariable
@ -3216,15 +3221,7 @@ class ManageSearches(Manage):
return t
def forceVersionCheck(self, *args, **kwargs):
# force a check to see if there is a new version
if sickbeard.versionCheckScheduler.action.check_for_new_version(force=True):
logger.log(u"Forcing version check")
self.redirect("/home/")
def forceBacklog(self, *args, **kwargs):
def forceBacklog(self):
# force it to run the next time it looks
result = sickbeard.backlogSearchScheduler.forceRun()
if result:
@ -3233,7 +3230,7 @@ class ManageSearches(Manage):
self.redirect("/manage/manageSearches/")
def forceSearch(self, *args, **kwargs):
def forceSearch(self):
# force it to run the next time it looks
result = sickbeard.dailySearchScheduler.forceRun()
@ -3244,7 +3241,7 @@ class ManageSearches(Manage):
self.redirect("/manage/manageSearches/")
def forceFindPropers(self, *args, **kwargs):
def forceFindPropers(self):
# force it to run the next time it looks
result = sickbeard.properFinderScheduler.forceRun()
@ -3337,7 +3334,7 @@ class History(WebRoot):
return t
def clearHistory(self, *args, **kwargs):
def clearHistory(self):
myDB = db.DBConnection()
myDB.action("DELETE FROM history WHERE 1=1")
@ -3346,7 +3343,7 @@ class History(WebRoot):
self.redirect("/history/")
def trimHistory(self, *args, **kwargs):
def trimHistory(self):
myDB = db.DBConnection()
myDB.action("DELETE FROM history WHERE date < " + str(
@ -3372,7 +3369,7 @@ class Config(WebRoot):
return menu
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config.tmpl")
t.submenu = self.ConfigMenu()
@ -3381,13 +3378,13 @@ class Config(WebRoot):
@route('/config/general/(.*)(/?)')
class ConfigGeneral(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_general.tmpl")
t.submenu = self.ConfigMenu()
return t
def generateApiKey(self, *args, **kwargs):
def generateApiKey(self):
return helpers.generateApiKey()
def saveRootDirs(self, rootDirString=None):
@ -3516,7 +3513,7 @@ class ConfigGeneral(Config):
@route('/config/backuprestore/(.*)(/?)')
class ConfigBackupRestore(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_backuprestore.tmpl")
t.submenu = self.ConfigMenu()
return t
@ -3564,7 +3561,7 @@ class ConfigBackupRestore(Config):
@route('/config/search/(.*)(/?)')
class ConfigSearch(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_search.tmpl")
t.submenu = self.ConfigMenu()
@ -3657,7 +3654,7 @@ class ConfigSearch(Config):
@route('/config/postProcessing/(.*)(/?)')
class ConfigPostProcessing(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_postProcessing.tmpl")
t.submenu = self.ConfigMenu()
@ -3837,7 +3834,7 @@ class ConfigPostProcessing(Config):
return "invalid"
def isRarSupported(self, *args, **kwargs):
def isRarSupported(self):
"""
Test Packing Support:
- Simulating in memory rar extraction on test.rar file
@ -3857,7 +3854,7 @@ class ConfigPostProcessing(Config):
@route('/config/providers/(.*)(/?)')
class ConfigProviders(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_providers.tmpl")
t.submenu = self.ConfigMenu()
return t
@ -4296,7 +4293,7 @@ class ConfigProviders(Config):
@route('/config/notifications/(.*)(/?)')
class ConfigNotifications(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_notifications.tmpl")
t.submenu = self.ConfigMenu()
return t
@ -4506,7 +4503,7 @@ class ConfigNotifications(Config):
@route('/config/subtitles/(.*)(/?)')
class ConfigSubtitles(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_subtitles.tmpl")
t.submenu = self.ConfigMenu()
return t
@ -4570,7 +4567,7 @@ class ConfigSubtitles(Config):
@route('/config/anime/(.*)(/?)')
class ConfigAnime(Config):
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="config_anime.tmpl")
t.submenu = self.ConfigMenu()
@ -4611,7 +4608,7 @@ class ErrorLogs(WebRoot):
return menu
def index(self, *args, **kwargs):
def index(self):
t = PageTemplate(rh=self, file="errorlogs.tmpl")
t.submenu = self.ErrorLogsMenu()
@ -4619,7 +4616,7 @@ class ErrorLogs(WebRoot):
return t
def clearerrors(self, *args, **kwargs):
def clearerrors(self):
classes.ErrorViewer.clear()
self.redirect("/errorlogs/")