mirror of
https://github.com/moparisthebest/SickRage
synced 2025-01-05 19:08:02 -05:00
Merge pull request #801 from KontiSR/dev_manual_search2
Enhancement to Manual searching and Gui queuing of manual searches
This commit is contained in:
commit
026c456e0d
BIN
gui/slick/images/queued.png
Normal file
BIN
gui/slick/images/queued.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 466 B |
@ -411,9 +411,9 @@
|
|||||||
<td class="search">
|
<td class="search">
|
||||||
#if int($epResult["season"]) != 0:
|
#if int($epResult["season"]) != 0:
|
||||||
#if ( int($epResult["status"]) in $Quality.SNATCHED or int($epResult["status"]) in $Quality.DOWNLOADED ) and $sickbeard.USE_FAILED_DOWNLOADS:
|
#if ( int($epResult["status"]) in $Quality.SNATCHED or int($epResult["status"]) in $Quality.DOWNLOADED ) and $sickbeard.USE_FAILED_DOWNLOADS:
|
||||||
<a class="epRetry" href="retryEpisode?show=$show.indexerid&season=$epResult["season"]&episode=$epResult["episode"]"><img src="$sbRoot/images/search32.png" height="16" alt="retry" title="Retry Download" /></a>
|
<a class="epRetry" id="<%=str(epResult["season"])+'x'+str(epResult["episode"])%>" name="<%=str(epResult["season"]) +"x"+str(epResult["episode"]) %>" href="retryEpisode?show=$show.indexerid&season=$epResult["season"]&episode=$epResult["episode"]"><img src="$sbRoot/images/search32.png" height="16" alt="retry" title="Retry Download" /></a>
|
||||||
#else:
|
#else:
|
||||||
<a class="epSearch" href="searchEpisode?show=$show.indexerid&season=$epResult["season"]&episode=$epResult["episode"]"><img src="$sbRoot/images/search32.png" width="16" height="16" alt="search" title="Manual Search" /></a>
|
<a class="epSearch" id="<%=str(epResult["season"])+'x'+str(epResult["episode"])%>" name="<%=str(epResult["season"]) +"x"+str(epResult["episode"]) %>" href="searchEpisode?show=$show.indexerid&season=$epResult["season"]&episode=$epResult["episode"]"><img src="$sbRoot/images/search32.png" width="16" height="16" alt="search" title="Manual Search" /></a>
|
||||||
#end if
|
#end if
|
||||||
#end if
|
#end if
|
||||||
#if $sickbeard.USE_SUBTITLES and $show.subtitles and len(set(str($epResult["subtitles"]).split(',')).intersection(set($subtitles.wantedLanguages()))) < len($subtitles.wantedLanguages()) and $epResult["location"]
|
#if $sickbeard.USE_SUBTITLES and $show.subtitles and len(set(str($epResult["subtitles"]).split(',')).intersection(set($subtitles.wantedLanguages()))) < len($subtitles.wantedLanguages()) and $epResult["location"]
|
||||||
|
@ -1,3 +1,112 @@
|
|||||||
|
var search_status_url = sbRoot + '/getManualSearchStatus';
|
||||||
|
$.pnotify.defaults.width = "400px";
|
||||||
|
$.pnotify.defaults.styling = "jqueryui";
|
||||||
|
$.pnotify.defaults.history = false;
|
||||||
|
$.pnotify.defaults.shadow = false;
|
||||||
|
$.pnotify.defaults.delay = 4000;
|
||||||
|
$.pnotify.defaults.maxonscreen = 5;
|
||||||
|
|
||||||
|
$.fn.manualSearches = [];
|
||||||
|
|
||||||
|
function check_manual_searches() {
|
||||||
|
var poll_interval = 5000;
|
||||||
|
$.ajax({
|
||||||
|
url: search_status_url + '?show=' + $('#showID').val(),
|
||||||
|
success: function (data) {
|
||||||
|
if (data.episodes) {
|
||||||
|
poll_interval = 5000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
poll_interval = 15000;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateImages(data);
|
||||||
|
//cleanupManualSearches(data);
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
poll_interval = 30000;
|
||||||
|
},
|
||||||
|
type: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function () {
|
||||||
|
setTimeout(check_manual_searches, poll_interval);
|
||||||
|
},
|
||||||
|
timeout: 15000 // timeout every 15 secs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateImages(data) {
|
||||||
|
$.each(data.episodes, function (name, ep) {
|
||||||
|
console.debug(ep.searchstatus);
|
||||||
|
// Get td element for current ep
|
||||||
|
var loadingImage = 'loading16_dddddd.gif';
|
||||||
|
var queuedImage = 'queued.png';
|
||||||
|
var searchImage = 'search32.png';
|
||||||
|
var status = null;
|
||||||
|
//Try to get the <a> Element
|
||||||
|
el=$('a[id=' + ep.season + 'x' + ep.episode+']');
|
||||||
|
img=el.children('img');
|
||||||
|
parent=el.parent();
|
||||||
|
if (el) {
|
||||||
|
if (ep.searchstatus == 'searching') {
|
||||||
|
//el=$('td#' + ep.season + 'x' + ep.episode + '.search img');
|
||||||
|
img.attr('title','Searching');
|
||||||
|
img.attr('alt','searching');
|
||||||
|
img.attr('src',sbRoot+'/images/' + loadingImage);
|
||||||
|
disableLink(el);
|
||||||
|
// Update Status and Quality
|
||||||
|
var rSearchTerm = /(\w+)\s\((.+?)\)/;
|
||||||
|
HtmlContent = ep.searchstatus;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ep.searchstatus == 'queued') {
|
||||||
|
//el=$('td#' + ep.season + 'x' + ep.episode + '.search img');
|
||||||
|
img.attr('title','Queued');
|
||||||
|
img.attr('alt','queued');
|
||||||
|
img.attr('src',sbRoot+'/images/' + queuedImage );
|
||||||
|
disableLink(el);
|
||||||
|
HtmlContent = ep.searchstatus;
|
||||||
|
}
|
||||||
|
else if (ep.searchstatus == 'finished') {
|
||||||
|
//el=$('td#' + ep.season + 'x' + ep.episode + '.search img');
|
||||||
|
img.attr('title','Searching');
|
||||||
|
img.attr('alt','searching');
|
||||||
|
img.parent().attr('class','epRetry');
|
||||||
|
img.attr('src',sbRoot+'/images/' + searchImage);
|
||||||
|
enableLink(el);
|
||||||
|
|
||||||
|
// Update Status and Quality
|
||||||
|
var rSearchTerm = /(\w+)\s\((.+?)\)/;
|
||||||
|
HtmlContent = ep.status.replace(rSearchTerm,"$1"+' <span class="quality '+ep.quality+'">'+"$2"+'</span>');
|
||||||
|
|
||||||
|
}
|
||||||
|
// update the status column if it exists
|
||||||
|
parent.siblings('.status_column').html(HtmlContent)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
check_manual_searches();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function enableLink(el) {
|
||||||
|
el.on('click.disabled', false);
|
||||||
|
el.attr('enableClick', '1');
|
||||||
|
el.fadeTo("fast", 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableLink(el) {
|
||||||
|
el.off('click.disabled');
|
||||||
|
el.attr('enableClick', '0');
|
||||||
|
el.fadeTo("fast", .5)
|
||||||
|
}
|
||||||
|
|
||||||
(function(){
|
(function(){
|
||||||
|
|
||||||
$.ajaxEpSearch = {
|
$.ajaxEpSearch = {
|
||||||
@ -5,6 +114,7 @@
|
|||||||
size: 16,
|
size: 16,
|
||||||
colorRow: false,
|
colorRow: false,
|
||||||
loadingImage: 'loading16_dddddd.gif',
|
loadingImage: 'loading16_dddddd.gif',
|
||||||
|
queuedImage: 'queued.png',
|
||||||
noImage: 'no16.png',
|
noImage: 'no16.png',
|
||||||
yesImage: 'yes16.png'
|
yesImage: 'yes16.png'
|
||||||
}
|
}
|
||||||
@ -13,14 +123,34 @@
|
|||||||
$.fn.ajaxEpSearch = function(options){
|
$.fn.ajaxEpSearch = function(options){
|
||||||
options = $.extend({}, $.ajaxEpSearch.defaults, options);
|
options = $.extend({}, $.ajaxEpSearch.defaults, options);
|
||||||
|
|
||||||
$('.epSearch').click(function(){
|
$('.epSearch').click(function(event){
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Check if we have disabled the click
|
||||||
|
if ( $(this).attr('enableClick') == '0' ) {
|
||||||
|
console.debug("Already queued, not downloading!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $(this).attr('class') == "epRetry" ) {
|
||||||
|
if ( !confirm("Mark download as bad and retry?") )
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
var parent = $(this).parent();
|
var parent = $(this).parent();
|
||||||
|
|
||||||
// put the ajax spinner (for non white bg) placeholder while we wait
|
// Create var for anchor
|
||||||
parent.empty();
|
link = $(this);
|
||||||
parent.append($("<img/>").attr({"src": sbRoot+"/images/"+options.loadingImage, "height": options.size, "alt": "", "title": "loading"}));
|
|
||||||
|
// Create var for img under anchor and set options for the loading gif
|
||||||
|
img=$(this).children('img');
|
||||||
|
img.attr('title','loading');
|
||||||
|
img.attr('alt','');
|
||||||
|
img.attr('src',sbRoot+'/images/' + options.loadingImage);
|
||||||
|
|
||||||
|
|
||||||
$.getJSON($(this).attr('href'), function(data){
|
$.getJSON($(this).attr('href'), function(data){
|
||||||
|
|
||||||
// if they failed then just put the red X
|
// if they failed then just put the red X
|
||||||
if (data.result == 'failure') {
|
if (data.result == 'failure') {
|
||||||
img_name = options.noImage;
|
img_name = options.noImage;
|
||||||
@ -28,7 +158,7 @@
|
|||||||
|
|
||||||
// if the snatch was successful then apply the corresponding class and fill in the row appropriately
|
// if the snatch was successful then apply the corresponding class and fill in the row appropriately
|
||||||
} else {
|
} else {
|
||||||
img_name = options.yesImage;
|
img_name = options.loadingImage;
|
||||||
img_result = 'success';
|
img_result = 'success';
|
||||||
// color the row
|
// color the row
|
||||||
if (options.colorRow)
|
if (options.colorRow)
|
||||||
@ -38,15 +168,21 @@
|
|||||||
HtmlContent = data.result.replace(rSearchTerm,"$1"+' <span class="quality '+data.quality+'">'+"$2"+'</span>');
|
HtmlContent = data.result.replace(rSearchTerm,"$1"+' <span class="quality '+data.quality+'">'+"$2"+'</span>');
|
||||||
// update the status column if it exists
|
// update the status column if it exists
|
||||||
parent.siblings('.status_column').html(HtmlContent)
|
parent.siblings('.status_column').html(HtmlContent)
|
||||||
|
// Only if the queing was succesfull, disable the onClick event of the loading image
|
||||||
|
disableLink(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
// put the corresponding image as the result for the the row
|
// put the corresponding image as the result of queuing of the manual search
|
||||||
parent.empty();
|
img.attr('title',img_result);
|
||||||
parent.append($("<img/>").attr({"src": sbRoot+"/images/"+img_name, "height": options.size, "alt": img_result, "title": img_result}));
|
img.attr('alt',img_result);
|
||||||
|
img.attr('height', options.size);
|
||||||
|
img.attr('src',sbRoot+"/images/"+img_name);
|
||||||
});
|
});
|
||||||
|
//
|
||||||
|
|
||||||
// fon't follow the link
|
// don't follow the link
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
$('#sbRoot').ajaxEpSearch({'colorRow': true});
|
$('#sbRoot').ajaxEpSearch({'colorRow': true});
|
||||||
$('#sbRoot').ajaxEpRetry({'colorRow': true});
|
//$('#sbRoot').ajaxEpRetry({'colorRow': true});
|
||||||
|
|
||||||
$('#sbRoot').ajaxEpSubtitlesSearch();
|
$('#sbRoot').ajaxEpSubtitlesSearch();
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ DAILY_SEARCH = 20
|
|||||||
FAILED_SEARCH = 30
|
FAILED_SEARCH = 30
|
||||||
MANUAL_SEARCH = 40
|
MANUAL_SEARCH = 40
|
||||||
|
|
||||||
|
MANUAL_SEARCH_HISTORY = []
|
||||||
|
MANUAL_SEARCH_HISTORY_SIZE = 100
|
||||||
|
|
||||||
class SearchQueue(generic_queue.GenericQueue):
|
class SearchQueue(generic_queue.GenericQueue):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -55,6 +57,22 @@ class SearchQueue(generic_queue.GenericQueue):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def is_show_in_queue(self, show):
|
||||||
|
for cur_item in self.queue:
|
||||||
|
if isinstance(cur_item, (ManualSearchQueueItem, FailedQueueItem)) and cur_item.show.indexerid == show:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_all_ep_from_queue(self, show):
|
||||||
|
ep_obj_list = []
|
||||||
|
for cur_item in self.queue:
|
||||||
|
if isinstance(cur_item, (ManualSearchQueueItem, FailedQueueItem)) and str(cur_item.show.indexerid) == show:
|
||||||
|
ep_obj_list.append(cur_item)
|
||||||
|
|
||||||
|
if ep_obj_list:
|
||||||
|
return ep_obj_list
|
||||||
|
return False
|
||||||
|
|
||||||
def pause_backlog(self):
|
def pause_backlog(self):
|
||||||
self.min_priority = generic_queue.QueuePriorities.HIGH
|
self.min_priority = generic_queue.QueuePriorities.HIGH
|
||||||
|
|
||||||
@ -65,6 +83,12 @@ class SearchQueue(generic_queue.GenericQueue):
|
|||||||
# backlog priorities are NORMAL, this should be done properly somewhere
|
# backlog priorities are NORMAL, this should be done properly somewhere
|
||||||
return self.min_priority >= generic_queue.QueuePriorities.NORMAL
|
return self.min_priority >= generic_queue.QueuePriorities.NORMAL
|
||||||
|
|
||||||
|
def is_manualsearch_in_progress(self):
|
||||||
|
for cur_item in self.queue + [self.currentItem]:
|
||||||
|
if isinstance(cur_item, (ManualSearchQueueItem, FailedQueueItem)):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def is_backlog_in_progress(self):
|
def is_backlog_in_progress(self):
|
||||||
for cur_item in self.queue + [self.currentItem]:
|
for cur_item in self.queue + [self.currentItem]:
|
||||||
if isinstance(cur_item, BacklogQueueItem):
|
if isinstance(cur_item, BacklogQueueItem):
|
||||||
@ -140,12 +164,15 @@ class ManualSearchQueueItem(generic_queue.QueueItem):
|
|||||||
self.success = None
|
self.success = None
|
||||||
self.show = show
|
self.show = show
|
||||||
self.segment = segment
|
self.segment = segment
|
||||||
|
self.started = None
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
generic_queue.QueueItem.run(self)
|
generic_queue.QueueItem.run(self)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.log("Beginning manual search for: [" + self.segment.prettyName() + "]")
|
logger.log("Beginning manual search for: [" + self.segment.prettyName() + "]")
|
||||||
|
self.started = True
|
||||||
|
|
||||||
searchResult = search.searchProviders(self.show, [self.segment], True)
|
searchResult = search.searchProviders(self.show, [self.segment], True)
|
||||||
|
|
||||||
if searchResult:
|
if searchResult:
|
||||||
@ -165,6 +192,9 @@ class ManualSearchQueueItem(generic_queue.QueueItem):
|
|||||||
except Exception:
|
except Exception:
|
||||||
logger.log(traceback.format_exc(), logger.DEBUG)
|
logger.log(traceback.format_exc(), logger.DEBUG)
|
||||||
|
|
||||||
|
### Keep a list with the 100 last executed searches
|
||||||
|
fifo(MANUAL_SEARCH_HISTORY, self, MANUAL_SEARCH_HISTORY_SIZE)
|
||||||
|
|
||||||
if self.success is None:
|
if self.success is None:
|
||||||
self.success = False
|
self.success = False
|
||||||
|
|
||||||
@ -246,3 +276,8 @@ class FailedQueueItem(generic_queue.QueueItem):
|
|||||||
self.success = False
|
self.success = False
|
||||||
|
|
||||||
self.finish()
|
self.finish()
|
||||||
|
|
||||||
|
def fifo(myList, item, maxSize = 100):
|
||||||
|
if len(myList) >= maxSize:
|
||||||
|
myList.pop(0)
|
||||||
|
myList.append(item)
|
@ -4308,7 +4308,6 @@ class Home(MainHandler):
|
|||||||
|
|
||||||
redirect("/home/displayShow?show=" + show)
|
redirect("/home/displayShow?show=" + show)
|
||||||
|
|
||||||
|
|
||||||
def searchEpisode(self, show=None, season=None, episode=None):
|
def searchEpisode(self, show=None, season=None, episode=None):
|
||||||
|
|
||||||
# retrieve the episode object and fail if we can't get one
|
# retrieve the episode object and fail if we can't get one
|
||||||
@ -4318,14 +4317,78 @@ class Home(MainHandler):
|
|||||||
|
|
||||||
# make a queue item for it and put it on the queue
|
# make a queue item for it and put it on the queue
|
||||||
ep_queue_item = search_queue.ManualSearchQueueItem(ep_obj.show, ep_obj)
|
ep_queue_item = search_queue.ManualSearchQueueItem(ep_obj.show, ep_obj)
|
||||||
|
|
||||||
sickbeard.searchQueueScheduler.action.add_item(ep_queue_item) # @UndefinedVariable
|
sickbeard.searchQueueScheduler.action.add_item(ep_queue_item) # @UndefinedVariable
|
||||||
|
|
||||||
# wait until the queue item tells us whether it worked or not
|
|
||||||
while ep_queue_item.success is None: # @UndefinedVariable
|
|
||||||
time.sleep(cpu_presets[sickbeard.CPU_PRESET])
|
|
||||||
|
|
||||||
# return the correct json value
|
|
||||||
if ep_queue_item.success:
|
if ep_queue_item.success:
|
||||||
|
return returnManualSearchResult(ep_queue_item)
|
||||||
|
if not ep_queue_item.started and ep_queue_item.success is None:
|
||||||
|
return json.dumps({'result': 'success'}) #I Actually want to call it queued, because the search hasnt been started yet!
|
||||||
|
if ep_queue_item.started and ep_queue_item.success is None:
|
||||||
|
return json.dumps({'result': 'success'})
|
||||||
|
else:
|
||||||
|
return json.dumps({'result': 'failure'})
|
||||||
|
|
||||||
|
### Returns the current ep_queue_item status for the current viewed show.
|
||||||
|
# Possible status: Downloaded, Snatched, etc...
|
||||||
|
# Returns {'show': 279530, 'episodes' : ['episode' : 6, 'season' : 1, 'searchstatus' : 'queued', 'status' : 'running', 'quality': '4013']
|
||||||
|
def getManualSearchStatus(self, show=None, season=None):
|
||||||
|
|
||||||
|
episodes = []
|
||||||
|
currentManualSearchThreadsQueued = []
|
||||||
|
currentManualSearchThreadActive = []
|
||||||
|
finishedManualSearchThreadItems= []
|
||||||
|
|
||||||
|
# Queued Searches
|
||||||
|
currentManualSearchThreadsQueued = sickbeard.searchQueueScheduler.action.get_all_ep_from_queue(show)
|
||||||
|
# Running Searches
|
||||||
|
if (sickbeard.searchQueueScheduler.action.is_manualsearch_in_progress()):
|
||||||
|
currentManualSearchThreadActive = sickbeard.searchQueueScheduler.action.currentItem
|
||||||
|
|
||||||
|
# Finished Searches
|
||||||
|
finishedManualSearchThreadItems = sickbeard.search_queue.MANUAL_SEARCH_HISTORY
|
||||||
|
|
||||||
|
if currentManualSearchThreadsQueued:
|
||||||
|
for searchThread in currentManualSearchThreadsQueued:
|
||||||
|
searchstatus = 'queued'
|
||||||
|
|
||||||
|
episodes.append({'episode': searchThread.segment.episode,
|
||||||
|
'episodeindexid': searchThread.segment.indexerid,
|
||||||
|
'season' : searchThread.segment.season,
|
||||||
|
'searchstatus' : searchstatus,
|
||||||
|
'status' : statusStrings[searchThread.segment.status],
|
||||||
|
'quality': self.getQualityClass(searchThread.segment)})
|
||||||
|
|
||||||
|
if currentManualSearchThreadActive:
|
||||||
|
searchThread = currentManualSearchThreadActive
|
||||||
|
searchstatus = 'searching'
|
||||||
|
if searchThread.success:
|
||||||
|
searchstatus = 'finished'
|
||||||
|
episodes.append({'episode': searchThread.segment.episode,
|
||||||
|
'episodeindexid': searchThread.segment.indexerid,
|
||||||
|
'season' : searchThread.segment.season,
|
||||||
|
'searchstatus' : searchstatus,
|
||||||
|
'status' : statusStrings[searchThread.segment.status],
|
||||||
|
'quality': self.getQualityClass(searchThread.segment)})
|
||||||
|
|
||||||
|
if finishedManualSearchThreadItems:
|
||||||
|
for searchThread in finishedManualSearchThreadItems:
|
||||||
|
if str(searchThread.show.indexerid) == show and not [x for x in episodes if x['episodeindexid'] == searchThread.segment.indexerid]:
|
||||||
|
searchstatus = 'finished'
|
||||||
|
episodes.append({'episode': searchThread.segment.episode,
|
||||||
|
'episodeindexid': searchThread.segment.indexerid,
|
||||||
|
'season' : searchThread.segment.season,
|
||||||
|
'searchstatus' : searchstatus,
|
||||||
|
'status' : statusStrings[searchThread.segment.status],
|
||||||
|
'quality': self.getQualityClass(searchThread.segment)})
|
||||||
|
|
||||||
|
return json.dumps({'show': show, 'episodes' : episodes})
|
||||||
|
|
||||||
|
#return json.dumps()
|
||||||
|
|
||||||
|
def getQualityClass(self, ep_obj):
|
||||||
|
# return the correct json value
|
||||||
|
|
||||||
# Find the quality class for the episode
|
# Find the quality class for the episode
|
||||||
quality_class = Quality.qualityStrings[Quality.UNKNOWN]
|
quality_class = Quality.qualityStrings[Quality.UNKNOWN]
|
||||||
ep_status, ep_quality = Quality.splitCompositeStatus(ep_obj.status)
|
ep_status, ep_quality = Quality.splitCompositeStatus(ep_obj.status)
|
||||||
@ -4334,12 +4397,7 @@ class Home(MainHandler):
|
|||||||
quality_class = qualityPresetStrings[x]
|
quality_class = qualityPresetStrings[x]
|
||||||
break
|
break
|
||||||
|
|
||||||
return json.dumps({'result': statusStrings[ep_obj.status],
|
return quality_class
|
||||||
'quality': quality_class
|
|
||||||
})
|
|
||||||
|
|
||||||
return json.dumps({'result': 'failure'})
|
|
||||||
|
|
||||||
|
|
||||||
def searchEpisodeSubtitles(self, show=None, season=None, episode=None):
|
def searchEpisodeSubtitles(self, show=None, season=None, episode=None):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user