mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-05 17:43:37 +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 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 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]
|
||||
|
|
|
@ -1289,6 +1289,7 @@ input sizing (for config pages)
|
|||
========================================================================== */
|
||||
|
||||
.showlist-select optgroup,
|
||||
#results-sortby optgroup,
|
||||
#pickShow optgroup,
|
||||
#showfilter optgroup,
|
||||
#showsort optgroup,
|
||||
|
@ -1298,6 +1299,7 @@ input sizing (for config pages)
|
|||
}
|
||||
|
||||
.showlist-select optgroup option,
|
||||
#results-sortby optgroup option,
|
||||
#pickShow optgroup option,
|
||||
#showfilter optgroup option,
|
||||
#showsort optgroup option,
|
||||
|
|
|
@ -1254,6 +1254,7 @@ input sizing (for config pages)
|
|||
========================================================================== */
|
||||
|
||||
.showlist-select optgroup,
|
||||
#results-sortby optgroup,
|
||||
#pickShow optgroup,
|
||||
#showfilter optgroup,
|
||||
#showsort optgroup,
|
||||
|
@ -1263,6 +1264,7 @@ input sizing (for config pages)
|
|||
}
|
||||
|
||||
.showlist-select optgroup option,
|
||||
#results-sortby optgroup option,
|
||||
#pickShow optgroup option,
|
||||
#showfilter optgroup option,
|
||||
#showsort optgroup option,
|
||||
|
|
|
@ -1113,11 +1113,16 @@ div.formpaginate{
|
|||
margin-left:10px
|
||||
}
|
||||
|
||||
.stepDiv #searchResults div{
|
||||
.stepDiv #searchResults .results-item{
|
||||
width:100%;
|
||||
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-style:italic
|
||||
}
|
||||
|
@ -1126,6 +1131,11 @@ div.formpaginate{
|
|||
margin-right:6px
|
||||
}
|
||||
|
||||
a span.article,
|
||||
a:hover span.article{
|
||||
color:#2f4799
|
||||
}
|
||||
|
||||
.stepone-result-title{
|
||||
font-weight:600;
|
||||
margin-left:10px
|
||||
|
@ -2785,6 +2795,7 @@ config*.tmpl
|
|||
padding-top:10px
|
||||
}
|
||||
|
||||
select .selected-text,
|
||||
select .selected{
|
||||
font-weight:700;
|
||||
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
|
||||
|
||||
<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 type="text/javascript" src="$sbRoot/js/formwizard.js?v=$sbPID"></script>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/** @namespace config.sortArticle */
|
||||
/** @namespace config.resultsSortby */
|
||||
$(document).ready(function () {
|
||||
|
||||
function populateLangSelect() {
|
||||
|
@ -71,59 +73,146 @@ $(document).ready(function () {
|
|||
$('#searchResults').empty().html('search timed out, try again or try another database');
|
||||
},
|
||||
success: function (data) {
|
||||
var resultStr = '', checked = '', rowType, row = 0;
|
||||
var resultStr = '', attrs = '', checked = !1, rowType, row = 0, srcState = '';
|
||||
|
||||
if (0 === data.results.length) {
|
||||
resultStr += '<span class="boldest">Sorry, no results found. Try a different search.</span>';
|
||||
} else {
|
||||
var idxSrcDB = 0, idxSrcDBId = 1, idxSrcUrl = 2, idxShowID = 3, idxTitle = 4, idxTitleHtml = 5,
|
||||
idxDate = 6, idxNetwork = 7, idxGenres = 8, idxOverview = 9;
|
||||
$.each(data.results, function (index, obj) {
|
||||
checked = (0 == row ? ' checked' : '');
|
||||
rowType = (0 == row % 2 ? '' : ' class="alt"');
|
||||
var result = {
|
||||
SrcName: 0, isInDB: 1, SrcId: 2, SrcDBId: 3, SrcUrl: 4, ShowID: 5, Title: 6, TitleHtml: 7,
|
||||
Aired: 8, Network: 9, Genre: 10, Overview: 11, RelSort: 12, DateSort: 13, AzSort: 14, ImgUrl: 15
|
||||
};
|
||||
$.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++;
|
||||
|
||||
var display_show_name = cleanseText(obj[idxTitle], !0), showstartdate = '';
|
||||
var displayShowName = cleanseText(item[result.Title], !0), showstartdate = '';
|
||||
|
||||
if (null !== obj[idxDate]) {
|
||||
var startDate = new Date(obj[idxDate]);
|
||||
if (null !== item[result.Aired]) {
|
||||
var startDate = new Date(item[result.Aired]);
|
||||
var today = new Date();
|
||||
showstartdate = ' <span class="stepone-result-date">('
|
||||
+ (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"'
|
||||
+ ' 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"'
|
||||
+ ' value="' + cleanseText([obj[idxSrcDBId], obj[idxSrcDB], obj[idxShowID], obj[idxTitle]].join('|'), !0) + '"'
|
||||
+ checked
|
||||
+ ' value="' + cleanseText([item[result.SrcDBId], item[result.SrcName], item[result.ShowID], item[result.Title]].join('|'), !0) + '"'
|
||||
+ attrs
|
||||
+ ' />'
|
||||
+ '<a'
|
||||
+ ' class="stepone-result-title"'
|
||||
+ ' title="<div style=\'color: rgb(66, 139, 202)\'>' + cleanseText(obj[idxTitleHtml], !0) + '</div>'
|
||||
+ (0 < obj[idxGenres].length ? '<div style=\'font-weight:bold\'>(<em>' + obj[idxGenres] + '</em>)</div>' : '')
|
||||
+ (0 < obj[idxNetwork].length ? '<div style=\'font-weight:bold;font-size:0.9em;color:#888\'><em>' + obj[idxNetwork] + '</em></div>' : '')
|
||||
+ (0 < obj[idxOverview].length ? '<p style=\'margin:0 0 2px\'>' + obj[idxOverview] + '</p>' : '')
|
||||
+ '<span style=\'float:right\'>Click for more</span>'
|
||||
+ ' title="<div style=\'color: rgb(66, 139, 202)\'>' + cleanseText(item[result.TitleHtml], !0) + '</div>'
|
||||
+ (0 < item[result.Genre].length ? '<div style=\'font-weight:bold\'>(<em>' + item[result.Genre] + '</em>)</div>' : '')
|
||||
+ (0 < item[result.Network].length ? '<div style=\'font-weight:bold;font-size:0.9em;color:#888\'><em>' + item[result.Network] + '</em></div>' : '')
|
||||
+ '<img style=\'max-height:150px;float:right;margin-left:3px\' src=\'/' + item[result.ImgUrl] + '\'>'
|
||||
+ (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;"'
|
||||
+ '>' + 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
|
||||
+ (null == obj[idxSrcDB] ? ''
|
||||
: ' <span class="stepone-result-db grey-text">' + '[' + obj[idxSrcDB] + ']' + '</span>')
|
||||
+ ('' === srcState ? ''
|
||||
: ' <span class="stepone-result-db grey-text">' + '[' + srcState + ']' + '</span>')
|
||||
+ '</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(
|
||||
'<fieldset>' + "\n" + '<legend class="legendStep" style="margin-bottom: 15px">'
|
||||
+ (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
|
||||
+ '</div>'
|
||||
+ '</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();
|
||||
myform.loadsection(0);
|
||||
$('.stepone-result-radio, .stepone-result-title').each(addQTip);
|
||||
|
|
|
@ -167,6 +167,8 @@ METADATA_TIVO = None
|
|||
METADATA_MEDE8ER = None
|
||||
METADATA_KODI = None
|
||||
|
||||
RESULTS_SORTBY = None
|
||||
|
||||
QUALITY_DEFAULT = None
|
||||
STATUS_DEFAULT = None
|
||||
WANTED_BEGIN_DEFAULT = None
|
||||
|
@ -536,6 +538,8 @@ def initialize(console_logging=True):
|
|||
versionCheckScheduler, showQueueScheduler, searchQueueScheduler, \
|
||||
properFinderScheduler, autoPostProcesserScheduler, subtitlesFinderScheduler, background_mapping_task, \
|
||||
provider_ping_thread_pool
|
||||
# Add Show Search
|
||||
global RESULTS_SORTBY
|
||||
# Add Show Defaults
|
||||
global STATUS_DEFAULT, QUALITY_DEFAULT, SHOW_TAG_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_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):
|
||||
ROOT_DIRS = ''
|
||||
|
||||
RESULTS_SORTBY = check_setting_str(CFG, 'General', 'results_sortby', '')
|
||||
|
||||
QUALITY_DEFAULT = check_setting_int(CFG, 'General', 'quality_default', SD)
|
||||
STATUS_DEFAULT = check_setting_int(CFG, 'General', 'status_default', SKIPPED)
|
||||
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']['backlog_nofull'] = int(BACKLOG_NOFULL)
|
||||
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']['status_default'] = int(STATUS_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.
|
||||
"""
|
||||
|
||||
# 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
|
||||
mute = []
|
||||
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:
|
||||
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:
|
||||
del kwargs['nocache']
|
||||
else:
|
||||
|
|
|
@ -2560,8 +2560,9 @@ class NewHomeAddShows(Home):
|
|||
def sanitizeFileName(self, name):
|
||||
return helpers.sanitizeFileName(name)
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
def searchIndexersForShowName(self, search_term, lang='en', indexer=None):
|
||||
if not lang or lang == 'null':
|
||||
if not lang or 'null' == lang:
|
||||
lang = 'en'
|
||||
term = search_term.decode('utf-8').strip()
|
||||
terms = []
|
||||
|
@ -2595,7 +2596,7 @@ class NewHomeAddShows(Home):
|
|||
except (StandardError, Exception):
|
||||
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)]:
|
||||
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
||||
lINDEXER_API_PARMS['language'] = lang
|
||||
|
@ -2608,7 +2609,7 @@ class NewHomeAddShows(Home):
|
|||
logger.log('Fetching show using id: %s (%s) from tv datasource %s' % (
|
||||
search_id, search_term, sickbeard.indexerApi(indexer).name), logger.DEBUG)
|
||||
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'],
|
||||
'network': r['network'], 'overview': r['overview'],
|
||||
'genres': '' if not r['genre'] else r['genre'].lower().strip('|').replace('|', ', '),
|
||||
|
@ -2632,7 +2633,7 @@ class NewHomeAddShows(Home):
|
|||
except (StandardError, Exception):
|
||||
pass
|
||||
|
||||
# Query trakt for tvdb ids
|
||||
# query trakt for tvdb ids
|
||||
try:
|
||||
logger.log('Searching for show using search term: %s from tv datasource Trakt' % search_term, logger.DEBUG)
|
||||
resp = []
|
||||
|
@ -2674,34 +2675,74 @@ class NewHomeAddShows(Home):
|
|||
for iid, name in sickbeard.indexerApi().all_indexers.iteritems()}
|
||||
# noinspection PyUnboundLocalVariable
|
||||
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, INDEXER_TVDB)[id == INDEXER_TVDB_X], sickbeard.indexerApi((id, INDEXER_TVDB)[id == INDEXER_TVDB_X]).config['show_url'], int(show['id']),
|
||||
([[id_names[iid], any([helpers.find_show_by_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.get('network', '') or '', show.get('genres', '') or '',
|
||||
re.sub(r'([,\.!][^,\.!]*?)$', '...',
|
||||
re.sub(r'([!\?\.])(?=\w)', r'\1 ',
|
||||
re.sub(r'([,.!][^,.!]*?)$', '...',
|
||||
re.sub(r'([.!?])(?=\w)', r'\1 ',
|
||||
self.encode_html((show.get('overview', '') or '')[:250:].strip()))),
|
||||
self._get_UWRatio(term, show['seriesname'], show.get('aliases', [])), None, None,
|
||||
self._make_search_image_url(iid, show)
|
||||
] for show in shows.itervalues()] for iid, shows in results.iteritems()))
|
||||
|
||||
lang_id = sickbeard.indexerApi().config['langabbv_to_id'][lang]
|
||||
return json.dumps({
|
||||
'results': sorted(final_results, reverse=True, key=lambda x: x[10]),
|
||||
'langid': lang_id})
|
||||
# return json.dumps({
|
||||
# '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')),
|
||||
# 'langid': lang_id})
|
||||
def final_order(sortby_index, data, final_sort):
|
||||
idx_is_indb = 1
|
||||
for (n, x) in enumerate(data):
|
||||
x[sortby_index] = n + (1000, 0)[x[idx_is_indb] and 'notop' not in sickbeard.RESULTS_SORTBY]
|
||||
return data if not final_sort else sorted(data, reverse=False, key=lambda x: x[sortby_index])
|
||||
|
||||
def sort_date(data_result, is_last_sort):
|
||||
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
|
||||
def _make_search_image_url(iid, show):
|
||||
img_url = ''
|
||||
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'))
|
||||
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'])
|
||||
return img_url
|
||||
|
||||
|
@ -4658,6 +4699,19 @@ class ConfigGeneral(Config):
|
|||
def saveRootDirs(self, rootDirString=None):
|
||||
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,
|
||||
default_wanted_latest=None, default_flatten_folders=False, default_scene=False,
|
||||
default_subtitles=False, default_anime=False, default_tag=''):
|
||||
|
@ -6171,7 +6225,8 @@ class CachedImages(MainHandler):
|
|||
self.delete_all_dummy_images(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:
|
||||
helpers.set_file_timestamp(static_image_path, min_age=3, new_time=None)
|
||||
|
||||
|
|
Loading…
Reference in a new issue