Change terminology around the custom quality selection to improve clarity.

Change restrict changing custom download qualities to reasonable selections.
Add upgrade to quality selections on Add show page and Import existing show page.
This commit is contained in:
JackDandy 2018-02-02 22:24:33 +00:00
parent f31332185a
commit fae9ae6bb7
10 changed files with 135 additions and 77 deletions

View file

@ -1,4 +1,11 @@
### 0.14.0 (2018-02-01 02:30:00 UTC) ### 0.14.1 (2018-02-03 22:40:00 UTC)
Change terminology around the custom quality selection to improve clarity
Change restrict changing custom download qualities to reasonable selections
Add upgrade to quality selections on Add show page and Import existing show page
### 0.14.0 (2018-02-01 02:30:00 UTC)
* Change improve core scheduler logic * Change improve core scheduler logic
* Change improve media process to parse anime format 'Show Name 123 - 001 - Ep 1 name' * Change improve media process to parse anime format 'Show Name 123 - 001 - Ep 1 name'

View file

@ -4114,6 +4114,11 @@ fieldset[disabled] .navbar-default .btn-link:focus{
background-color:#080808 \9 background-color:#080808 \9
} }
.btn-inverse.btn.disabled,
.btn-inverse[disabled]{
color:#444
}
.btn-xs{ .btn-xs{
padding:1px 5px; padding:1px 5px;
font-size:12px; font-size:12px;

View file

@ -293,7 +293,7 @@
#else #else
#if $anyQualities #if $anyQualities
<div> <div>
<span class="details-title">Initial</span> <span class="details-title">Qualities</span>
<span class="details-info"> <span class="details-info">
#echo ', '.join([$Quality.get_quality_ui($x) for $x in sorted($anyQualities)])# #echo ', '.join([$Quality.get_quality_ui($x) for $x in sorted($anyQualities)])#
</span> </span>

View file

@ -149,18 +149,6 @@
#set global $any_qualities = $qualities[0] #set global $any_qualities = $qualities[0]
#set global $best_qualities = $qualities[1] #set global $best_qualities = $qualities[1]
#include $os.path.join($sg_str('PROG_DIR'), 'gui/slick/interfaces/default/inc_qualityChooser.tmpl') #include $os.path.join($sg_str('PROG_DIR'), 'gui/slick/interfaces/default/inc_qualityChooser.tmpl')
#if $any_qualities + $best_qualities
<div class="field-pair show-if-quality-custom" style="display:none">
<label for="upgrade-once">
<span class="component-title">Upgrade once</span>
<span class="component-desc">
<input type="checkbox" name="upgrade_once" id="upgrade-once"#echo ('', $html_checked)[$show.upgrade_once]#>
<p>stop upgrading after matching the first best <em>upgrade</em> quality</p>
</span>
</label>
</div>
#end if
</div> </div>
</div><!-- /component-group1 //--> </div><!-- /component-group1 //-->

View file

@ -1,6 +1,7 @@
#import sickbeard #import sickbeard
#from sickbeard.common import Quality, qualityPresets, qualityPresetStrings #from sickbeard.common import Quality, qualityPresets, qualityPresetStrings
##
#set $html_checked = ' checked="checked"'
#set $html_selected = ' selected="selected"' #set $html_selected = ' selected="selected"'
<div class="field-pair"> <div class="field-pair">
<label for="quality-preset" class="clearfix"> <label for="quality-preset" class="clearfix">
@ -23,16 +24,16 @@
<div id="custom-quality" class="show-if-quality-custom" style="display:none"> <div id="custom-quality" class="show-if-quality-custom" style="display:none">
<div class="field-pair"> <div class="field-pair">
<div class="component-group-desc tip-text"> <div class="component-group-desc tip-text">
<p style="margin-bottom:25px">An <em class="highlight-text">initial</em> quality downloads before optional upgrades</p> <p style="margin-bottom:25px">Wanted quality</p>
<p id="unknown-quality" style="display:none"> <p id="unknown-quality" style="display:none">
Temporarily use <em class="red-text">'Unknown'</em> to skip release qual checks. <em class="red-text">Briefly use</em> <em class="highlight-text">'Unknown'</em> to skip release quality checks
Results in spam if left on but expect spam if left on
</p> </p>
</div> </div>
<span id="initial-quality" class="component-desc"> <span id="wanted-quality" class="component-desc">
<p>Select one or more qualities; the best one found when searching will be snatched</p> <p>select one or more qualities; the best one found when searching will be used</p>
#set $any_quality_list = filter(lambda x: x > $Quality.NONE and x < $Quality.UNKNOWN, $Quality.qualityStrings) #set $any_quality_list = filter(lambda x: x > $Quality.NONE and x < $Quality.UNKNOWN, $Quality.qualityStrings)
#set $has_unknown = False #set $has_unknown = False
#for $cur_quality in sorted($any_quality_list): #for $cur_quality in sorted($any_quality_list):
@ -53,13 +54,13 @@
<div class="field-pair" style="clear:both"> <div class="field-pair" style="clear:both">
<div class="component-group-desc tip-text"> <div class="component-group-desc tip-text">
<p style="margin-bottom:25px">All found <em class="highlight-text">upgrade</em> qualities download until the best</p> <p style="margin-bottom:25px">All selected qualities found will upgrade until the best</p>
<p id="no-upgrade" style="display:none">No <em class="highlight-text">upgrades</em> selected, an <em class="highlight-text">initial</em> snatch will complete any search</p> <p id="no-upgrade" style="display:none">With no upgrades selected, search is complete when a <em class="highlight-text">wanted quality</em> is found</p>
<p id="upgrade-cond" style="display:none">An <em class="highlight-text">upgrade</em> will only search after an <em class="highlight-text">initial</em> has complete</p> <p id="upgrade-cond" style="display:none">Upgrades will search <em class="highlight-text">after</em> a wanted quality release is snatched or downloaded</p>
</div> </div>
<span id="upgrade-quality" class="component-desc"> <span id="upgrade-quality" class="component-desc">
<p>Optional, upgrade a completed download to any selected quality</p> <p>optional, upgrade existing media to any selected quality</p>
#set $best_quality_list = filter(lambda x: x > $Quality.SDTV and x < $Quality.UNKNOWN, $Quality.qualityStrings) #set $best_quality_list = filter(lambda x: x > $Quality.SDTV and x < $Quality.UNKNOWN, $Quality.qualityStrings)
#for $cur_quality in sorted($best_quality_list): #for $cur_quality in sorted($best_quality_list):
<a href="#" data-quality="$cur_quality" class="btn btn-inverse dark-bg#echo ('', ' active')[$cur_quality in $best_qualities]#" role="button"><i class="icon-glyph searchadd"></i>$Quality.get_quality_ui($cur_quality)</a> <a href="#" data-quality="$cur_quality" class="btn btn-inverse dark-bg#echo ('', ' active')[$cur_quality in $best_qualities]#" role="button"><i class="icon-glyph searchadd"></i>$Quality.get_quality_ui($cur_quality)</a>
@ -70,11 +71,22 @@
</span> </span>
</div> </div>
<div class="field-pair" id="upgrade-once-opt" style="display:none">
<label for="upgrade-once">
<span class="component-title">Upgrade once</span>
<span class="component-desc">
<input type="checkbox" name="upgrade_once" id="upgrade-once"#echo ('', $html_checked)[$varExists('show') and $show.upgrade_once]#>
<p>stop upgrading after matching the first best <em>upgrade</em> quality</p>
</span>
</label>
</div>
<span class="component-desc bfr"> <span class="component-desc bfr">
<div style="float:left;padding-right:28px"> <div style="float:left;padding-right:28px">
<h4 class="jumbo">Initial</h4> <h4 class="jumbo">Wanted</h4>
#set $any_quality_list = filter(lambda x: x > $Quality.NONE, $Quality.qualityStrings) #set $any_quality_list = filter(lambda x: x > $Quality.NONE, $Quality.qualityStrings)
<select id="initial-qualities" name="anyQualities" multiple="multiple" size="$len($any_quality_list)" class="form-control form-control-inline input-sm">
<select id="wanted-qualities" name="anyQualities" multiple="multiple" size="$len($any_quality_list)" class="form-control form-control-inline input-sm">
#for $cur_quality in sorted($any_quality_list): #for $cur_quality in sorted($any_quality_list):
<option value="$cur_quality"#echo ('', $html_selected)[$cur_quality in $any_qualities]#>$Quality.get_quality_ui($cur_quality)</option> <option value="$cur_quality"#echo ('', $html_selected)[$cur_quality in $any_qualities]#>$Quality.get_quality_ui($cur_quality)</option>
#end for #end for

View file

@ -66,7 +66,7 @@
<div class="manageCustom pull-left"> <div class="manageCustom pull-left">
<h4 style="font-size:14px">Initial</h4> <h4 style="font-size:14px">Initial</h4>
#set $anyQualityList = filter(lambda x: x > $common.Quality.NONE, $common.Quality.qualityStrings) #set $anyQualityList = filter(lambda x: x > $common.Quality.NONE, $common.Quality.qualityStrings)
<select id="initial-qualities" name="anyQualities" multiple="multiple" size="$len($anyQualityList)"> <select id="wanted-qualities" name="anyQualities" multiple="multiple" size="$len($anyQualityList)">
#for $curQuality in sorted($anyQualityList): #for $curQuality in sorted($anyQualityList):
<option value="$curQuality" #if $curQuality in $anyQualities then $selected else ''#>$common.Quality.get_quality_ui($curQuality)</option> <option value="$curQuality" #if $curQuality in $anyQualities then $selected else ''#>$common.Quality.get_quality_ui($curQuality)</option>
#end for #end for

View file

@ -3,7 +3,7 @@ $(document).ready(function(){
$('#saveDefaultsButton').click(function() { $('#saveDefaultsButton').click(function() {
var anyQualArray = [], bestQualArray = []; var anyQualArray = [], bestQualArray = [];
$('#initial-qualities option:selected').each(function(i, d) { $('#wanted-qualities option:selected').each(function(i, d) {
anyQualArray.push($(d).val()); anyQualArray.push($(d).val());
}); });
$('#upgrade-qualities option:selected').each(function(i, d) { $('#upgrade-qualities option:selected').each(function(i, d) {
@ -32,7 +32,7 @@ $(document).ready(function(){
$(this).attr('disabled', true); $(this).attr('disabled', true);
}); });
$('#statusSelect, #quality-preset, #initial-qualities, #upgrade-qualities, #wanted_begin, #wanted_latest,' $('#statusSelect, #quality-preset, #wanted-qualities, #upgrade-qualities, #wanted_begin, #wanted_latest,'
+ ' #flatten_folders, #scene, #subtitles, #anime, #tag').change(function() { + ' #flatten_folders, #scene, #subtitles, #anime, #tag').change(function() {
$('#saveDefaultsButton').attr('disabled', false); $('#saveDefaultsButton').attr('disabled', false);
}); });

View file

@ -1,14 +1,14 @@
function setFromPresets (preset) { function setFromPresets (preset){
var elCustomQuality = $('.show-if-quality-custom'), var elCustomQuality = $('.show-if-quality-custom');
selected = 'selected', quality, selectState, btn$, dev = !1;
if (preset = parseInt(preset)) {
!dev && elCustomQuality.fadeOut('fast', 'linear');
var upgrade = !0; if(preset = parseInt(preset)){
$('#initial-qualities, #upgrade-qualities').find('option').each(function() { var upgradePreset = !0, quality, stateReqd, btn$;
if (upgrade && 'upgrade-qualities' === $(this).parent().attr('id')) { elCustomQuality.fadeOut('fast', 'linear');
upgrade = !1;
switch (preset) { $('#wanted-qualities, #upgrade-qualities').find('option').each(function(){
if(upgradePreset && /upgrade/.test($(this).parent().attr('id'))){
upgradePreset = !1;
switch(preset){
case 3: preset = 128 + 32 + 4; break; case 3: preset = 128 + 32 + 4; break;
case 164: preset = 256 + 64 + 16 + 4; break; case 164: preset = 256 + 64 + 16 + 4; break;
case 336: preset = 256; break; case 336: preset = 256; break;
@ -16,76 +16,117 @@ function setFromPresets (preset) {
} }
} }
quality = $(this).val(); quality = $(this).val(); // quality from select$
selectState = ((preset & parseInt(quality, 10)) ? selected : !1); stateReqd = ((preset & parseInt(quality, 10)) ? !0 : !1);
$(this).attr(selected, selectState); if(stateReqd !== this.selected){
$(this).prop('selected', stateReqd);
var list = /initial/.test($(this).parent().attr('id')) ? '#initial-quality': '#upgrade-quality'; btn$ = $(/upgrade/.test($(this).parent().attr('id')) ? '#upgrade-quality' : '#wanted-quality')
btn$ = $(/initial/.test($(this).parent().attr('id')) ? '#initial-quality': '#upgrade-quality').find('a.btn[data-quality="' + quality + '"]'); .find('a.btn[data-quality="' + quality + '"]');
if(!selectState){ if(!stateReqd){
btn$.removeClass('active') btn$.removeClass('active');
} else {
} else { btn$.removeClass('disabled').addClass('active');
btn$.addClass('active') }
} }
dev && console.log(preset, list, 'this.val():', quality, 'selectState:', selectState, 'hasClass:', btn$.hasClass('active'))
}); });
dev && console.log('-----------------------');
} else } else
elCustomQuality.fadeIn('fast', 'linear'); elCustomQuality.fadeIn('fast', 'linear');
refreshUpgrades();
presentTips(); presentTips();
} }
function presentTips() { function presentTips(){
var tip$ = $('#unknown-quality'); var tip$ = $('#unknown-quality'), tip2$;
if ($('#initial-quality').find('a.btn[data-quality="32768"]').hasClass('active')) { if($('#wanted-quality').find('a.btn[data-quality="32768"]').hasClass('active')){
tip$.fadeIn('fast', 'linear'); tip$.fadeIn('fast', 'linear');
} else { } else {
tip$.fadeOut('fast', 'linear'); tip$.fadeOut('fast', 'linear');
} }
var tip$ = $('#no-upgrade'), tip2$ = $('#upgrade-cond'); tip$ = $('#no-upgrade'); tip2$ = $('#upgrade-cond, #upgrade-once-opt');
if ($('#upgrade-quality').find('a.btn').hasClass('active')) { if($('#upgrade-quality').find('a.btn').hasClass('active')){
tip$.fadeOut('fast', 'linear', function(){tip2$.fadeIn('fast', 'linear');}); tip$.fadeOut('fast', 'linear', function(){tip2$.fadeIn('fast', 'linear');});
} else { } else {
if(!!$('#upgrade-once:checked').length){
$('#upgrade-once').click();
}
tip2$.fadeOut('fast', 'linear', function(){tip$.fadeIn('fast', 'linear');}); tip2$.fadeOut('fast', 'linear', function(){tip$.fadeIn('fast', 'linear');});
} }
} }
$(function() { function refreshUpgrades(){
var btn$, minQuality=99999999, quality, upgrade$;
$.map($('#wanted-quality').find('a.btn.active'), function(btn){
btn$ = $(btn);
quality = parseInt(btn$.data('quality'), 10);
minQuality = quality < minQuality ? quality : minQuality;
});
$.map($('#upgrade-quality').find('a.btn'), function(btn){
btn$ = $(btn);
quality = parseInt(btn$.data('quality'), 10);
upgrade$ = $('#upgrade-qualities');
if(quality <= minQuality){
if(btn$.hasClass('active') // then btn is about to changed state so reflect change to select option
|| 1 === upgrade$.find('option[value="' + quality + '"]:selected').length){
upgrade$.find('option[value="' + quality + '"]').prop('selected', !1);
}
btn$.removeClass('active').addClass('disabled');
} else if(btn$.hasClass('disabled')){
btn$.removeClass('disabled');
}
});
}
$(function(){
var elQualityPreset = $('#quality-preset'), var elQualityPreset = $('#quality-preset'),
selected = ':selected'; selected = ':selected';
elQualityPreset.change(function() { elQualityPreset.change(function(){
setFromPresets($(this).find(selected).val()); setFromPresets($(this).find(selected).val());
}); });
setFromPresets(elQualityPreset.find(selected).val()); setFromPresets(elQualityPreset.find(selected).val());
$('#initial-qualities').change(function() { $('#wanted-qualities').change(function(){
presentTips(); presentTips();
}); });
$('#custom-quality').find('a[href="#"].btn').on('click', function(event){ $('#custom-quality').find('a[href="#"].btn').on('click', function(event){
event.stopPropagation(); event.stopPropagation();
var active$ = $('#wanted-quality').find('a.btn.active'), num_active = active$.length;
$(this).toggleClass('active'); if(1 < num_active || (1 === num_active && $(this).data('quality') !== active$.data('quality'))){
var select$ = $('initial-quality' === $(this).closest('.component-desc').attr('id') ? '#initial-qualities' : '#upgrade-qualities'), $(this).toggleClass('active');
quality = $(this).data('quality'), arrSelected = $.map(select$.val(), function(v){return parseInt(v, 10)}) || Array();
var isInit = 'wanted-quality' === $(this).closest('.component-desc').attr('id'),
select$ = $(isInit ? '#wanted-qualities' : '#upgrade-qualities'),
quality = $(this).data('quality'),
arrSelected = $.map(select$.val(), function (v){
return parseInt(v, 10)
}) || Array();
if($(this).hasClass('active')){
arrSelected.push(quality);
} else {
arrSelected = arrSelected.filter(function (elem){
return elem !== quality;
});
}
select$.val(arrSelected).change();
if(isInit){
refreshUpgrades();
}
presentTips();
if($(this).hasClass('active')){
arrSelected.push(quality);
} else {
arrSelected = arrSelected.filter(function(elem){
return elem !== quality;
});
} }
select$.val(arrSelected).change();
presentTips();
return !1; return !1;
}); });
}); });

View file

@ -177,10 +177,11 @@ class ShowQueue(generic_queue.GenericQueue):
def addShow(self, indexer, indexer_id, showDir, default_status=None, quality=None, flatten_folders=None, def addShow(self, indexer, indexer_id, showDir, default_status=None, quality=None, flatten_folders=None,
lang='en', subtitles=None, anime=None, scene=None, paused=None, blacklist=None, whitelist=None, lang='en', subtitles=None, anime=None, scene=None, paused=None, blacklist=None, whitelist=None,
wanted_begin=None, wanted_latest=None, tag=None, new_show=False, show_name=None): wanted_begin=None, wanted_latest=None, tag=None, new_show=False, show_name=None, upgrade_once=False):
queueItemObj = QueueItemAdd(indexer, indexer_id, showDir, default_status, quality, flatten_folders, lang, queueItemObj = QueueItemAdd(indexer, indexer_id, showDir, default_status, quality, flatten_folders, lang,
subtitles, anime, scene, paused, blacklist, whitelist, subtitles, anime, scene, paused, blacklist, whitelist,
wanted_begin, wanted_latest, tag, new_show=new_show, show_name=show_name) wanted_begin, wanted_latest, tag,
new_show=new_show, show_name=show_name, upgrade_once=upgrade_once)
self.add_item(queueItemObj) self.add_item(queueItemObj)
@ -238,7 +239,7 @@ class ShowQueueItem(generic_queue.QueueItem):
class QueueItemAdd(ShowQueueItem): class QueueItemAdd(ShowQueueItem):
def __init__(self, indexer, indexer_id, showDir, default_status, quality, flatten_folders, lang, subtitles, anime, def __init__(self, indexer, indexer_id, showDir, default_status, quality, flatten_folders, lang, subtitles, anime,
scene, paused, blacklist, whitelist, default_wanted_begin, default_wanted_latest, tag, scene, paused, blacklist, whitelist, default_wanted_begin, default_wanted_latest, tag,
scheduled_update=False, new_show=False, show_name=None): scheduled_update=False, new_show=False, show_name=None, upgrade_once=False):
self.indexer = indexer self.indexer = indexer
self.indexer_id = indexer_id self.indexer_id = indexer_id
@ -247,6 +248,7 @@ class QueueItemAdd(ShowQueueItem):
self.default_wanted_begin = default_wanted_begin self.default_wanted_begin = default_wanted_begin
self.default_wanted_latest = default_wanted_latest self.default_wanted_latest = default_wanted_latest
self.quality = quality self.quality = quality
self.upgrade_once = upgrade_once
self.flatten_folders = flatten_folders self.flatten_folders = flatten_folders
self.lang = lang self.lang = lang
self.subtitles = subtitles self.subtitles = subtitles
@ -341,6 +343,7 @@ class QueueItemAdd(ShowQueueItem):
self.show.location = self.showDir self.show.location = self.showDir
self.show.subtitles = self.subtitles if None is not self.subtitles else sickbeard.SUBTITLES_DEFAULT self.show.subtitles = self.subtitles if None is not self.subtitles else sickbeard.SUBTITLES_DEFAULT
self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
self.show.upgrade_once = self.upgrade_once
self.show.flatten_folders = self.flatten_folders if None is not self.flatten_folders else sickbeard.FLATTEN_FOLDERS_DEFAULT self.show.flatten_folders = self.flatten_folders if None is not self.flatten_folders else sickbeard.FLATTEN_FOLDERS_DEFAULT
self.show.anime = self.anime if None is not self.anime else sickbeard.ANIME_DEFAULT self.show.anime = self.anime if None is not self.anime else sickbeard.ANIME_DEFAULT
self.show.scene = self.scene if None is not self.scene else sickbeard.SCENE_DEFAULT self.show.scene = self.scene if None is not self.scene else sickbeard.SCENE_DEFAULT

View file

@ -3638,7 +3638,8 @@ class NewHomeAddShows(Home):
return t.respond() return t.respond()
def addNewShow(self, whichSeries=None, indexerLang='en', rootDir=None, defaultStatus=None, def addNewShow(self, whichSeries=None, indexerLang='en', rootDir=None, defaultStatus=None,
quality_preset=None, anyQualities=None, bestQualities=None, flatten_folders=None, subtitles=None, quality_preset=None, anyQualities=None, bestQualities=None, upgrade_once=None,
flatten_folders=None, subtitles=None,
fullShowPath=None, other_shows=None, skipShow=None, providedIndexer=None, anime=None, fullShowPath=None, other_shows=None, skipShow=None, providedIndexer=None, anime=None,
scene=None, blacklist=None, whitelist=None, wanted_begin=None, wanted_latest=None, tag=None, scene=None, blacklist=None, whitelist=None, wanted_begin=None, wanted_latest=None, tag=None,
return_to=None, cancel_form=None): return_to=None, cancel_form=None):
@ -3747,6 +3748,7 @@ class NewHomeAddShows(Home):
if type(bestQualities) != list: if type(bestQualities) != list:
bestQualities = [bestQualities] bestQualities = [bestQualities]
newQuality = Quality.combineQualities(map(int, anyQualities), map(int, bestQualities)) newQuality = Quality.combineQualities(map(int, anyQualities), map(int, bestQualities))
upgrade_once = config.checkbox_to_value(upgrade_once)
wanted_begin = config.minimax(wanted_begin, 0, -1, 10) wanted_begin = config.minimax(wanted_begin, 0, -1, 10)
wanted_latest = config.minimax(wanted_latest, 0, -1, 10) wanted_latest = config.minimax(wanted_latest, 0, -1, 10)
@ -3756,7 +3758,7 @@ class NewHomeAddShows(Home):
flatten_folders, indexerLang, subtitles, anime, flatten_folders, indexerLang, subtitles, anime,
scene, None, blacklist, whitelist, scene, None, blacklist, whitelist,
wanted_begin, wanted_latest, tag, new_show=new_show, wanted_begin, wanted_latest, tag, new_show=new_show,
show_name=show_name) # @UndefinedVariable show_name=show_name, upgrade_once=upgrade_once)
# ui.notifications.message('Show added', 'Adding the specified show into ' + show_dir) # ui.notifications.message('Show added', 'Adding the specified show into ' + show_dir)
return finishAddShow() return finishAddShow()