Merge pull request #571 from adam111316/feature/ChangeEditJS

Add option to create season search exceptions from editShow page
This commit is contained in:
adam111316 2015-12-05 12:20:25 +08:00
commit d07c4d9add
6 changed files with 172 additions and 123 deletions

View file

@ -95,6 +95,7 @@
* 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 to always display branch and commit hash on 'Help & Info' page
* Add option to create season search exceptions from editShow page
[develop changelog]
* Enable Alpha Ratio again now that the secure login page over https is fixed

View file

@ -14,43 +14,13 @@
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
<script type="text/javascript" src="$sbRoot/js/qualityChooser.js?v=$sbPID"></script>
<script type="text/javascript" charset="utf-8">
<!--
\$(document).ready(function(){
\$.getJSON('$sbRoot/home/addShows/getIndexerLanguages', {}, function(data) {
var resultStr = '';
if (data.results.length == 0) {
flag = ' class="flag" style="background-image:url($sbRoot/images/flags/${show.lang}.png)"';
resultStr = '<option value="$show.lang" selected="selected" + flag>$show.lang</option>';
} else {
var current_lang_added = false;
\$.each(data.results, function(index, obj) {
if (obj == '$show.lang') {
selected = ' selected="selected"';
current_lang_added = true;
}
else {
selected = '';
}
flag = ' class="flag" style="background-image:url($sbRoot/images/flags/' + obj + '.png);"';
resultStr += '<option value="' + obj + '"' + selected + flag + '>' + obj + '</option>';
});
if (!current_lang_added)
resultStr += '<option value="$show.lang" selected="selected">$show.lang</option>';
}
\$('#indexerLangSelectEdit').html(resultStr)
});
});
//-->
<script type="text/javascript" src="$sbRoot/js/editShow.js?v=$sbPID"></script>
<script>
var config = {
show_lang: "$show.lang",
show_isanime: #echo ['!1','!0'][$show.is_anime]#
}
</script>
#if $varExists('header')
<h1 class="header">$header</h1>
#else
@ -99,15 +69,25 @@
<span class="component-title">Scene exception</span>
<span class="component-desc">
<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">
<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 class="component-desc">
<div id="SceneException">
<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" >
#for $cur_exception in $show.exceptions:
<option value="$cur_exception">$cur_exception</option>
<select id="exceptions_list" name="exceptions_list" multiple="multiple" class="input350" style="min-height:90px; float:left" >
#for $cur_exception_season in $show.exceptions:
#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
</select>
<span><p class="note">this list overrides the original name<br />to search, it doesn't append to it</p></span>
@ -252,69 +232,6 @@
#end if
<input type="submit" id="submit" value="Submit" class="btn btn-primary" />
</form>
<script type="text/javascript" charset="utf-8">
<!--
var all_exceptions = new Array;
jQuery('#location').fileBrowser({ title: 'Select Show Location' });
\$('#submit').click(function(){
all_exceptions = []
\$('#exceptions_list option').each ( function() {
all_exceptions.push( \$(this).val() );
});
\$('#exceptions_list').val(all_exceptions);
#if $show.is_anime:
generate_bwlist()
#end if
});
\$('#addSceneName').click(function() {
var scene_ex = \$('#SceneName').val()
var option = \$('<option>')
all_exceptions = []
\$('#exceptions_list option').each ( function() {
all_exceptions.push( \$(this).val() )
});
\$('#SceneName').val('')
if (jQuery.inArray(scene_ex, all_exceptions) > -1 || (scene_ex == ''))
return
\$('#SceneException').show()
option.attr('value',scene_ex)
option.html(scene_ex)
return option.appendTo('#exceptions_list');
});
\$('#removeSceneName').click(function() {
\$('#exceptions_list option:selected').remove();
\$(this).toggle_SceneException()
});
$.fn.toggle_SceneException = function() {
all_exceptions = []
\$('#exceptions_list option').each ( function() {
all_exceptions.push( \$(this).val() );
});
if ('' == all_exceptions)
\$('#SceneException').hide();
else
\$('#SceneException').show();
}
\$(this).toggle_SceneException();
//-->
</script>
</div>
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')

106
gui/slick/js/editShow.js Normal file
View file

@ -0,0 +1,106 @@
/*globals $, config, sbRoot, generate_bwlist*/
$(document).ready(function () {
$.getJSON(sbRoot + '/home/addShows/getIndexerLanguages', {}, function (data) {
var resultStr, flag, selected, current_lang_added = '';
if (data.results.length === 0) {
flag = ' class="flag" style="background-image:url(' + sbRoot + '/images/flags/' + config.show_lang + '.png)"';
resultStr = '<option value="' + config.show_lang + '" selected="selected"' + flag + '>' + config.show_lang + '</option>';
} else {
current_lang_added = false;
$.each(data.results, function (index, obj) {
if (obj === config.show_lang) {
selected = ' selected="selected"';
current_lang_added = true;
}
else {
selected = '';
}
flag = ' class="flag" style="background-image:url(' + sbRoot + '/images/flags/' + obj + '.png);"';
resultStr += '<option value="' + obj + '"' + selected + flag + '>' + obj + '</option>';
});
if (!current_lang_added) {
resultStr += '<option value=" ' + config.show_lang + '" selected="selected"> ' + config.show_lang + '</option>';
}
}
$('#indexerLangSelectEdit').html(resultStr);
});
var all_exceptions = [];
$('#location').fileBrowser({title: 'Select Show Location'});
$('#submit').click(function () {
all_exceptions = [];
$('#exceptions_list').find('option').each (function () {
all_exceptions.push($(this).val());
});
$('#exceptions_list').val(all_exceptions);
if (config.show_isanime) {
generate_bwlist();
}
});
$('#addSceneName').click(function () {
var scene_ex = $('#SceneName').val();
var scene_ex_season = $('#SceneNameSeason').val();
var option = $('<option>');
all_exceptions = [];
$('#exceptions_list').find('option').each (function () {
all_exceptions.push($(this).val());
});
$('#SceneName').val('');
$('#SceneNameSeason').val('');
if ($.inArray(scene_ex_season + '|' + scene_ex, all_exceptions) > -1 || (scene_ex === '')) {
return;
}
$('#SceneException').show();
option.attr('value', scene_ex_season + '|' + 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');
});
$('#removeSceneName').click(function () {
$('#exceptions_list').find('option:selected').remove();
$(this).toggle_SceneException();
});
$.fn.toggle_SceneException = function () {
all_exceptions = [];
$('#exceptions_list').find('option').each (function () {
all_exceptions.push($(this).val());
});
if ('' === all_exceptions) {
$('#SceneException').hide();
}
else {
$('#SceneException').show();
}
};
$(this).toggle_SceneException();
});

View file

@ -22,6 +22,11 @@ import sickbeard
from lib.dateutil import parser
from sickbeard.common import Quality
try:
from collections import OrderedDict
except ImportError:
from requests.compat import OrderedDict
class SearchResult:
"""
@ -151,7 +156,7 @@ class ShowListUI:
"""
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
based on what shows are in SB.
based on what shows are in SB.
"""
def __init__(self, config, log=None):
@ -222,3 +227,24 @@ class UIError():
def __init__(self, message):
self.message = message
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 sickbeard
from collections import defaultdict
from lib import adba
from sickbeard import helpers
from sickbeard import name_cache
from sickbeard import logger
from sickbeard import db
from sickbeard.classes import OrderedDefaultdict
exception_dict = {}
anidb_exception_dict = {}
@ -86,15 +88,13 @@ def get_scene_exceptions(indexer_id, season=-1):
def get_all_scene_exceptions(indexer_id):
exceptions_dict = {}
exceptions_dict = OrderedDefaultdict(list)
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:
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'])
return exceptions_dict
@ -237,28 +237,28 @@ def retrieve_exceptions():
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.
"""
global exceptionsCache
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)
# A change has been made to the scene exception list. Let's clear the cache, to make this visible
if indexer_id in exceptionsCache:
exceptionsCache[indexer_id] = {}
exceptionsCache[indexer_id][season] = scene_exceptions
for exception in scene_exceptions:
cur_season, cur_exception = exception.split('|', 1)
for cur_exception in scene_exceptions:
exceptionsCache[indexer_id][cur_season].append(cur_exception)
if not isinstance(cur_exception, unicode):
cur_exception = unicode(cur_exception, 'utf-8', 'replace')
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():

View file

@ -42,7 +42,6 @@ from sickbeard.common import SD, HD720p, HD1080p
from sickbeard.exceptions import ex
from sickbeard.helpers import remove_article, starify
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, \
get_xem_numbering_for_show, get_scene_absolute_numbering_for_show, get_xem_absolute_numbering_for_show, \
get_scene_absolute_numbering
@ -1246,7 +1245,7 @@ class Home(MainHandler):
else:
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):
bestQualities = []
@ -1255,6 +1254,10 @@ class Home(MainHandler):
t = PageTemplate(headers=self.request.headers, file='editShow.tmpl')
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 not showObj.release_groups:
showObj.release_groups = BlackAndWhiteList(showObj.indexerid)
@ -1273,7 +1276,6 @@ class Home(MainHandler):
with showObj.lock:
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
return t.respond()
@ -1317,10 +1319,7 @@ class Home(MainHandler):
if directCall:
do_update_exceptions = False
else:
if set(exceptions_list) == set(showObj.exceptions):
do_update_exceptions = False
else:
do_update_exceptions = True
do_update_exceptions = True # TODO make this smarter and only update on changes
with showObj.lock:
if anime: