mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-07 10:33:38 +00:00
Change show search, add options to choose order of search results.
Add option to sort search results by 'A to Z' or 'First aired'. Add option to sort search results by 'Relevancy' using Fuzzywuzzy lib. Change search result anchor text uses SORT_ARTICLE setting for display. Change add server side search result ordering. Change use iteritems instead of items to improve performance. Change existing shows in DB are no longer selectable in result list. Change add image to search result item hover over. Change improve image load speed on browse Trakt/IMDb/AniDB pages. Change PEP8.
This commit is contained in:
parent
07d72e05f1
commit
11711b2238
10 changed files with 233 additions and 53 deletions
10
CHANGES.md
10
CHANGES.md
|
@ -89,6 +89,16 @@
|
||||||
* Add new parameter 'poster' to indexer api
|
* Add new parameter 'poster' to indexer api
|
||||||
* Add optional tvdb_api load season image: lINDEXER_API_PARMS['seasons'] = True
|
* Add optional tvdb_api load season image: lINDEXER_API_PARMS['seasons'] = True
|
||||||
* Add optional tvdb_api load season wide image: lINDEXER_API_PARMS['seasonwides'] = True
|
* Add optional tvdb_api load season wide image: lINDEXER_API_PARMS['seasonwides'] = True
|
||||||
|
* Add Fuzzywuzzy 0.15.1 to sort search results
|
||||||
|
* Change remove search results filtering from tv info source
|
||||||
|
* Change suppress startup warnings for Fuzzywuzzy and Cheetah libs
|
||||||
|
* Change show search, add options to choose order of search results
|
||||||
|
* Add option to sort search results by 'A to Z' or 'First aired'
|
||||||
|
* Add option to sort search results by 'Relevancy' using Fuzzywuzzy lib
|
||||||
|
* Change search result anchor text uses SORT_ARTICLE setting for display
|
||||||
|
* Change existing shows in DB are no longer selectable in result list
|
||||||
|
* Change add image to search result item hover over
|
||||||
|
* Change improve image load speed on browse Trakt/IMDb/AniDB pages
|
||||||
|
|
||||||
|
|
||||||
[develop changelog]
|
[develop changelog]
|
||||||
|
|
|
@ -1289,6 +1289,7 @@ input sizing (for config pages)
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
.showlist-select optgroup,
|
.showlist-select optgroup,
|
||||||
|
#results-sortby optgroup,
|
||||||
#pickShow optgroup,
|
#pickShow optgroup,
|
||||||
#showfilter optgroup,
|
#showfilter optgroup,
|
||||||
#showsort optgroup,
|
#showsort optgroup,
|
||||||
|
@ -1298,6 +1299,7 @@ input sizing (for config pages)
|
||||||
}
|
}
|
||||||
|
|
||||||
.showlist-select optgroup option,
|
.showlist-select optgroup option,
|
||||||
|
#results-sortby optgroup option,
|
||||||
#pickShow optgroup option,
|
#pickShow optgroup option,
|
||||||
#showfilter optgroup option,
|
#showfilter optgroup option,
|
||||||
#showsort optgroup option,
|
#showsort optgroup option,
|
||||||
|
|
|
@ -1254,6 +1254,7 @@ input sizing (for config pages)
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
.showlist-select optgroup,
|
.showlist-select optgroup,
|
||||||
|
#results-sortby optgroup,
|
||||||
#pickShow optgroup,
|
#pickShow optgroup,
|
||||||
#showfilter optgroup,
|
#showfilter optgroup,
|
||||||
#showsort optgroup,
|
#showsort optgroup,
|
||||||
|
@ -1263,6 +1264,7 @@ input sizing (for config pages)
|
||||||
}
|
}
|
||||||
|
|
||||||
.showlist-select optgroup option,
|
.showlist-select optgroup option,
|
||||||
|
#results-sortby optgroup option,
|
||||||
#pickShow optgroup option,
|
#pickShow optgroup option,
|
||||||
#showfilter optgroup option,
|
#showfilter optgroup option,
|
||||||
#showsort optgroup option,
|
#showsort optgroup option,
|
||||||
|
|
|
@ -1113,11 +1113,16 @@ div.formpaginate{
|
||||||
margin-left:10px
|
margin-left:10px
|
||||||
}
|
}
|
||||||
|
|
||||||
.stepDiv #searchResults div{
|
.stepDiv #searchResults .results-item{
|
||||||
|
width:100%;
|
||||||
line-height:1.7
|
line-height:1.7
|
||||||
}
|
}
|
||||||
|
|
||||||
.stepDiv #searchResults div .exists-db{
|
.stepDiv #searchResults .results-item input[disabled=disabled]{
|
||||||
|
visibility:hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepDiv #searchResults .results-item .exists-db{
|
||||||
font-weight:800;
|
font-weight:800;
|
||||||
font-style:italic
|
font-style:italic
|
||||||
}
|
}
|
||||||
|
@ -1126,6 +1131,11 @@ div.formpaginate{
|
||||||
margin-right:6px
|
margin-right:6px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a span.article,
|
||||||
|
a:hover span.article{
|
||||||
|
color:#2f4799
|
||||||
|
}
|
||||||
|
|
||||||
.stepone-result-title{
|
.stepone-result-title{
|
||||||
font-weight:600;
|
font-weight:600;
|
||||||
margin-left:10px
|
margin-left:10px
|
||||||
|
@ -2785,6 +2795,7 @@ config*.tmpl
|
||||||
padding-top:10px
|
padding-top:10px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select .selected-text,
|
||||||
select .selected{
|
select .selected{
|
||||||
font-weight:700;
|
font-weight:700;
|
||||||
color:#888
|
color:#888
|
||||||
|
|
BIN
gui/slick/images/image-light.png
Normal file
BIN
gui/slick/images/image-light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 215 B |
|
@ -15,7 +15,11 @@
|
||||||
#set indexer_count = len([$i for $i in $sickbeard.indexerApi().indexers if $sickbeard.indexerApi(i).config.get('active', False) and not $sickbeard.indexerApi(i).config.get('defunct', False)]) + 1
|
#set indexer_count = len([$i for $i in $sickbeard.indexerApi().indexers if $sickbeard.indexerApi(i).config.get('active', False) and not $sickbeard.indexerApi(i).config.get('defunct', False)]) + 1
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var show_scene_maps = ${show_scene_maps}
|
var show_scene_maps = ${show_scene_maps},
|
||||||
|
config = {
|
||||||
|
sortArticle: #echo ['!1','!0'][$sg_var('SORT_ARTICLE')]#,
|
||||||
|
resultsSortby: '#echo $sg_str('RESULTS_SORTBY', 'rel')#'
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript" src="$sbRoot/js/formwizard.js?v=$sbPID"></script>
|
<script type="text/javascript" src="$sbRoot/js/formwizard.js?v=$sbPID"></script>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/** @namespace config.sortArticle */
|
||||||
|
/** @namespace config.resultsSortby */
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
function populateLangSelect() {
|
function populateLangSelect() {
|
||||||
|
@ -71,59 +73,146 @@ $(document).ready(function () {
|
||||||
$('#searchResults').empty().html('search timed out, try again or try another database');
|
$('#searchResults').empty().html('search timed out, try again or try another database');
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
var resultStr = '', checked = '', rowType, row = 0;
|
var resultStr = '', attrs = '', checked = !1, rowType, row = 0, srcState = '';
|
||||||
|
|
||||||
if (0 === data.results.length) {
|
if (0 === data.results.length) {
|
||||||
resultStr += '<span class="boldest">Sorry, no results found. Try a different search.</span>';
|
resultStr += '<span class="boldest">Sorry, no results found. Try a different search.</span>';
|
||||||
} else {
|
} else {
|
||||||
var idxSrcDB = 0, idxSrcDBId = 1, idxSrcUrl = 2, idxShowID = 3, idxTitle = 4, idxTitleHtml = 5,
|
var result = {
|
||||||
idxDate = 6, idxNetwork = 7, idxGenres = 8, idxOverview = 9;
|
SrcName: 0, isInDB: 1, SrcId: 2, SrcDBId: 3, SrcUrl: 4, ShowID: 5, Title: 6, TitleHtml: 7,
|
||||||
$.each(data.results, function (index, obj) {
|
Aired: 8, Network: 9, Genre: 10, Overview: 11, RelSort: 12, DateSort: 13, AzSort: 14, ImgUrl: 15
|
||||||
checked = (0 == row ? ' checked' : '');
|
};
|
||||||
rowType = (0 == row % 2 ? '' : ' class="alt"');
|
$.each(data.results, function (index, item) {
|
||||||
|
attrs = (!0 === item[result.isInDB] ? ' disabled="disabled"' : (!0 === checked ? '' : ' checked'));
|
||||||
|
checked = (' checked' === attrs) ? !0 : checked;
|
||||||
|
rowType = (0 == row % 2 ? '' : ' alt');
|
||||||
row++;
|
row++;
|
||||||
|
|
||||||
var display_show_name = cleanseText(obj[idxTitle], !0), showstartdate = '';
|
var displayShowName = cleanseText(item[result.Title], !0), showstartdate = '';
|
||||||
|
|
||||||
if (null !== obj[idxDate]) {
|
if (null !== item[result.Aired]) {
|
||||||
var startDate = new Date(obj[idxDate]);
|
var startDate = new Date(item[result.Aired]);
|
||||||
var today = new Date();
|
var today = new Date();
|
||||||
showstartdate = ' <span class="stepone-result-date">('
|
showstartdate = ' <span class="stepone-result-date">('
|
||||||
+ (startDate > today ? 'will debut' : 'started')
|
+ (startDate > today ? 'will debut' : 'started')
|
||||||
+ ': ' + obj[idxDate] + ')</span>';
|
+ ': ' + item[result.Aired] + ')</span>';
|
||||||
}
|
}
|
||||||
resultStr += '<div' + rowType + '>'
|
|
||||||
|
srcState = [
|
||||||
|
null === item[result.SrcName] ? '' : item[result.SrcName],
|
||||||
|
!1 === item[result.isInDB] ? '' : '<span class="exists-db">exists in db</span>']
|
||||||
|
.join(' - ').replace(/(^[\s-]+|[\s-]+$)/, '');
|
||||||
|
resultStr += '<div class="results-item' + rowType + '" data-indb="' + (!1 === item[result.isInDB] ? '' : '1') + '" data-sort-rel="' + item[result.RelSort] + '" data-sort-date="' + item[result.DateSort] + '" data-sort-az="' + item[result.AzSort] + '">'
|
||||||
+ '<input id="whichSeries" type="radio"'
|
+ '<input id="whichSeries" type="radio"'
|
||||||
+ ' class="stepone-result-radio"'
|
+ ' class="stepone-result-radio"'
|
||||||
+ ' title="Add show <span style=\'color: rgb(66, 139, 202)\'>' + display_show_name + '</span>"'
|
+ (!1 === item[result.isInDB]
|
||||||
|
? ' title="Add show <span style=\'color: rgb(66, 139, 202)\'>' + displayShowName + '</span>"'
|
||||||
|
: ' title="Show exists in DB,<br><span style=\'font-weight:700\'>selection not possible</span>"')
|
||||||
+ ' name="whichSeries"'
|
+ ' name="whichSeries"'
|
||||||
+ ' value="' + cleanseText([obj[idxSrcDBId], obj[idxSrcDB], obj[idxShowID], obj[idxTitle]].join('|'), !0) + '"'
|
+ ' value="' + cleanseText([item[result.SrcDBId], item[result.SrcName], item[result.ShowID], item[result.Title]].join('|'), !0) + '"'
|
||||||
+ checked
|
+ attrs
|
||||||
+ ' />'
|
+ ' />'
|
||||||
+ '<a'
|
+ '<a'
|
||||||
+ ' class="stepone-result-title"'
|
+ ' class="stepone-result-title"'
|
||||||
+ ' title="<div style=\'color: rgb(66, 139, 202)\'>' + cleanseText(obj[idxTitleHtml], !0) + '</div>'
|
+ ' title="<div style=\'color: rgb(66, 139, 202)\'>' + cleanseText(item[result.TitleHtml], !0) + '</div>'
|
||||||
+ (0 < obj[idxGenres].length ? '<div style=\'font-weight:bold\'>(<em>' + obj[idxGenres] + '</em>)</div>' : '')
|
+ (0 < item[result.Genre].length ? '<div style=\'font-weight:bold\'>(<em>' + item[result.Genre] + '</em>)</div>' : '')
|
||||||
+ (0 < obj[idxNetwork].length ? '<div style=\'font-weight:bold;font-size:0.9em;color:#888\'><em>' + obj[idxNetwork] + '</em></div>' : '')
|
+ (0 < item[result.Network].length ? '<div style=\'font-weight:bold;font-size:0.9em;color:#888\'><em>' + item[result.Network] + '</em></div>' : '')
|
||||||
+ (0 < obj[idxOverview].length ? '<p style=\'margin:0 0 2px\'>' + obj[idxOverview] + '</p>' : '')
|
+ '<img style=\'max-height:150px;float:right;margin-left:3px\' src=\'/' + item[result.ImgUrl] + '\'>'
|
||||||
+ '<span style=\'float:right\'>Click for more</span>'
|
+ (0 < item[result.Overview].length ? '<p style=\'margin:0 0 2px\'>' + item[result.Overview] + '</p>' : '')
|
||||||
|
+ '<span style=\'float:right;clear:both\'>Click for more</span>'
|
||||||
+ '"'
|
+ '"'
|
||||||
+ ' href="' + anonURL + obj[idxSrcUrl] + obj[idxShowID] + ((data.langid && '' != data.langid) ? '&lid=' + data.langid : '') + '"'
|
+ ' href="' + anonURL + item[result.SrcUrl] + item[result.ShowID] + ((data.langid && '' != data.langid) ? '&lid=' + data.langid : '') + '"'
|
||||||
+ ' onclick="window.open(this.href, \'_blank\'); return false;"'
|
+ ' onclick="window.open(this.href, \'_blank\'); return false;"'
|
||||||
+ '>' + display_show_name + '</a>'
|
+ '>' + (config.sortArticle ? displayShowName : displayShowName.replace(/^((?:A(?!\s+to)n?)|The)(\s)+(.*)/i, '$3$2<span class="article">($1)</span>')) + '</a>'
|
||||||
+ showstartdate
|
+ showstartdate
|
||||||
+ (null == obj[idxSrcDB] ? ''
|
+ ('' === srcState ? ''
|
||||||
: ' <span class="stepone-result-db grey-text">' + '[' + obj[idxSrcDB] + ']' + '</span>')
|
: ' <span class="stepone-result-db grey-text">' + '[' + srcState + ']' + '</span>')
|
||||||
+ '</div>' + "\n";
|
+ '</div>' + "\n";
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
var selAttr = 'selected="selected" ',
|
||||||
|
selClass = 'selected-text',
|
||||||
|
classAttrSel = 'class="' + selClass + '" ',
|
||||||
|
defSortby = /^az/.test(config.resultsSortby) || /^date/.test(config.resultsSortby) ? '': classAttrSel + selAttr;
|
||||||
|
|
||||||
$('#searchResults').html(
|
$('#searchResults').html(
|
||||||
'<fieldset>' + "\n" + '<legend class="legendStep" style="margin-bottom: 15px">'
|
'<fieldset>' + "\n" + '<legend class="legendStep" style="margin-bottom: 15px">'
|
||||||
+ (0 < row ? row : 'No')
|
+ (0 < row ? row : 'No')
|
||||||
+ ' search result' + (1 == row ? '' : 's') + '...</legend>' + "\n"
|
+ ' search result' + (1 == row ? '' : 's') + '...'
|
||||||
|
+ '<span style="float:right;height:32px;line-height:1">'
|
||||||
|
+ '<select id="results-sortby" class="form-control form-control-inline input-sm">'
|
||||||
|
+ '<optgroup label="Sort by">'
|
||||||
|
+ '<option ' + (/^az/.test(config.resultsSortby) ? classAttrSel + selAttr : '') + 'value="az">A to Z</option>'
|
||||||
|
+ '<option ' + (/^date/.test(config.resultsSortby) ? classAttrSel + selAttr : '') + 'value="date">First aired</option>'
|
||||||
|
+ '<option ' + defSortby + 'value="rel">Relevancy</option>'
|
||||||
|
+ '</optgroup><optgroup label="With...">'
|
||||||
|
+ '<option ' + (!/notop$/.test(config.resultsSortby) ? classAttrSel : '') + 'value="ontop">Exists on top</option>'
|
||||||
|
+ '<option ' + (/notop$/.test(config.resultsSortby) ? classAttrSel : '') + 'value="notop">Exists in mix</option>'
|
||||||
|
+ '</optgroup></select></span>'
|
||||||
|
+ '</legend>' + "\n"
|
||||||
|
+ '<div id="holder">'
|
||||||
+ resultStr
|
+ resultStr
|
||||||
|
+ '</div>'
|
||||||
+ '</fieldset>'
|
+ '</fieldset>'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var container$ = $('#holder'),
|
||||||
|
sortbySelect$ = $('#results-sortby'),
|
||||||
|
reOrder = (function(value){
|
||||||
|
return ($('#results-sortby').find('option[value$="notop"]').hasClass(selClass)
|
||||||
|
? (1000 > value ? value + 1000 : value)
|
||||||
|
: (1000 > value ? value : value - 1000))}),
|
||||||
|
getData = (function(itemElem, sortby){
|
||||||
|
var position = parseInt($(itemElem).attr('data-sort-' + sortby));
|
||||||
|
return (!$(itemElem).attr('data-indb')) ? position : reOrder(position);
|
||||||
|
});
|
||||||
|
|
||||||
|
sortbySelect$.find('.' + selClass).each(function(){
|
||||||
|
$(this).html('> ' + $(this).html());
|
||||||
|
});
|
||||||
|
|
||||||
|
container$.isotope({
|
||||||
|
itemSelector: '.results-item',
|
||||||
|
sortBy: sortbySelect$.find('option:not([value$="top"]).' + selClass).val(),
|
||||||
|
layoutMode: 'masonry',
|
||||||
|
getSortData: {
|
||||||
|
az: function(itemElem){ return getData(itemElem, 'az'); },
|
||||||
|
date: function(itemElem){ return getData(itemElem, 'date'); },
|
||||||
|
rel: function(itemElem){ return getData(itemElem, 'rel'); }
|
||||||
|
}
|
||||||
|
}).on('arrangeComplete', function(event, items){
|
||||||
|
$(items).each(function(i, item){
|
||||||
|
if (1 === i % 2){
|
||||||
|
$(item.element).addClass('alt');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
sortbySelect$.on('change', function(){
|
||||||
|
var selectedSort = String($(this).val()), sortby = selectedSort, curSortby$, curSel$, newSel$;
|
||||||
|
|
||||||
|
curSortby$ = $(this).find('option:not([value$="top"])');
|
||||||
|
if (/top$/.test(selectedSort)){
|
||||||
|
sortby = curSortby$.filter('.' + selClass).val();
|
||||||
|
curSortby$ = $(this).find('option[value$="top"]');
|
||||||
|
}
|
||||||
|
curSel$ = curSortby$.filter('.' + selClass);
|
||||||
|
curSel$.html(curSel$.html().replace(/(?:>|>)\s/ , '')).removeClass(selClass);
|
||||||
|
|
||||||
|
newSel$ = $(this).find('option[value$="' + selectedSort + '"]');
|
||||||
|
newSel$.html('> ' + newSel$.html()).addClass(selClass);
|
||||||
|
|
||||||
|
$('.results-item[data-indb="1"]').each(function(){
|
||||||
|
$(this).attr(sortby, reOrder(parseInt($(this).attr(sortby), 10)));
|
||||||
|
});
|
||||||
|
$('.results-item').removeClass('alt');
|
||||||
|
container$.isotope('updateSortData').isotope({sortBy: sortby});
|
||||||
|
|
||||||
|
config.resultsSortby = sortby + ($(this).find('option[value$="notop"]').hasClass(selClass) ? ' notop' : '');
|
||||||
|
$.get(sbRoot + '/config/general/saveResultPrefs', {ui_results_sortby: selectedSort});
|
||||||
|
});
|
||||||
|
|
||||||
updateSampleText();
|
updateSampleText();
|
||||||
myform.loadsection(0);
|
myform.loadsection(0);
|
||||||
$('.stepone-result-radio, .stepone-result-title').each(addQTip);
|
$('.stepone-result-radio, .stepone-result-title').each(addQTip);
|
||||||
|
|
|
@ -167,6 +167,8 @@ METADATA_TIVO = None
|
||||||
METADATA_MEDE8ER = None
|
METADATA_MEDE8ER = None
|
||||||
METADATA_KODI = None
|
METADATA_KODI = None
|
||||||
|
|
||||||
|
RESULTS_SORTBY = None
|
||||||
|
|
||||||
QUALITY_DEFAULT = None
|
QUALITY_DEFAULT = None
|
||||||
STATUS_DEFAULT = None
|
STATUS_DEFAULT = None
|
||||||
WANTED_BEGIN_DEFAULT = None
|
WANTED_BEGIN_DEFAULT = None
|
||||||
|
@ -536,6 +538,8 @@ def initialize(console_logging=True):
|
||||||
versionCheckScheduler, showQueueScheduler, searchQueueScheduler, \
|
versionCheckScheduler, showQueueScheduler, searchQueueScheduler, \
|
||||||
properFinderScheduler, autoPostProcesserScheduler, subtitlesFinderScheduler, background_mapping_task, \
|
properFinderScheduler, autoPostProcesserScheduler, subtitlesFinderScheduler, background_mapping_task, \
|
||||||
provider_ping_thread_pool
|
provider_ping_thread_pool
|
||||||
|
# Add Show Search
|
||||||
|
global RESULTS_SORTBY
|
||||||
# Add Show Defaults
|
# Add Show Defaults
|
||||||
global STATUS_DEFAULT, QUALITY_DEFAULT, SHOW_TAG_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, \
|
global STATUS_DEFAULT, QUALITY_DEFAULT, SHOW_TAG_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, \
|
||||||
WANTED_BEGIN_DEFAULT, WANTED_LATEST_DEFAULT, SCENE_DEFAULT, ANIME_DEFAULT
|
WANTED_BEGIN_DEFAULT, WANTED_LATEST_DEFAULT, SCENE_DEFAULT, ANIME_DEFAULT
|
||||||
|
@ -754,6 +758,8 @@ def initialize(console_logging=True):
|
||||||
if not re.match(r'\d+\|[^|]+(?:\|[^|]+)*', ROOT_DIRS):
|
if not re.match(r'\d+\|[^|]+(?:\|[^|]+)*', ROOT_DIRS):
|
||||||
ROOT_DIRS = ''
|
ROOT_DIRS = ''
|
||||||
|
|
||||||
|
RESULTS_SORTBY = check_setting_str(CFG, 'General', 'results_sortby', '')
|
||||||
|
|
||||||
QUALITY_DEFAULT = check_setting_int(CFG, 'General', 'quality_default', SD)
|
QUALITY_DEFAULT = check_setting_int(CFG, 'General', 'quality_default', SD)
|
||||||
STATUS_DEFAULT = check_setting_int(CFG, 'General', 'status_default', SKIPPED)
|
STATUS_DEFAULT = check_setting_int(CFG, 'General', 'status_default', SKIPPED)
|
||||||
WANTED_BEGIN_DEFAULT = check_setting_int(CFG, 'General', 'wanted_begin_default', 0)
|
WANTED_BEGIN_DEFAULT = check_setting_int(CFG, 'General', 'wanted_begin_default', 0)
|
||||||
|
@ -1512,6 +1518,7 @@ def save_config():
|
||||||
new_config['General']['recentsearch_startup'] = int(RECENTSEARCH_STARTUP)
|
new_config['General']['recentsearch_startup'] = int(RECENTSEARCH_STARTUP)
|
||||||
new_config['General']['backlog_nofull'] = int(BACKLOG_NOFULL)
|
new_config['General']['backlog_nofull'] = int(BACKLOG_NOFULL)
|
||||||
new_config['General']['skip_removed_files'] = int(SKIP_REMOVED_FILES)
|
new_config['General']['skip_removed_files'] = int(SKIP_REMOVED_FILES)
|
||||||
|
new_config['General']['results_sortby'] = str(RESULTS_SORTBY)
|
||||||
new_config['General']['quality_default'] = int(QUALITY_DEFAULT)
|
new_config['General']['quality_default'] = int(QUALITY_DEFAULT)
|
||||||
new_config['General']['status_default'] = int(STATUS_DEFAULT)
|
new_config['General']['status_default'] = int(STATUS_DEFAULT)
|
||||||
new_config['General']['wanted_begin_default'] = int(WANTED_BEGIN_DEFAULT)
|
new_config['General']['wanted_begin_default'] = int(WANTED_BEGIN_DEFAULT)
|
||||||
|
|
|
@ -1108,13 +1108,6 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
|
||||||
2) Return True/False if success after using kwargs 'savefile' set to file pathname.
|
2) Return True/False if success after using kwargs 'savefile' set to file pathname.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# download and save file or simply fetch url
|
|
||||||
savename = None
|
|
||||||
if 'savename' in kwargs:
|
|
||||||
# session streaming
|
|
||||||
session.stream = True
|
|
||||||
savename = kwargs.pop('savename')
|
|
||||||
|
|
||||||
# selectively mute some errors
|
# selectively mute some errors
|
||||||
mute = []
|
mute = []
|
||||||
for muted in filter(
|
for muted in filter(
|
||||||
|
@ -1126,6 +1119,13 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
|
||||||
if None is session:
|
if None is session:
|
||||||
session = CloudflareScraper.create_scraper()
|
session = CloudflareScraper.create_scraper()
|
||||||
|
|
||||||
|
# download and save file or simply fetch url
|
||||||
|
savename = None
|
||||||
|
if 'savename' in kwargs:
|
||||||
|
# session streaming
|
||||||
|
session.stream = True
|
||||||
|
savename = kwargs.pop('savename')
|
||||||
|
|
||||||
if 'nocache' in kwargs:
|
if 'nocache' in kwargs:
|
||||||
del kwargs['nocache']
|
del kwargs['nocache']
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -2560,8 +2560,9 @@ class NewHomeAddShows(Home):
|
||||||
def sanitizeFileName(self, name):
|
def sanitizeFileName(self, name):
|
||||||
return helpers.sanitizeFileName(name)
|
return helpers.sanitizeFileName(name)
|
||||||
|
|
||||||
|
# noinspection PyPep8Naming
|
||||||
def searchIndexersForShowName(self, search_term, lang='en', indexer=None):
|
def searchIndexersForShowName(self, search_term, lang='en', indexer=None):
|
||||||
if not lang or lang == 'null':
|
if not lang or 'null' == lang:
|
||||||
lang = 'en'
|
lang = 'en'
|
||||||
term = search_term.decode('utf-8').strip()
|
term = search_term.decode('utf-8').strip()
|
||||||
terms = []
|
terms = []
|
||||||
|
@ -2595,7 +2596,7 @@ class NewHomeAddShows(Home):
|
||||||
except (StandardError, Exception):
|
except (StandardError, Exception):
|
||||||
search_term = (search_term, '')['tt' in search_id]
|
search_term = (search_term, '')['tt' in search_id]
|
||||||
|
|
||||||
# Query Indexers for each search term and build the list of results
|
# query Indexers for search term and build list of results
|
||||||
for indexer in sickbeard.indexerApi().indexers if not int(indexer) else [int(indexer)]:
|
for indexer in sickbeard.indexerApi().indexers if not int(indexer) else [int(indexer)]:
|
||||||
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
||||||
lINDEXER_API_PARMS['language'] = lang
|
lINDEXER_API_PARMS['language'] = lang
|
||||||
|
@ -2608,7 +2609,7 @@ class NewHomeAddShows(Home):
|
||||||
logger.log('Fetching show using id: %s (%s) from tv datasource %s' % (
|
logger.log('Fetching show using id: %s (%s) from tv datasource %s' % (
|
||||||
search_id, search_term, sickbeard.indexerApi(indexer).name), logger.DEBUG)
|
search_id, search_term, sickbeard.indexerApi(indexer).name), logger.DEBUG)
|
||||||
r = t[indexer_id, False]
|
r = t[indexer_id, False]
|
||||||
results.setdefault('tt' in search_id and INDEXER_TVDB_X or indexer, {})[int(indexer_id)] = {
|
results.setdefault((indexer, INDEXER_TVDB_X)['tt' in search_id], {})[int(indexer_id)] = {
|
||||||
'id': indexer_id, 'seriesname': r['seriesname'], 'firstaired': r['firstaired'],
|
'id': indexer_id, 'seriesname': r['seriesname'], 'firstaired': r['firstaired'],
|
||||||
'network': r['network'], 'overview': r['overview'],
|
'network': r['network'], 'overview': r['overview'],
|
||||||
'genres': '' if not r['genre'] else r['genre'].lower().strip('|').replace('|', ', '),
|
'genres': '' if not r['genre'] else r['genre'].lower().strip('|').replace('|', ', '),
|
||||||
|
@ -2632,7 +2633,7 @@ class NewHomeAddShows(Home):
|
||||||
except (StandardError, Exception):
|
except (StandardError, Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Query trakt for tvdb ids
|
# query trakt for tvdb ids
|
||||||
try:
|
try:
|
||||||
logger.log('Searching for show using search term: %s from tv datasource Trakt' % search_term, logger.DEBUG)
|
logger.log('Searching for show using search term: %s from tv datasource Trakt' % search_term, logger.DEBUG)
|
||||||
resp = []
|
resp = []
|
||||||
|
@ -2674,34 +2675,74 @@ class NewHomeAddShows(Home):
|
||||||
for iid, name in sickbeard.indexerApi().all_indexers.iteritems()}
|
for iid, name in sickbeard.indexerApi().all_indexers.iteritems()}
|
||||||
# noinspection PyUnboundLocalVariable
|
# noinspection PyUnboundLocalVariable
|
||||||
map(final_results.extend,
|
map(final_results.extend,
|
||||||
([['%s%s' % (id_names[id], helpers.find_show_by_id(sickbeard.showList, {(id, INDEXER_TVDB)[id == INDEXER_TVDB_X]: int(show['id'])}, no_mapped_ids=False) and ' - <span class="exists-db">exists in db</span>' or ''),
|
([[id_names[iid], any([helpers.find_show_by_id(
|
||||||
(id, INDEXER_TVDB)[id == INDEXER_TVDB_X], sickbeard.indexerApi((id, INDEXER_TVDB)[id == INDEXER_TVDB_X]).config['show_url'], int(show['id']),
|
sickbeard.showList, {(iid, INDEXER_TVDB)[INDEXER_TVDB_X == iid]: int(show['id'])},
|
||||||
|
no_mapped_ids=False)]),
|
||||||
|
iid, (iid, INDEXER_TVDB)[INDEXER_TVDB_X == iid],
|
||||||
|
sickbeard.indexerApi((iid, INDEXER_TVDB)[INDEXER_TVDB_X == iid]).config['show_url'], int(show['id']),
|
||||||
show['seriesname'], self.encode_html(show['seriesname']), show['firstaired'],
|
show['seriesname'], self.encode_html(show['seriesname']), show['firstaired'],
|
||||||
show.get('network', '') or '', show.get('genres', '') or '',
|
show.get('network', '') or '', show.get('genres', '') or '',
|
||||||
re.sub(r'([,\.!][^,\.!]*?)$', '...',
|
re.sub(r'([,.!][^,.!]*?)$', '...',
|
||||||
re.sub(r'([!\?\.])(?=\w)', r'\1 ',
|
re.sub(r'([.!?])(?=\w)', r'\1 ',
|
||||||
self.encode_html((show.get('overview', '') or '')[:250:].strip()))),
|
self.encode_html((show.get('overview', '') or '')[:250:].strip()))),
|
||||||
self._get_UWRatio(term, show['seriesname'], show.get('aliases', [])), None, None,
|
self._get_UWRatio(term, show['seriesname'], show.get('aliases', [])), None, None,
|
||||||
self._make_search_image_url(iid, show)
|
self._make_search_image_url(iid, show)
|
||||||
] for show in shows.itervalues()] for iid, shows in results.iteritems()))
|
] for show in shows.itervalues()] for iid, shows in results.iteritems()))
|
||||||
|
|
||||||
lang_id = sickbeard.indexerApi().config['langabbv_to_id'][lang]
|
def final_order(sortby_index, data, final_sort):
|
||||||
return json.dumps({
|
idx_is_indb = 1
|
||||||
'results': sorted(final_results, reverse=True, key=lambda x: x[10]),
|
for (n, x) in enumerate(data):
|
||||||
'langid': lang_id})
|
x[sortby_index] = n + (1000, 0)[x[idx_is_indb] and 'notop' not in sickbeard.RESULTS_SORTBY]
|
||||||
# return json.dumps({
|
return data if not final_sort else sorted(data, reverse=False, key=lambda x: x[sortby_index])
|
||||||
# 'results': sorted(final_results, reverse=True, key=lambda x: dateutil.parser.parse(
|
|
||||||
# re.match('^(?:19|20)\d\d$', str(x[6])) and ('%s-12-31' % str(x[6])) or (x[6] and str(x[6])) or '1900')),
|
def sort_date(data_result, is_last_sort):
|
||||||
# 'langid': lang_id})
|
idx_date_sort, idx_src, idx_aired = 13, 2, 8
|
||||||
|
return final_order(
|
||||||
|
idx_date_sort,
|
||||||
|
sorted(
|
||||||
|
sorted(data_result, reverse=True, key=lambda x: (dateutil.parser.parse(
|
||||||
|
re.match('^(?:19|20)\d\d$', str(x[idx_aired])) and ('%s-12-31' % str(x[idx_aired]))
|
||||||
|
or (x[idx_aired] and str(x[idx_aired])) or '1900'))),
|
||||||
|
reverse=False, key=lambda x: x[idx_src]), is_last_sort)
|
||||||
|
|
||||||
|
def sort_az(data_result, is_last_sort):
|
||||||
|
idx_az_sort, idx_src, idx_title = 14, 2, 6
|
||||||
|
return final_order(
|
||||||
|
idx_az_sort,
|
||||||
|
sorted(
|
||||||
|
data_result, reverse=False, key=lambda x: (
|
||||||
|
x[idx_src],
|
||||||
|
(remove_article(x[idx_title].lower()), x[idx_title].lower())[sickbeard.SORT_ARTICLE])),
|
||||||
|
is_last_sort)
|
||||||
|
|
||||||
|
def sort_rel(data_result, is_last_sort):
|
||||||
|
idx_rel_sort, idx_src, idx_rel = 12, 2, 12
|
||||||
|
return final_order(
|
||||||
|
idx_rel_sort,
|
||||||
|
sorted(
|
||||||
|
sorted(data_result, reverse=True, key=lambda x: x[idx_rel]),
|
||||||
|
reverse=False, key=lambda x: x[idx_src]), is_last_sort)
|
||||||
|
|
||||||
|
if 'az' == sickbeard.RESULTS_SORTBY[:2]:
|
||||||
|
sort_results = [sort_date, sort_rel, sort_az]
|
||||||
|
elif 'date' == sickbeard.RESULTS_SORTBY[:4]:
|
||||||
|
sort_results = [sort_az, sort_rel, sort_date]
|
||||||
|
else:
|
||||||
|
sort_results = [sort_az, sort_date, sort_rel]
|
||||||
|
|
||||||
|
for n, func in enumerate(sort_results):
|
||||||
|
final_results = func(final_results, n == len(sort_results) - 1)
|
||||||
|
|
||||||
|
return json.dumps({'results': final_results, 'langid': sickbeard.indexerApi().config['langabbv_to_id'][lang]})
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _make_search_image_url(iid, show):
|
def _make_search_image_url(iid, show):
|
||||||
img_url = ''
|
img_url = ''
|
||||||
if INDEXER_TRAKT == iid:
|
if INDEXER_TRAKT == iid:
|
||||||
img_url = 'imagecache?path=browse/thumb/trakt&filename=%s&tmdbid=%s&tvdbid=%s' % \
|
img_url = 'imagecache?path=browse/thumb/trakt&filename=%s&trans=0&tmdbid=%s&tvdbid=%s' % \
|
||||||
('%s.jpg' % show['trakt_id'], show.get('tmdb_id'), show.get('id'))
|
('%s.jpg' % show['trakt_id'], show.get('tmdb_id'), show.get('id'))
|
||||||
elif INDEXER_TVDB == iid:
|
elif INDEXER_TVDB == iid:
|
||||||
img_url = 'imagecache?path=browse/thumb/tvdb&filename=%s&tvdbid=%s' % \
|
img_url = 'imagecache?path=browse/thumb/tvdb&filename=%s&trans=0&tvdbid=%s' % \
|
||||||
('%s.jpg' % show['id'], show['id'])
|
('%s.jpg' % show['id'], show['id'])
|
||||||
return img_url
|
return img_url
|
||||||
|
|
||||||
|
@ -4658,6 +4699,19 @@ class ConfigGeneral(Config):
|
||||||
def saveRootDirs(self, rootDirString=None):
|
def saveRootDirs(self, rootDirString=None):
|
||||||
sickbeard.ROOT_DIRS = rootDirString
|
sickbeard.ROOT_DIRS = rootDirString
|
||||||
|
|
||||||
|
def saveResultPrefs(self, ui_results_sortby=None):
|
||||||
|
|
||||||
|
if ui_results_sortby in ('az', 'date', 'rel', 'notop', 'ontop'):
|
||||||
|
was_ontop = 'notop' not in sickbeard.RESULTS_SORTBY
|
||||||
|
if 'top' == ui_results_sortby[-3:]:
|
||||||
|
maybe_ontop = ('', ' notop')[was_ontop]
|
||||||
|
sortby = sickbeard.RESULTS_SORTBY.replace(' notop', '')
|
||||||
|
sickbeard.RESULTS_SORTBY = '%s%s' % (('rel', sortby)[any([sortby])], maybe_ontop)
|
||||||
|
else:
|
||||||
|
sickbeard.RESULTS_SORTBY = '%s%s' % (ui_results_sortby, (' notop', '')[was_ontop])
|
||||||
|
|
||||||
|
sickbeard.save_config()
|
||||||
|
|
||||||
def saveAddShowDefaults(self, default_status, any_qualities='', best_qualities='', default_wanted_begin=None,
|
def saveAddShowDefaults(self, default_status, any_qualities='', best_qualities='', default_wanted_begin=None,
|
||||||
default_wanted_latest=None, default_flatten_folders=False, default_scene=False,
|
default_wanted_latest=None, default_flatten_folders=False, default_scene=False,
|
||||||
default_subtitles=False, default_anime=False, default_tag=''):
|
default_subtitles=False, default_anime=False, default_tag=''):
|
||||||
|
@ -6171,7 +6225,8 @@ class CachedImages(MainHandler):
|
||||||
self.delete_all_dummy_images(static_image_path)
|
self.delete_all_dummy_images(static_image_path)
|
||||||
|
|
||||||
if not ek.ek(os.path.isfile, static_image_path):
|
if not ek.ek(os.path.isfile, static_image_path):
|
||||||
static_image_path = ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', 'slick', 'images', 'trans.png')
|
static_image_path = ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', 'slick',
|
||||||
|
'images', ('image-light.png', 'trans.png')[bool(int(kwargs.get('trans', 1)))])
|
||||||
else:
|
else:
|
||||||
helpers.set_file_timestamp(static_image_path, min_age=3, new_time=None)
|
helpers.set_file_timestamp(static_image_path, min_age=3, new_time=None)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue