mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-07 10:33:38 +00:00
Add option to create season search exceptions from editShow page
This commit is contained in:
parent
52d8539e25
commit
00b8b7723d
6 changed files with 72 additions and 27 deletions
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
|
@ -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()
|
|
@ -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():
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue