Browse Source

Change use diskcache instead of memcache for TVmaze cards.

Change disable AKAs for TVmaze cards since each calls the API and are not needed here.
Fix handling of card filters and sort states.
tags/release_0.25.1
JackDandy 4 years ago
parent
commit
4a1a9eea60
  1. 2
      CHANGES.md
  2. 24
      gui/slick/interfaces/default/home_browseShows.tmpl
  3. 56
      lib/api_tvmaze/tvmaze_api.py
  4. 5
      lib/tvinfo_base/base.py
  5. 42
      sickbeard/webserve.py

2
CHANGES.md

@ -83,6 +83,7 @@
* Add show name/networks card user input filter
* Change only auto refresh card view if a recoverable error occurs
* Update Requests library 2.25.1 (bdc00eb) to 2.26.0 (b0e025a)
* Fix handling of card filters and sort states
[develop changelog]
@ -93,6 +94,7 @@
* Fix genre field in tvmaze_api
* Change api interface folders to api_* to fix legacy tmdb_api folder cleanup on new installs
* Fix TVmaze genres property to be lowercase string
* Change use diskcache instead of memcache for TVmaze cards
### 0.24.15 (2021-08-05 11:45:00 UTC)

24
gui/slick/interfaces/default/home_browseShows.tmpl

@ -102,7 +102,7 @@ $(document).ready(function(){
});
#raw
$('#showsort').on('change', function(){
var sortCriteria = this.value.replace('by_', ''), el$ = $('#container'), shuffle = !1;
var elValue = this.value, sortCriteria = elValue.replace('by_', ''), el$ = $('#container'), shuffle = !1;
switch (sortCriteria) {
case 'asc':
case 'desc':
@ -119,15 +119,13 @@ $(document).ready(function(){
#end if
break;
#if $use_ratings
case 'rating':
shuffle = !0;
break;
#if $use_votes
case 'rating_votes':
sortCriteria = ['rating', 'votes'];
#end if
case 'rating':
shuffle = !0;
break;
#end if
#end if
default:
sortCriteria = 'name'
@ -140,21 +138,21 @@ $(document).ready(function(){
option$ = showSort.filter('option[value="asc"].selected, option[value="desc"].selected');
option$.removeClass('selected').removeAttr('selected').html(option$.text().replace(/^>\s/i, ''));
option$ = showSort.filter($('option[value="' + this.value + '"]'));
option$ = showSort.filter($('option[value="' + elValue + '"]'));
option$.addClass('selected').attr('selected', !0).html('> ' + option$.text());
savePrefs();
el$.one('layoutComplete', llUpdate);
el$.isotope({
sortAscending: 'asc' === this.value,
sortAscending: 'asc' === elValue,
sortBy: showSort.filter($('option[value^="by_"][class*="selected"]')).val().replace('by_', '')
});
} else if(0 == this.value.indexOf('by_')){
} else if(0 == elValue.indexOf('by_')){
option$ = showSort.filter($('option[value^="by_"][class*="selected"]'));
option$.removeClass('selected').removeAttr('selected').html(option$.text().replace(/^>\s/i, ''));
option$ = showSort.filter($('option[value="' + this.value + '"]'));
option$ = showSort.filter($('option[value="' + elValue + '"]'));
option$.addClass('selected').attr('selected', !0).html('> ' + option$.text());
savePrefs();
@ -184,12 +182,12 @@ $(document).ready(function(){
option$ = showSort.filter($('option[value^="*"].selected, #showsort option[value^="."].selected'));
option$.removeClass('selected').removeAttr('selected').html(option$.text().replace(/^>\s/i, ''));
option$ = showSort.filter($('option[value="' + this.value + '"]'));
option$ = showSort.filter($('option[value="' + elValue + '"]'));
option$.addClass('selected').attr('selected', !0).html('> ' + option$.text());
savePrefs();
var showCards = $('.show-card'), filter = this.value;
var showCards = $('.show-card'), filter = elValue;
if('.hide' === filter){
showCards.filter($('.hide')).removeClass('hide').addClass('to-hide');
filter = '.to-hide';
@ -278,7 +276,7 @@ $(document).ready(function(){
}
});
});
$('.resetshows').click(function() {
$('.resetshows').click(function() {
var input = $('#search_show_name');
if ('' !== input.val()){
input.val('').trigger('input').change();
@ -324,7 +322,7 @@ $(document).ready(function(){
</optgroup>
<optgroup label="Sort by">
<option value="by_name"#if 'by_name' in $saved_showsort_sortby and not $reset_showsort_sortby#$selected>>&nbsp;#else#>#end if#Name</option>
# omit for TVMaze as Original == First Aired
## omit for TVMaze as original order == First Aired
#if 'TVmaze' not in $browse_type
<option value="by_order"#if 'by_order' in $saved_showsort_sortby or $reset_showsort_sortby#$selected>>&nbsp;#else#>#end if#Original</option>
#end if

56
lib/api_tvmaze/tvmaze_api.py

@ -14,6 +14,7 @@ import requests
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
from _23 import filter_iter
from six import integer_types, iteritems, string_types
from sg_helpers import get_url, try_int
from lib.dateutil.parser import parser
@ -549,18 +550,16 @@ class TvMaze(TVInfoBase):
if p:
return self._convert_person(p)
def get_premieres(self, result_count=100, get_extra_images=False, **kwargs):
def get_premieres(self, **kwargs):
# type: (...) -> List[TVInfoEpisode]
return self._filtered_schedule(lambda e: all([1 == e.season_number, 1 == e.episode_number]),
get_images=get_extra_images)
return self._filtered_schedule(**kwargs).get('premieres')
def get_returning(self, result_count=100, get_extra_images=False, **kwargs):
def get_returning(self, **kwargs):
# type: (...) -> List[TVInfoEpisode]
return self._filtered_schedule(lambda e: all([1 != e.season_number, 1 == e.episode_number]),
get_images=get_extra_images)
return self._filtered_schedule(**kwargs).get('returning')
def _make_episode(self, episode_data, show_data=None, get_images=False):
# type: (TVMazeEpisode, TVMazeShow, bool) -> TVInfoEpisode
def _make_episode(self, episode_data, show_data=None, get_images=False, get_akas=False):
# type: (TVMazeEpisode, TVMazeShow, bool, bool) -> TVInfoEpisode
"""
make out of TVMazeEpisode object and optionally TVMazeShow a TVInfoEpisode
"""
@ -581,7 +580,8 @@ class TvMaze(TVInfoBase):
ti_show.show_type = show_data.type
ti_show.lastupdated = show_data.updated
ti_show.poster = show_data.image and show_data.image.get('original')
ti_show.aliases = [a.name for a in show_data.akas]
if get_akas:
ti_show.aliases = [a.name for a in show_data.akas]
if 'days' in show_data.schedule:
ti_show.airs_dayofweek = ', '.join(show_data.schedule['days'])
network = show_data.network or show_data.web_channel
@ -656,12 +656,32 @@ class TvMaze(TVInfoBase):
ti_episode.show = ti_show
return ti_episode
def _filtered_schedule(self, condition, get_images=False):
try:
result = sorted([
e for e in tvmaze.get_full_schedule()
if condition(e) and (None is e.show.language or re.search('(?i)eng|jap', e.show.language))],
key=lambda x: x.show.premiered or x.airstamp)
return [self._make_episode(r, r.show, get_images) for r in result]
except(BaseException, Exception):
return []
def _filtered_schedule(self, **kwargs):
cache_name_key = 'tvmaze_schedule'
is_none, schedule = self._get_cache_entry(cache_name_key)
if None is schedule and not is_none:
schedule = []
try:
schedule = tvmaze.get_full_schedule()
except(BaseException, Exception):
pass
premieres = []
returning = []
rc_lang = re.compile('(?i)eng|jap')
for cur_show in filter_iter(lambda s: 1 == s.episode_number and (
None is s.show.language or rc_lang.search(s.show.language)), schedule):
if 1 == cur_show.season_number:
premieres += [cur_show]
else:
returning += [cur_show]
premieres = [self._make_episode(r, r.show, **kwargs)
for r in sorted(premieres, key=lambda e: e.show.premiered)]
returning = [self._make_episode(r, r.show, **kwargs)
for r in sorted(returning, key=lambda e: e.airstamp)]
schedule = dict(premieres=premieres, returning=returning)
self._set_cache_entry(cache_name_key, schedule, expire=self.schedule_cache_expire)
return schedule

5
lib/tvinfo_base/base.py

@ -807,6 +807,7 @@ class TVInfoBase(object):
self.diskcache = diskcache.Cache(directory=self._cachedir, disk_pickle_protocol=2) # type: diskcache.Cache
self.cache_expire = 60 * 60 * 18 # type: integer_types
self.search_cache_expire = 60 * 15 # type: integer_types
self.schedule_cache_expire = 60 * 30 # type: integer_types
self.config = {
'apikey': '',
'debug_enabled': False,
@ -1168,14 +1169,14 @@ class TVInfoBase(object):
# type: (...) -> List[TVInfoEpisode]
return []
def get_premieres(self, result_count=100, **kwargs):
def get_premieres(self, **kwargs):
# type: (...) -> List[TVInfoEpisode]
"""
get all premiering shows
"""
return []
def get_returning(self, result_count=100, get_extra_images=False, **kwargs):
def get_returning(self, **kwargs):
# type: (...) -> List[TVInfoShow]
"""
get all returning shows

42
sickbeard/webserve.py

@ -5187,28 +5187,19 @@ class AddShows(Home):
footnote = None
filtered = []
def card_cache(mem_key):
# noinspection PyProtectedMember
from lib.dateutil.tz.tz import _datetime_to_timestamp
now = int(_datetime_to_timestamp(datetime.datetime.now()))
if (sickbeard.MEMCACHE.get(mem_key, {}).get('data')
and (now < sickbeard.MEMCACHE.get(mem_key, {}).get('expire', 0))):
return sickbeard.MEMCACHE.get(mem_key).get('data')
tvinfo_config = sickbeard.TVInfoAPI(TVINFO_TVMAZE).api_params.copy()
t = sickbeard.TVInfoAPI(TVINFO_TVMAZE).setup(**tvinfo_config)
if 'prem' in mem_key:
data = t.get_premieres()
else:
data = t.get_returning()
sickbeard.MEMCACHE[mem_key] = dict(expire=(30*60) + now, data=data)
return data
tvinfo_config = sickbeard.TVInfoAPI(TVINFO_TVMAZE).api_params.copy()
t = sickbeard.TVInfoAPI(TVINFO_TVMAZE).setup(**tvinfo_config)
if 'New' in browse_title:
episodes = card_cache('tvmaze_premiere')
episodes = t.get_premieres()
else:
episodes = card_cache('tvmaze_returning')
episodes = t.get_returning()
# handle switching between returning and premieres
sickbeard.BROWSELIST_MRU.setdefault(browse_type, dict())
showfilter = ('by_returning', 'by_premiered')['New' in browse_title]
saved_showsort = sickbeard.BROWSELIST_MRU[browse_type].get('tvm_%s' % kwargs['mode']) or '*,asc'
showsort = saved_showsort + (',%s' % showfilter, '')[3 == len(saved_showsort.split(','))]
sickbeard.BROWSELIST_MRU[browse_type].update(dict(showfilter=showfilter, showsort=showsort))
oldest, newest, oldest_dt, newest_dt, use_networks = None, None, 9999999, 0, False
dedupe = []
@ -5680,8 +5671,12 @@ class AddShows(Home):
save_config = False
if browse_type in ('AniDB', 'IMDb', 'Metacritic', 'Trakt', 'TVCalendar', 'TVmaze', 'Nextepisode'):
save_config = True
sickbeard.BROWSELIST_MRU[browse_type] = dict(
showfilter=kwargs.get('showfilter', ''), showsort=kwargs.get('showsort', ''))
if browse_type in ('TVmaze',) and kwargs.get('showfilter') and kwargs.get('showsort'):
sickbeard.BROWSELIST_MRU.setdefault(browse_type, dict()) \
.update({kwargs.get('showfilter'): kwargs.get('showsort')})
else:
sickbeard.BROWSELIST_MRU[browse_type] = dict(
showfilter=kwargs.get('showfilter', ''), showsort=kwargs.get('showsort', ''))
if save_config:
sickbeard.save_config()
return json.dumps({'success': save_config})
@ -5700,8 +5695,7 @@ class AddShows(Home):
showsort = t.saved_showsort.split(',')
t.saved_showsort_sortby = 3 == len(showsort) and showsort[2] or 'by_order'
t.reset_showsort_sortby = ('votes' in t.saved_showsort_sortby and not kwargs.get('use_votes', True)
or 'rating' in t.saved_showsort_sortby and not kwargs.get('use_ratings', True)
or 'returning' in t.saved_showsort_sortby and 'Returning' not in browse_title)
or 'rating' in t.saved_showsort_sortby and not kwargs.get('use_ratings', True))
t.is_showsort_desc = ('desc' == (2 <= len(showsort) and showsort[1] or 'asc')) and not t.reset_showsort_sortby
t.saved_showsort_view = 1 <= len(showsort) and showsort[0] or '*'
t.all_shows = []

Loading…
Cancel
Save