diff --git a/CHANGES.md b/CHANGES.md index 0ba6b6c9..d6a29276 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -86,6 +86,9 @@ * Change add nzb.org BoxSD and BoxHD categories * Change post processor, ignore symlinks found in process_dir * Change file modify date of episodes older than 1970 can be changed to airdate, log warning on set fail +* 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 [develop changelog] @@ -98,6 +101,8 @@ * Update Certifi 2015.11.20.1 (385476b) to 2017.01.23 (9f9dc30) * Update Tornado Web Server 4.5.dev1 (92f29b8) to 4.5.dev1 (38e493e) * Update unidecode library 0.04.18 to 0.04.20 (1e18d98) +* Fix image not loaded from tvdb_api if there is only one poster/banner +* Change prevent setting show/episode attr to None from indexer data ### 0.12.27 (2017-08-22 19:00:00 UTC) diff --git a/lib/tvdb_api/tvdb_api.py b/lib/tvdb_api/tvdb_api.py index cd45e156..a959f2ed 100644 --- a/lib/tvdb_api/tvdb_api.py +++ b/lib/tvdb_api/tvdb_api.py @@ -20,7 +20,7 @@ import logging import requests import requests.exceptions import datetime -from sickbeard.helpers import getURL +from sickbeard.helpers import getURL, tryInt import sickbeard from lib.dateutil.parser import parse @@ -354,6 +354,9 @@ class Tvdb: cache=True, banners=False, fanart=False, + posters=False, + seasons=False, + seasonwides=False, actors=False, custom_ui=None, language=None, @@ -460,6 +463,9 @@ class Tvdb: raise ValueError('Invalid value for Cache %r (type was %s)' % (cache, type(cache))) self.config['banners_enabled'] = banners + self.config['posters_enabled'] = posters + self.config['seasons_enabled'] = seasons + self.config['seasonwides_enabled'] = seasonwides self.config['fanart_enabled'] = fanart self.config['actors_enabled'] = actors @@ -586,7 +592,7 @@ class Tvdb: k_org = k k = k.lower() if None is not v: - if k in ['banner', 'fanart', 'poster']: + if k in ['banner', 'fanart', 'poster'] and v: v = self.config['url_artworkPrefix'] % v elif 'genre' == k: v = '|%s|' % '|'.join([self._clean_data(c) for c in v if isinstance(c, basestring)]) @@ -721,8 +727,8 @@ class Tvdb: try: for cur_banner in img_list: bid = cur_banner['id'] - btype = cur_banner['keytype'] - btype2 = cur_banner['resolution'] + btype = (cur_banner['keytype'], 'banner')['series' == cur_banner['keytype']] + btype2 = (cur_banner['resolution'], tryInt(cur_banner['subkey'], cur_banner['subkey']))[btype in ('season', 'seasonwide')] if None is btype or None is btype2: continue if btype not in banners: @@ -790,22 +796,51 @@ class Tvdb: for k, v in show_data['data'].iteritems(): self._set_show_data(sid, k, v) - if self.config['banners_enabled']: + p = '' + if self.config['posters_enabled']: poster_data = self._getetsrc(self.config['url_seriesBanner'] % (sid, 'poster'), language=language) - if poster_data and 'data' in poster_data and poster_data['data'] and len(poster_data['data']) > 1: + if poster_data and 'data' in poster_data and poster_data['data'] and len(poster_data['data']) > 0: + poster_data['data'] = sorted(poster_data['data'], reverse=True, + key=lambda x: (x['ratingsinfo']['average'], x['ratingsinfo']['count'])) + p = self.config['url_artworkPrefix'] % poster_data['data'][0]['filename'] + self._parse_banners(sid, poster_data['data']) + if p: + self._set_show_data(sid, u'poster', p) + + b = '' + if self.config['banners_enabled']: + poster_data = self._getetsrc(self.config['url_seriesBanner'] % (sid, 'series'), language=language) + if poster_data and 'data' in poster_data and poster_data['data'] and len(poster_data['data']) > 0: + poster_data['data'] = sorted(poster_data['data'], reverse=True, + key=lambda x: (x['ratingsinfo']['average'], x['ratingsinfo']['count'])) b = self.config['url_artworkPrefix'] % poster_data['data'][0]['filename'] self._parse_banners(sid, poster_data['data']) - else: - b = '' - self._set_show_data(sid, u'poster', b) + if b: + self._set_show_data(sid, u'banner', b) + if self.config['seasons_enabled']: + poster_data = self._getetsrc(self.config['url_seriesBanner'] % (sid, 'season'), language=language) + if poster_data and 'data' in poster_data and poster_data['data'] and len(poster_data['data']) > 0: + poster_data['data'] = sorted(poster_data['data'], reverse=True, + key=lambda x: (-1 * tryInt(x['subkey']), x['ratingsinfo']['average'], x['ratingsinfo']['count'])) + self._parse_banners(sid, poster_data['data']) + + if self.config['seasonwides_enabled']: + poster_data = self._getetsrc(self.config['url_seriesBanner'] % (sid, 'seasonwide'), language=language) + if poster_data and 'data' in poster_data and poster_data['data'] and len(poster_data['data']) > 0: + poster_data['data'] = sorted(poster_data['data'], reverse=True, + key=lambda x: (-1 * tryInt(x['subkey']), x['ratingsinfo']['average'], x['ratingsinfo']['count'])) + self._parse_banners(sid, poster_data['data']) + + f = '' if self.config['fanart_enabled']: fanart_data = self._getetsrc(self.config['url_seriesBanner'] % (sid, 'fanart'), language=language) - if fanart_data and 'data' in fanart_data and fanart_data['data'] and len(fanart_data['data']) > 1: + if fanart_data and 'data' in fanart_data and fanart_data['data'] and len(fanart_data['data']) > 0: + fanart_data['data'] = sorted(fanart_data['data'], reverse=True, + key=lambda x: (x['ratingsinfo']['average'], x['ratingsinfo']['count'])) f = self.config['url_artworkPrefix'] % fanart_data['data'][0]['filename'] self._parse_banners(sid, fanart_data['data']) - else: - f = '' + if f: self._set_show_data(sid, u'fanart', f) if self.config['actors_enabled']: diff --git a/sickbeard/metadata/generic.py b/sickbeard/metadata/generic.py index 6257ec52..00d80616 100644 --- a/sickbeard/metadata/generic.py +++ b/sickbeard/metadata/generic.py @@ -763,6 +763,8 @@ class GenericMetadata(): lINDEXER_API_PARMS = sickbeard.indexerApi(show_obj.indexer).api_params.copy() if image_type.startswith('fanart'): lINDEXER_API_PARMS['fanart'] = True + elif image_type.startswith('poster'): + lINDEXER_API_PARMS['posters'] = True else: lINDEXER_API_PARMS['banners'] = True lINDEXER_API_PARMS['dvdorder'] = 0 != show_obj.dvdorder diff --git a/sickbeard/tv.py b/sickbeard/tv.py index 1afe5cb7..6ca9d7c7 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -78,6 +78,11 @@ def dirty_setter(attr_name, types=None): return wrapper +def dict_prevent_None(d, key, default): + v = getattr(d, key, default) + return (v, default)[None is v] + + class TVShow(object): def __init__(self, indexer, indexerid, lang=''): self._indexerid = int(indexerid) @@ -925,12 +930,12 @@ class TVShow(object): raise sickbeard.indexer_attributenotfound( "Found %s, but attribute 'seriesname' was empty." % (self.indexerid)) - self.classification = getattr(myEp, 'classification', 'Scripted') - self.genre = getattr(myEp, 'genre', '') - self.network = getattr(myEp, 'network', '') - self.runtime = getattr(myEp, 'runtime', '') + self.classification = dict_prevent_None(myEp, 'classification', 'Scripted') + self.genre = dict_prevent_None(myEp, 'genre', '') + self.network = dict_prevent_None(myEp, 'network', '') + self.runtime = dict_prevent_None(myEp, 'runtime', '') - self.imdbid = getattr(myEp, 'imdb_id', '') + self.imdbid = dict_prevent_None(myEp, 'imdb_id', '') if getattr(myEp, 'airs_dayofweek', None) is not None and getattr(myEp, 'airs_time', None) is not None: self.airs = ('%s %s' % (myEp['airs_dayofweek'], myEp['airs_time'])).strip() @@ -938,8 +943,8 @@ class TVShow(object): if getattr(myEp, 'firstaired', None) is not None: self.startyear = int(str(myEp["firstaired"]).split('-')[0]) - self.status = getattr(myEp, 'status', '') - self.overview = getattr(myEp, 'overview', '') + self.status = dict_prevent_None(myEp, 'status', '') + self.overview = dict_prevent_None(myEp, 'overview', '') def load_imdb_info(self): @@ -1799,7 +1804,7 @@ class TVEpisode(object): (self.show.indexerid, season, episode, myEp['absolute_number']), logger.DEBUG) self.absolute_number = int(myEp['absolute_number']) - self.name = getattr(myEp, 'episodename', '') + self.name = dict_prevent_None(myEp, 'episodename', '') self.season = season self.episode = episode @@ -1817,7 +1822,7 @@ class TVEpisode(object): self.season, self.episode ) - self.description = getattr(myEp, 'overview', '') + self.description = dict_prevent_None(myEp, 'overview', '') firstaired = getattr(myEp, 'firstaired', None) if None is firstaired or firstaired in '0000-00-00':