1
0
mirror of https://github.com/moparisthebest/SickRage synced 2024-11-16 06:15:09 -05:00

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, added no cache header.
Fixed WebAPI builder issues with show.delete cmd.
Fixed article sorting for both WebAPI and WebUI.
This commit is contained in:
echel0n 2014-12-12 17:52:32 -08:00
parent 6c4bedcec0
commit 0209852af5
7 changed files with 124 additions and 267 deletions

View File

@ -1,48 +1,49 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>API Builder</title>
<script type="text/javascript" charset="utf-8">
<!--
sbRoot = "$sbRoot";
//-->
</script>
<script type="text/javascript" src="$sbRoot/js/lib/jquery-1.8.3.min.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/apibuilder.js?$sbPID"></script>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>SickRage - API Builder</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<meta name="robots" content="noindex">
<style type="text/css">
<!--
#apibuilder select { padding: 2px 2px 2px 6px; display: block; float: left; margin: auto 8px 4px auto;
}
#apibuilder select option { padding: 1px 6px; line-height: 1.2em; }
#apibuilder .disabled { color: #ccc; }
#apibuilder .action { background-color: #efefef; }
-->
</style>
<script type="text/javascript" charset="utf-8">
<!--
sbRoot = "$sbRoot";
//-->
</script>
<script type="text/javascript" src="$sbRoot/js/lib/jquery-1.7.2.min.js?$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/apibuilder.js?$sbPID"></script>
<style type="text/css">
<!--
#apibuilder select { padding: 2px 2px 2px 6px; display: block; float: left; margin: auto 8px 4px auto; }
#apibuilder select option { padding: 1px 6px; line-height: 1.2em; }
#apibuilder .disabled { color: #ccc; }
#apibuilder .action { background-color: #efefef; }
-->
</style>
<script type="text/javascript">
var hide_empty_list=true;
var hide_empty_list=true;
var disable_empty_list=true;
addListGroup("api", "Command");
addOption("Command", "SickBeard", "?cmd=sb", 1); //make default
addList("Command", "SickBeard.AddRootDir", "?cmd=sb.addrootdir", "sb.addrootdir", "", "", "action");
addOption("Command", "SickBeard.CheckScheduler", "?cmd=sb.checkscheduler", "", "", "action");
addList("Command", "SickBeard.DeleteRootDir", "?cmd=sb.deleterootdir", "sb.deleterootdir", "", "", "action");
addOption("Command", "SickBeard.ForceSearch", "?cmd=sb.forcesearch", "", "", "action");
addOption("Command", "SickBeard.GetDefaults", "?cmd=sb.getdefaults", "", "", "action");
addOption("Command", "SickBeard.GetMessages", "?cmd=sb.getmessages", "", "", "action");
addOption("Command", "SickBeard.GetRootDirs", "?cmd=sb.getrootdirs", "", "", "action");
addList("Command", "SickBeard.PauseBacklog", "?cmd=sb.pausebacklog", "sb.pausebacklog", "", "", "action");
addOption("Command", "SickBeard.Ping", "?cmd=sb.ping", "", "", "action");
addOption("Command", "SickBeard.Restart", "?cmd=sb.restart", "", "", "action");
addList("Command", "SickBeard.SearchAllIndexers", "?cmd=sb.searchindexers", "sb.searchindexers", "", "", "action");
addList("Command", "SickBeard.SearchTVDB", "?cmd=sb.searchtvdb&indexer=1", "sb.searchindexers", "", "", "action");
addList("Command", "SickBeard.SearchTVRage", "?cmd=sb.searchtvrage&indexer=2", "sb.searchindexers", "", "", "action");
addList("Command", "SickBeard.SetDefaults", "?cmd=sb.setdefaults", "sb.setdefaults", "", "", "action");
addOption("Command", "SickBeard.Shutdown", "?cmd=sb.shutdown", "", "", "action");
addOption("Command", "SickRage", "?cmd=sb", 1); //make default
addList("Command", "SickRage.AddRootDir", "?cmd=sb.addrootdir", "sb.addrootdir", "", "", "action");
addOption("Command", "SickRage.CheckScheduler", "?cmd=sb.checkscheduler", "", "", "action");
addList("Command", "SickRage.DeleteRootDir", "?cmd=sb.deleterootdir", "sb.deleterootdir", "", "", "action");
addOption("Command", "SickRage.ForceSearch", "?cmd=sb.forcesearch", "", "", "action");
addOption("Command", "SickRage.GetDefaults", "?cmd=sb.getdefaults", "", "", "action");
addOption("Command", "SickRage.GetMessages", "?cmd=sb.getmessages", "", "", "action");
addOption("Command", "SickRage.GetRootDirs", "?cmd=sb.getrootdirs", "", "", "action");
addList("Command", "SickRage.PauseBacklog", "?cmd=sb.pausebacklog", "sb.pausebacklog", "", "", "action");
addOption("Command", "SickRage.Ping", "?cmd=sb.ping", "", "", "action");
addOption("Command", "SickRage.Restart", "?cmd=sb.restart", "", "", "action");
addList("Command", "SickRage.searchindexers", "?cmd=sb.searchindexers", "sb.searchindexers", "", "", "action");
addList("Command", "SickRage.SetDefaults", "?cmd=sb.setdefaults", "sb.setdefaults", "", "", "action");
addOption("Command", "SickRage.Shutdown", "?cmd=sb.shutdown", "", "", "action");
addList("Command", "Coming Episodes", "?cmd=future", "future");
addList("Command", "Episode", "?cmd=episode", "episode");
addList("Command", "Episode.Search", "?cmd=episode.search", "episode.search", "", "", "action");
@ -51,16 +52,12 @@ addList("Command", "Scene Exceptions", "?cmd=exceptions", "exceptions");
addList("Command", "History", "?cmd=history", "history");
addOption("Command", "History.Clear", "?cmd=history.clear", "", "", "action");
addOption("Command", "History.Trim", "?cmd=history.trim", "", "", "action");
addList("Command", "Failed", "?cmd=failed", "failed");
addOption("Command", "Backlog", "?cmd=backlog");
addList("Command", "PostProcess", "?cmd=postprocess", "postprocess", "", "","action");
addList("Command", "Logs", "?cmd=logs", "logs");
addList("Command", "Show", "?cmd=show", "indexerid");
addList("Command", "Show.AddExisting", "?cmd=show.addexisting", "show.addexisting", "", "", "action");
addList("Command", "Show.AddNew", "?cmd=show.addnew", "show.addnew", "", "", "action");
addList("Command", "Show.Cache", "?cmd=show.cache", "indexerid", "", "", "action");
addList("Command", "Show.Delete", "?cmd=show.delete", "indexerid", "", "", "action");
addList("Command", "Show.Delete", "?cmd=show.delete", "show.delete", "", "", "action");
addList("Command", "Show.GetBanner", "?cmd=show.getbanner", "indexerid", "", "", "action");
addList("Command", "Show.GetPoster", "?cmd=show.getposter", "indexerid", "", "", "action");
addList("Command", "Show.GetQuality", "?cmd=show.getquality", "indexerid", "", "", "action");
@ -85,18 +82,6 @@ addOption("logs", "Info", "&min_level=info");
addOption("logs", "Warning", "&min_level=warning");
addOption("logs", "Error", "&min_level=error");
addOption("show.delete", "Optional Param", "", 1);
addOption("show.delete", "removefiles", "&removefiles=0");
addOption("show.delete", "removefiles", "&removefiles=1");
addOption("postprocess", "Optional Param", "", 1);
addOption("postprocess", "C:\\PATH\\TO\\DIR", "&path=C:\\Temp");
addOption("postprocess", "return_data", "&return_data=1");
addOption("postprocess", "force_replace", "&force_replace=1");
addOption("postprocess", "is_priority", "&is_priority=1");
addOption("postprocess", "process_method", "&process_method=copy");
addOption("postprocess", "type", "&type=manual")
addOption("sb.setdefaults", "Optional Param", "", 1);
addList("sb.setdefaults", "Exclude Paused Shows on ComingEps", "&future_show_paused=0", "sb.setdefaults-status");
addList("sb.setdefaults", "Include Paused Shows on ComingEps", "&future_show_paused=1", "sb.setdefaults-status");
@ -108,14 +93,14 @@ addList("sb.setdefaults-status", "Archived", "&status=archived", "sb.setdefaults
addList("sb.setdefaults-status", "Ignored", "&status=ignored", "sb.setdefaults-opt");
addOption("sb.setdefaults-opt", "Optional Param", "", 1);
addList("sb.setdefaults-opt", "No Season Folder", "&season_folder=0", "quality");
addList("sb.setdefaults-opt", "Use Season Folder", "&season_folder=1", "quality");
addList("sb.setdefaults-opt", "Flatten (No Season Folder)", "&flatten_folders=1", "quality");
addList("sb.setdefaults-opt", "Use Season Folder", "&flatten_folders=0", "quality");
addOption("shows", "Optional Param", "", 1);
addOption("shows", "Show Only Paused", "&paused=1");
addOption("shows", "Show Only Not Paused", "&paused=0");
addOption("shows", "Sort by Show Name", "&sort=name");
addOption("shows", "Sort by TVDB ID", "&sort=id");
addOption("shows", "Sort by INDEXER ID", "&sort=id");
addList("show.addexisting", "C:\\temp\\show1", "&location=C:\\temp\\show1", "show.addexisting-indexerid");
addList("show.addexisting", "D:\\Temp\\show2", "&location=D:\\Temp\\show2", "show.addexisting-indexerid");
@ -126,8 +111,8 @@ addList("show.addexisting-indexerid", "101501 (Ancient Aliens)", "&indexerid=101
addList("show.addexisting-indexerid", "80348 (Chuck)", "&indexerid=80348", "show.addexisting-opt");
addOption("show.addexisting-opt", "Optional Param", "", 1);
addList("show.addexisting-opt", "No Season Folder", "&season_folder=0", "quality");
addList("show.addexisting-opt", "Use Season Folder", "&season_folder=1", "quality");
addList("show.addexisting-opt", "Flatten (No Season Folder)", "&flatten_folders=1", "quality");
addList("show.addexisting-opt", "Use Season Folder", "&flatten_folders=0", "quality");
addList("show.addnew", "101501 (Ancient Aliens)", "&indexerid=101501", "show.addnew-loc");
addList("show.addnew", "80348 (Chuck)", "&indexerid=80348", "show.addnew-loc");
@ -145,8 +130,8 @@ addList("show.addnew-status", "Archived", "&status=archived", "show.addnew-opt")
addList("show.addnew-status", "Ignored", "&status=ignored", "show.addnew-opt");
addOption("show.addnew-opt", "Optional Param", "", 1);
addList("show.addnew-opt", "No Season Folder", "&season_folder=0", "quality");
addList("show.addnew-opt", "Use Season Folder", "&season_folder=1", "quality");
addList("show.addnew-opt", "Flatten (No Season Folder)", "&flatten_folders=1", "quality");
addList("show.addnew-opt", "Use Season Folder", "&flatten_folders=0", "quality");
addOptGroup("sb.searchindexers", "Search by Name");
addList("sb.searchindexers", "Lost", "&name=Lost", "sb.searchindexers-lang");
@ -283,15 +268,25 @@ addList("episode.setstatus", "$curShow.name", "&indexerid=$curShow.indexerid", "
// build out each show's season+episode list for episode.setstatus cmd
#for $curShow in $episodeSQLResults:
#set $curSeason = -1
#for $curShowSeason in $episodeSQLResults[$curShow]:
#if $curShowSeason.season != $curSeason and $curShowSeason.season != 0:
// insert just the season as the ep number is now optional
addList("episode.setstatus-$curShow", "Season $curShowSeason.season", "&season=$curShowSeason.season", "episode-status-$curShow");
#end if
#set $curSeason = int($curShowSeason.season)
addList("episode.setstatus-$curShow", "$curShowSeason.season x $curShowSeason.episode", "&season=$curShowSeason.season&episode=$curShowSeason.episode", "episode-status-$curShow");
#end for
addOption("episode-status-$curShow", "Wanted", "&status=wanted");
addOption("episode-status-$curShow", "Skipped", "&status=skipped");
addOption("episode-status-$curShow", "Archived", "&status=archived");
addOption("episode-status-$curShow", "Ignored", "&status=ignored");
addList("episode-status-$curShow", "Wanted", "&status=wanted", "force");
addList("episode-status-$curShow", "Skipped", "&status=skipped", "force");
addList("episode-status-$curShow", "Archived", "&status=archived", "force");
addList("episode-status-$curShow", "Ignored", "&status=ignored", "force");
#end for
addOption("force", "Optional Param", "", 1);
addOption("force", "Replace Downloaded EP", "&force=1");
addOption("force", "Skip Downloaded EP", "&force=0");
addOption("future", "Optional Param", "", 1);
addList("future", "Sort by Date", "&sort=date", "future-type");
addList("future", "Sort by Network", "&sort=network", "future-type");
@ -327,15 +322,6 @@ addOption("history-limit", "Optional Param", "", 1);
addOption("history-limit", "Show Only Downloaded", "&type=downloaded");
addOption("history-limit", "Show Only Snatched", "&type=snatched");
addOption("failed", "Optional Param", "", 1);
//addOptGroup("failed", "Limit Results");
addList("failed", "Limit Results (2)", "&limit=2", "failed-limit");
addList("failed", "Limit Results (25)", "&limit=25", "failed-limit");
addList("failed", "Limit Results (50)", "&limit=50", "failed-limit");
//endOptGroup("failed");
addOption("failed-limit", "Optional Param", "", 1);
addOption("exceptions", "Optional Param", "", 1);
#for $curShow in $sortedShowList:
addOption("exceptions", "$curShow.name", "&indexerid=$curShow.indexerid");
@ -364,6 +350,13 @@ addOption("show.pause-opt", "Optional Param", "", 1);
addOption("show.pause-opt", "Unpause", "&pause=0");
addOption("show.pause-opt", "Pause", "&pause=1");
#for $curShow in $sortedShowList:
addList("show.delete", "$curShow.name", "&indexerid=$curShow.indexerid", "show.delete-opt");
#end for
addOption("show.delete-opt", "Optional Param", "", 1);
addOption("show.delete-opt", "Remove Files", "&removefiles=1");
addOption("show.delete-opt", "Don't Remove Files", "&removefiles=0");
</script>
</head>
@ -390,8 +383,8 @@ addOption("show.pause-opt", "Pause", "&pause=1");
<select name="sixthlevel"><option></option></select>
<select name="seventhlevel"><option></option></select>
<div style="float: left; ">
<input class="btn" type="button" value="Reset" onclick="resetListGroup('api',1)" />
<input class="btn" type="button" value="Go" onclick="goListGroup(this.form['apikey'].value, this.form['seventhlevel'].value, this.form['sixthlevel'].value, this.form['fifthlevel'].value, this.form['forthlevel'].value, this.form['thirdlevel'].value, this.form['secondlevel'].value, this.form['firstlevel'].value)" />
<input type="button" value="Reset" onclick="resetListGroup('api',1)" />
<input type="button" value="Go" onclick="goListGroup(this.form['apikey'].value, this.form['seventhlevel'].value, this.form['sixthlevel'].value, this.form['fifthlevel'].value, this.form['forthlevel'].value, this.form['thirdlevel'].value, this.form['secondlevel'].value, this.form['firstlevel'].value)" />
</div>
</td>
</tr>
@ -402,4 +395,4 @@ addOption("show.pause-opt", "Pause", "&pause=1");
</body>
</html>
</html>

View File

@ -244,7 +244,7 @@
</tr>
#end if
<tr><td class="showLegend">Size:</td><td>$sickbeard.helpers.human(sickbeard.helpers.get_size($showLoc[0]))</td></tr>
<tr><td class="showLegend">Size:</td><td>$sickbeard.helpers.pretty_filesize(sickbeard.helpers.get_size($showLoc[0]))</td></tr>
</table>

View File

@ -11,16 +11,16 @@ var _disable_empty_list=false;
var _hide_empty_list=false;
function goListGroup(apikey, L7, L6, L5, L4, L3, L2, L1){
var GlobalOptions = "";
var html, GlobalOptions = "";
$('.global').each(function(){
var checked = $(this).prop('checked');
if(checked) {
var globalID = $(this).attr('id');
// handle jsonp/callback global option differently
if(globalID == "jsonp") {
GlobalOptions = GlobalOptions + "&" + globalID + "=foo";
GlobalOptions = GlobalOptions + "&" + globalID + "=foo";
} else {
GlobalOptions = GlobalOptions + "&" + globalID + "=1";
GlobalOptions = GlobalOptions + "&" + globalID + "=1";
}
}
});
@ -28,7 +28,7 @@ function goListGroup(apikey, L7, L6, L5, L4, L3, L2, L1){
// handle the show.getposter / show.getbanner differently as they return an image and not json
if (L1 == "?cmd=show.getposter" || L1 == "?cmd=show.getbanner") {
var imgcache = sbRoot + "/api/" + apikey + "/" + L1 + L2 + GlobalOptions;
var html = imgcache + '<br/><br/><img src="' + sbRoot + '/images/loading16.gif" id="imgcache">';
html = imgcache + '<br/><br/><img src="' + sbRoot + '/images/loading16.gif" id="imgcache">';
$('#apiResponse').html(html);
$.ajax({
url: sbRoot + "/api/" + apikey + "/" + L1 + L2 + GlobalOptions,
@ -38,10 +38,10 @@ function goListGroup(apikey, L7, L6, L5, L4, L3, L2, L1){
success: function (img) {
$('#imgcache').attr('src', imgcache);
}
})
});
}
else {
var html = sbRoot + "/api/" + apikey + "/" + L1 + L2 + L3 + L4 + L5 + L6 + L7 + GlobalOptions + "<br/><pre>";
html = sbRoot + "/api/" + apikey + "/" + L1 + L2 + L3 + L4 + L5 + L6 + L7 + GlobalOptions + "<br/><pre>";
html += $.ajax({
url: sbRoot + "/api/" + apikey + "/" + L1 + L2 + L3 + L4 + L5 + L6 + L7 + GlobalOptions,
async: false,
@ -189,13 +189,13 @@ function cs_getCookie(name) {
function cs_optionOBJ(type,text,value,label,css) { this.type=type; this.text=text; this.value=value; this.label=label; this.css=css; }
function cs_getOptions(menu,list) {
var opt=new Array();
var opt=[];
for (var i=0; i<menu.items.length; i++) {
opt[i]=new cs_optionOBJ(menu.items[i].type, menu.items[i].dis, menu.items[i].link, menu.items[i].label, menu.items[i].css);
}
if (opt.length==0 && menu.name!="") {
cs_getSubList(menu.name,list);
opt[0]=new cs_optionOBJ(cs_L, "loading ...", "", "", "");
//opt[0]=new cs_optionOBJ(cs_L, "loading ...", "", "", "");
}
return opt;
}
@ -638,4 +638,4 @@ function selectOptions(n,opts,mode) {
}
}
}
// ------
// ------

View File

@ -43,18 +43,6 @@ import adba
import requests
import requests.exceptions
try:
import json
except ImportError:
from lib import simplejson as json
try:
import xml.etree.cElementTree as etree
except ImportError:
import elementtree.ElementTree as etree
from xml.dom.minidom import Node
from sickbeard.exceptions import MultipleShowObjectsException, ex
from sickbeard import logger, classes
from sickbeard.common import USER_AGENT, mediaExtensions, subtitleExtensions
@ -659,12 +647,11 @@ def get_all_episodes_from_absolute_number(show, absolute_numbers, indexer_id=Non
if not show and indexer_id:
show = findCertainShow(sickbeard.showList, indexer_id)
if show:
for absolute_number in absolute_numbers:
ep = show.getEpisode(None, None, absolute_number=absolute_number)
if ep:
episodes.append(ep.episode)
season = ep.season # this will always take the last found seson so eps that cross the season border are not handeled well
for absolute_number in absolute_numbers if show else []:
ep = show.getEpisode(None, None, absolute_number=absolute_number)
if ep:
episodes.append(ep.episode)
season = ep.season # this will always take the last found seson so eps that cross the season border are not handeled well
return (season, episodes)
@ -733,79 +720,6 @@ def create_https_certificates(ssl_cert, ssl_key):
return True
if __name__ == '__main__':
import doctest
doctest.testmod()
def parse_json(data):
"""
Parse json data into a python object
data: data string containing json
Returns: parsed data as json or None
"""
try:
parsedJSON = json.loads(data)
except ValueError, e:
logger.log(u"Error trying to decode json data. Error: " + ex(e), logger.DEBUG)
return None
return parsedJSON
def parse_xml(data, del_xmlns=False):
"""
Parse data into an xml elementtree.ElementTree
data: data string containing xml
del_xmlns: if True, removes xmlns namesspace from data before parsing
Returns: parsed data as elementtree or None
"""
if del_xmlns:
data = re.sub(' xmlns="[^"]+"', '', data)
try:
parsedXML = etree.fromstring(data)
except Exception, e:
logger.log(u"Error trying to parse xml data. Error: " + ex(e), logger.DEBUG)
parsedXML = None
return parsedXML
def get_xml_text(element, mini_dom=False):
"""
Get all text inside a xml element
element: A xml element either created with elementtree.ElementTree or xml.dom.minidom
mini_dom: Default False use elementtree, True use minidom
Returns: text
"""
text = ""
if mini_dom:
node = element
for child in node.childNodes:
if child.nodeType in (Node.CDATA_SECTION_NODE, Node.TEXT_NODE):
text += child.data
else:
if element is not None:
for child in [element] + element.findall('.//*'):
if child.text:
text += child.text
return text.strip()
def backupVersionedFile(old_file, version):
numTries = 0
@ -1397,32 +1311,6 @@ def clearCache(force=False):
logger.WARNING)
break
def human(size):
"""
format a size in bytes into a 'human' file size, e.g. bytes, KB, MB, GB, TB, PB
Note that bytes/KB will be reported in whole numbers but MB and above will have greater precision
e.g. 1 byte, 43 bytes, 443 KB, 4.3 MB, 4.43 GB, etc
"""
if size == 1:
# because I really hate unnecessary plurals
return "1 byte"
suffixes_table = [('bytes', 0), ('KB', 0), ('MB', 1), ('GB', 2),('TB', 2), ('PB', 2)]
num = float(size)
for suffix, precision in suffixes_table:
if num < 1024.0:
break
num /= 1024.0
if precision == 0:
formatted_size = "%d" % num
else:
formatted_size = str(round(num, ndigits=precision))
return "%s %s" % (formatted_size, suffix)
def get_size(start_path='.'):
total_size = 0
@ -1432,11 +1320,7 @@ def get_size(start_path='.'):
total_size += ek.ek(os.path.getsize, fp)
return total_size
def md5(text):
return hashlib.md5(ek.ss(text)).hexdigest()
def generateApiKey(*args, **kwargs):
def generateApiKey():
""" Return a new randomized API_KEY
"""
@ -1475,4 +1359,12 @@ def pretty_filesize(file_bytes):
size = '%.2f KB' % kilobytes
else:
size = '%.2f b' % file_bytes
return size
return size
if __name__ == '__main__':
import doctest
doctest.testmod()
def remove_article(text=''):
return re.sub(r'(?i)/^(?:(?:A(?!\s+to)n?)|The)\s(\w)', r'\1', text)

View File

@ -120,14 +120,14 @@ class NewznabProvider(generic.NZBProvider):
params['apikey'] = self.key
try:
categories = self.getURL("%s/api" % (self.url), params=params, timeout=10)
xml_categories = self.getURL("%s/api" % (self.url), params=params, timeout=10, json=True)
except:
logger.log(u"Error getting html for [%s]" %
("%s/api?%s" % (self.url, '&'.join("%s=%s" % (x,y) for x,y in params.items())) ), logger.DEBUG)
return (False, return_categories, "Error getting html for [%s]" %
("%s/api?%s" % (self.url, '&'.join("%s=%s" % (x,y) for x,y in params.items()) )))
xml_categories = helpers.parse_xml(categories)
#xml_categories = helpers.parse_xml(categories)
if not xml_categories:
logger.log(u"Error parsing xml for [%s]" % (self.name),

View File

@ -36,8 +36,8 @@ from sickbeard import classes
from sickbeard import processTV
from sickbeard import network_timezones, sbdatetime
from sickbeard.exceptions import ex
from sickbeard.common import SNATCHED, SNATCHED_PROPER, DOWNLOADED, SKIPPED, UNAIRED, IGNORED, ARCHIVED, WANTED, UNKNOWN
from common import Quality, Overview, qualityPresetStrings, statusStrings
from sickbeard.common import Quality, Overview, qualityPresetStrings, statusStrings, SNATCHED, SNATCHED_PROPER, DOWNLOADED, SKIPPED, UNAIRED, IGNORED, ARCHIVED, WANTED, UNKNOWN
from sickbeard.webserve import WebRoot
try:
import json
@ -322,12 +322,12 @@ class ApiCall(ApiHandler):
if required:
try:
self._missing
self._requiredParams.append(key)
self._requiredParams += [key]
except AttributeError:
self._missing = []
self._requiredParams = {}
self._requiredParams[key] = {"allowedValues": allowedValues,
"defaultValue": orgDefault}
self._requiredParams = {key: {"allowedValues": allowedValues,
"defaultValue": orgDefault}}
if missing and key not in self._missing:
self._missing.append(key)
else:
@ -2291,7 +2291,7 @@ class CMD_ShowGetPoster(ApiCall):
def run(self):
""" get the poster for a show in sickrage """
return {'outputType': 'image', 'image': self.showPoster(self.indexerid, 'poster')}
return {'outputType': 'image', 'image': WebRoot().showPoster(self.indexerid, 'poster')}
class CMD_ShowGetBanner(ApiCall):
@ -2314,7 +2314,7 @@ class CMD_ShowGetBanner(ApiCall):
def run(self):
""" get the banner for a show in sickrage """
return {'outputType': 'image', 'image': self.handler.showPoster(self.indexerid, 'banner')}
return {'outputType': 'image', 'image': WebRoot().showPoster(self.indexerid, 'banner')}
class CMD_ShowPause(ApiCall):

View File

@ -17,7 +17,6 @@
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
from __future__ import with_statement
import inspect
import traceback
import os
@ -27,7 +26,6 @@ import re
import datetime
import sickbeard
from sickbeard import config, sab
from sickbeard import clients
from sickbeard import history, notifiers, processTV
@ -41,7 +39,6 @@ from sickbeard import scene_exceptions
from sickbeard import subtitles
from sickbeard import network_timezones
from sickbeard import sbdatetime
from sickbeard.providers import newznab, rsstorrent
from sickbeard.common import Quality, Overview, statusStrings, qualityPresetStrings, cpu_presets
from sickbeard.common import SNATCHED, UNAIRED, IGNORED, ARCHIVED, WANTED, FAILED
@ -56,9 +53,7 @@ from sickbeard.scene_numbering import get_scene_numbering, set_scene_numbering,
from lib.dateutil import tz
from lib.unrar2 import RarFile
from lib import adba, subliminal
from lib.trakt import TraktAPI
from lib.trakt.exceptions import traktException, traktAuthException, traktServerBusy
@ -75,14 +70,12 @@ except ImportError:
from Cheetah.Template import Template
from tornado.routes import route
from tornado.web import RequestHandler, HTTPError, authenticated, asynchronous, addslash
from tornado.web import RequestHandler, HTTPError, authenticated, asynchronous
from tornado.gen import coroutine
from tornado.ioloop import IOLoop
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor
from bug_tracker import BugTracker
route_locks = {}
class PageTemplate(Template):
@ -135,6 +128,9 @@ class PageTemplate(Template):
class BaseHandler(RequestHandler):
def __init__(self, *args, **kwargs):
super(BaseHandler, self).__init__(*args, **kwargs)
def write_error(self, status_code, **kwargs):
# handle 404 http errors
if status_code == 404:
@ -186,33 +182,24 @@ class WebHandler(BaseHandler):
@authenticated
def get(self, route, *args, **kwargs):
try:
# route -> method obj
route = route.strip('/').replace('.', '_') or 'index'
# get route
#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
# 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_call(method, callback=self.async_done, **params)
self.async_call(method, callback=self.async_done)
except:
logger.log('Failed doing webui request "%s": %s' % (route, traceback.format_exc()), logger.ERROR)
raise HTTPError(404)
@run_on_executor
def async_call(self, function, callback=None, **kwargs):
def async_call(self, function, callback=None):
try:
kwargs = self.request.arguments
for arg, value in kwargs.items():
if len(value) == 1:
kwargs[arg] = value[0]
result = function(**kwargs)
if callback:
callback(result)
@ -236,7 +223,7 @@ class WebHandler(BaseHandler):
def _genericMessage(self, subject, message):
t = PageTemplate(rh=self, file="genericMessage.tmpl")
t.submenu = self.HomeMenu()
t.submenu = Home().HomeMenu()
t.subject = subject
t.message = message
return t
@ -347,22 +334,15 @@ class WebRoot(WebHandler):
t = PageTemplate(rh=self, file="apiBuilder.tmpl")
def titler(x):
if not x or sickbeard.SORT_ARTICLE:
return x
if x.lower().startswith('a '):
x = x[2:]
elif x.lower().startswith('an '):
x = x[3:]
elif x.lower().startswith('the '):
x = x[4:]
return x
return (helpers.remove_article(x), x)[not x or sickbeard.SORT_ARTICLE]
t.sortedShowList = sorted(sickbeard.showList, lambda x, y: cmp(titler(x.name), titler(y.name)))
myDB = db.DBConnection(row_type="dict")
seasonSQLResults = {}
episodeSQLResults = {}
myDB = db.DBConnection(row_type="dict")
for curShow in t.sortedShowList:
seasonSQLResults[curShow.indexerid] = myDB.select(
"SELECT DISTINCT season FROM tv_episodes WHERE showid = ? ORDER BY season DESC", [curShow.indexerid])
@ -1117,15 +1097,7 @@ class Home(WebRoot):
epCounts[curEpCat] += 1
def titler(x):
if not x or sickbeard.SORT_ARTICLE:
return x
if x.lower().startswith('a '):
x = x[2:]
if x.lower().startswith('an '):
x = x[3:]
elif x.lower().startswith('the '):
x = x[4:]
return x
return (helpers.remove_article(x), x)[not x or sickbeard.SORT_ARTICLE]
if sickbeard.ANIME_SPLIT_HOME:
shows = []
@ -3155,7 +3127,7 @@ class Manage(WebRoot):
if re.search('localhost', sickbeard.TORRENT_HOST):
if not sickbeard.LOCALHOST_IP:
if sickbeard.LOCALHOST_IP == '':
t.webui_url = re.sub('localhost', helpers.get_lan_ip(), sickbeard.TORRENT_HOST)
else:
t.webui_url = re.sub('localhost', sickbeard.LOCALHOST_IP, sickbeard.TORRENT_HOST)