Add option to create season search exceptions from editShow page

This commit is contained in:
Adam 2015-12-05 12:09:23 +08:00
parent 52d8539e25
commit 00b8b7723d
6 changed files with 72 additions and 27 deletions

View file

@ -95,6 +95,7 @@
* Add notice for users with Python 2.7.8 or below to update to latest Python * Add notice for users with Python 2.7.8 or below to update to latest Python
* Change position of parsed qualities to the start of log lines * Change position of parsed qualities to the start of log lines
* Change to always display branch and commit hash on 'Help & Info' page * Change to always display branch and commit hash on 'Help & Info' page
* Add option to create season search exceptions from editShow page
[develop changelog] [develop changelog]
* Enable Alpha Ratio again now that the secure login page over https is fixed * Enable Alpha Ratio again now that the secure login page over https is fixed

View file

@ -69,15 +69,25 @@
<span class="component-title">Scene exception</span> <span class="component-title">Scene exception</span>
<span class="component-desc"> <span class="component-desc">
<input type="text" id="SceneName" class="form-control form-control-inline input-sm input200"> <input type="text" id="SceneName" class="form-control form-control-inline input-sm input200">
<select id="SceneNameSeason" class="form-control form-control-inline input-sm input100" style="float:left">
<option value="-1">Series</option>
#if $show.anime:
#for $season in $seasonResults:
<option value="$season[0]">Season $season[0]</option>
#end for
#end if
</select>
<input class="btn btn-inline" type="button" value="Add" id="addSceneName"> <input class="btn btn-inline" type="button" value="Add" id="addSceneName">
<p class="clear-left note">add alternative release names found on search providers for <b class="boldest grey-text">$show.name</b></p> <p class="clear-left note">add alternative release names found on search providers for <b class="boldest grey-text">$show.name</b></p>
</span> </span>
<span class="component-desc"> <span class="component-desc">
<div id="SceneException"> <div id="SceneException">
<h4 class="grey-text">Exceptions list (multi-selectable)</h4> <h4 class="grey-text">Exceptions list (multi-selectable)</h4>
<select id="exceptions_list" name="exceptions_list" multiple="multiple" class="input200" style="min-height:90px; float:left" > <select id="exceptions_list" name="exceptions_list" multiple="multiple" class="input350" style="min-height:90px; float:left" >
#for $cur_exception in $show.exceptions: #for $cur_exception_season in $show.exceptions:
<option value="$cur_exception">$cur_exception</option> #for $cur_exception in $show.exceptions[$cur_exception_season]:
<option value="$cur_exception_season|$cur_exception">S#echo ($cur_exception_season, '*')[$cur_exception_season == -1]#: $cur_exception</option>
#end for
#end for #end for
</select> </select>
<span><p class="note">this list overrides the original name<br />to search, it doesn't append to it</p></span> <span><p class="note">this list overrides the original name<br />to search, it doesn't append to it</p></span>

View file

@ -53,6 +53,7 @@ $(document).ready(function () {
$('#addSceneName').click(function () { $('#addSceneName').click(function () {
var scene_ex = $('#SceneName').val(); var scene_ex = $('#SceneName').val();
var scene_ex_season = $('#SceneNameSeason').val();
var option = $('<option>'); var option = $('<option>');
all_exceptions = []; all_exceptions = [];
@ -61,14 +62,20 @@ $(document).ready(function () {
}); });
$('#SceneName').val(''); $('#SceneName').val('');
$('#SceneNameSeason').val('');
if ($.inArray(scene_ex, all_exceptions) > -1 || (scene_ex === '')) { if ($.inArray(scene_ex_season + '|' + scene_ex, all_exceptions) > -1 || (scene_ex === '')) {
return; return;
} }
$('#SceneException').show(); $('#SceneException').show();
option.attr('value', scene_ex); option.attr('value', scene_ex_season + '|' + scene_ex);
option.html(scene_ex); if (scene_ex_season === "-1") {
option.html('S*: ' + scene_ex);
}
else {
option.html('S' + scene_ex_season + ': ' + scene_ex);
}
return option.appendTo('#exceptions_list'); return option.appendTo('#exceptions_list');
}); });
@ -94,4 +101,6 @@ $(document).ready(function () {
}; };
$(this).toggle_SceneException(); $(this).toggle_SceneException();
}); });

View file

@ -22,6 +22,11 @@ import sickbeard
from lib.dateutil import parser from lib.dateutil import parser
from sickbeard.common import Quality from sickbeard.common import Quality
try:
from collections import OrderedDict
except ImportError:
from requests.compat import OrderedDict
class SearchResult: class SearchResult:
""" """
@ -151,7 +156,7 @@ class ShowListUI:
""" """
This class is for tvdb-api. Instead of prompting with a UI to pick the This class is for tvdb-api. Instead of prompting with a UI to pick the
desired result out of a list of shows it tries to be smart about it desired result out of a list of shows it tries to be smart about it
based on what shows are in SB. based on what shows are in SB.
""" """
def __init__(self, config, log=None): def __init__(self, config, log=None):
@ -222,3 +227,24 @@ class UIError():
def __init__(self, message): def __init__(self, message):
self.message = message self.message = message
self.time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
class OrderedDefaultdict(OrderedDict):
def __init__(self, *args, **kwargs):
if not args:
self.default_factory = None
else:
if not (args[0] is None or callable(args[0])):
raise TypeError('first argument must be callable or None')
self.default_factory = args[0]
args = args[1:]
super(OrderedDefaultdict, self).__init__(*args, **kwargs)
def __missing__ (self, key):
if self.default_factory is None:
raise KeyError(key)
self[key] = default = self.default_factory()
return default
def __reduce__(self): # optional, for pickle support
args = (self.default_factory,) if self.default_factory else ()
return self.__class__, args, None, None, self.iteritems()

View file

@ -22,11 +22,13 @@ import threading
import datetime import datetime
import sickbeard import sickbeard
from collections import defaultdict
from lib import adba from lib import adba
from sickbeard import helpers from sickbeard import helpers
from sickbeard import name_cache from sickbeard import name_cache
from sickbeard import logger from sickbeard import logger
from sickbeard import db from sickbeard import db
from sickbeard.classes import OrderedDefaultdict
exception_dict = {} exception_dict = {}
anidb_exception_dict = {} anidb_exception_dict = {}
@ -86,15 +88,13 @@ def get_scene_exceptions(indexer_id, season=-1):
def get_all_scene_exceptions(indexer_id): def get_all_scene_exceptions(indexer_id):
exceptions_dict = {} exceptions_dict = OrderedDefaultdict(list)
my_db = db.DBConnection('cache.db') my_db = db.DBConnection('cache.db')
exceptions = my_db.select('SELECT show_name,season FROM scene_exceptions WHERE indexer_id = ?', [indexer_id]) exceptions = my_db.select('SELECT show_name,season FROM scene_exceptions WHERE indexer_id = ? ORDER BY season', [indexer_id])
if exceptions: if exceptions:
for cur_exception in exceptions: for cur_exception in exceptions:
if not cur_exception['season'] in exceptions_dict:
exceptions_dict[cur_exception['season']] = []
exceptions_dict[cur_exception['season']].append(cur_exception['show_name']) exceptions_dict[cur_exception['season']].append(cur_exception['show_name'])
return exceptions_dict return exceptions_dict
@ -237,28 +237,28 @@ def retrieve_exceptions():
xem_exception_dict.clear() xem_exception_dict.clear()
def update_scene_exceptions(indexer_id, scene_exceptions, season=-1): def update_scene_exceptions(indexer_id, scene_exceptions):
""" """
Given a indexer_id, and a list of all show scene exceptions, update the db. Given a indexer_id, and a list of all show scene exceptions, update the db.
""" """
global exceptionsCache global exceptionsCache
my_db = db.DBConnection('cache.db') my_db = db.DBConnection('cache.db')
my_db.action('DELETE FROM scene_exceptions WHERE indexer_id=? and season=?', [indexer_id, season]) my_db.action('DELETE FROM scene_exceptions WHERE indexer_id=?', [indexer_id])
# A change has been made to the scene exception list. Let's clear the cache, to make this visible
exceptionsCache[indexer_id] = defaultdict(list)
logger.log(u'Updating scene exceptions', logger.MESSAGE) logger.log(u'Updating scene exceptions', logger.MESSAGE)
for exception in scene_exceptions:
# A change has been made to the scene exception list. Let's clear the cache, to make this visible cur_season, cur_exception = exception.split('|', 1)
if indexer_id in exceptionsCache:
exceptionsCache[indexer_id] = {}
exceptionsCache[indexer_id][season] = scene_exceptions
for cur_exception in scene_exceptions: exceptionsCache[indexer_id][cur_season].append(cur_exception)
if not isinstance(cur_exception, unicode): if not isinstance(cur_exception, unicode):
cur_exception = unicode(cur_exception, 'utf-8', 'replace') cur_exception = unicode(cur_exception, 'utf-8', 'replace')
my_db.action('INSERT INTO scene_exceptions (indexer_id, show_name, season) VALUES (?,?,?)', my_db.action('INSERT INTO scene_exceptions (indexer_id, show_name, season) VALUES (?,?,?)',
[indexer_id, cur_exception, season]) [indexer_id, cur_exception, cur_season])
def _anidb_exceptions_fetcher(): def _anidb_exceptions_fetcher():

View file

@ -42,7 +42,6 @@ from sickbeard.common import SD, HD720p, HD1080p
from sickbeard.exceptions import ex from sickbeard.exceptions import ex
from sickbeard.helpers import remove_article, starify from sickbeard.helpers import remove_article, starify
from sickbeard.indexers.indexer_config import INDEXER_TVDB, INDEXER_TVRAGE from sickbeard.indexers.indexer_config import INDEXER_TVDB, INDEXER_TVRAGE
from sickbeard.scene_exceptions import get_scene_exceptions
from sickbeard.scene_numbering import get_scene_numbering, set_scene_numbering, get_scene_numbering_for_show, \ from sickbeard.scene_numbering import get_scene_numbering, set_scene_numbering, get_scene_numbering_for_show, \
get_xem_numbering_for_show, get_scene_absolute_numbering_for_show, get_xem_absolute_numbering_for_show, \ get_xem_numbering_for_show, get_scene_absolute_numbering_for_show, get_xem_absolute_numbering_for_show, \
get_scene_absolute_numbering get_scene_absolute_numbering
@ -1246,7 +1245,7 @@ class Home(MainHandler):
else: else:
return self._genericMessage('Error', errString) return self._genericMessage('Error', errString)
showObj.exceptions = scene_exceptions.get_scene_exceptions(showObj.indexerid) showObj.exceptions = scene_exceptions.get_all_scene_exceptions(showObj.indexerid)
if None is not quality_preset and int(quality_preset): if None is not quality_preset and int(quality_preset):
bestQualities = [] bestQualities = []
@ -1255,6 +1254,10 @@ class Home(MainHandler):
t = PageTemplate(headers=self.request.headers, file='editShow.tmpl') t = PageTemplate(headers=self.request.headers, file='editShow.tmpl')
t.submenu = self.HomeMenu() t.submenu = self.HomeMenu()
myDB = db.DBConnection()
t.seasonResults = myDB.select(
'SELECT DISTINCT season FROM tv_episodes WHERE showid = ? ORDER BY season asc', [showObj.indexerid])
if showObj.is_anime: if showObj.is_anime:
if not showObj.release_groups: if not showObj.release_groups:
showObj.release_groups = BlackAndWhiteList(showObj.indexerid) showObj.release_groups = BlackAndWhiteList(showObj.indexerid)
@ -1273,7 +1276,6 @@ class Home(MainHandler):
with showObj.lock: with showObj.lock:
t.show = showObj t.show = showObj
t.scene_exceptions = get_scene_exceptions(showObj.indexerid)
t.show_has_scene_map = showObj.indexerid in sickbeard.scene_exceptions.xem_tvdb_ids_list + sickbeard.scene_exceptions.xem_rage_ids_list t.show_has_scene_map = showObj.indexerid in sickbeard.scene_exceptions.xem_tvdb_ids_list + sickbeard.scene_exceptions.xem_rage_ids_list
return t.respond() return t.respond()
@ -1317,10 +1319,7 @@ class Home(MainHandler):
if directCall: if directCall:
do_update_exceptions = False do_update_exceptions = False
else: else:
if set(exceptions_list) == set(showObj.exceptions): do_update_exceptions = True # TODO make this smarter and only update on changes
do_update_exceptions = False
else:
do_update_exceptions = True
with showObj.lock: with showObj.lock:
if anime: if anime: