From a0099da56bd1d37eddaba0197e4693a90b1f5a96 Mon Sep 17 00:00:00 2001 From: Prinz23 Date: Sat, 18 Feb 2023 14:50:37 +0000 Subject: [PATCH] Fix show view edit language. Fix reload show data if requested language changes. Fix broken lang in tvdb api. Change use language in all get_show tvinfo data calls. Fix TMDB show language fallback check. Fix add requested_language to tvinfo show cache. Fix reset loaded statuses of cached show. Fix TVDb image parsing. --- CHANGES.md | 8 +++++++- lib/api_tmdb/tmdb_api.py | 4 ++-- lib/api_tvdb/tvdb_api.py | 25 +++++++++++++++++-------- lib/tvinfo_base/base.py | 16 ++++++++++++---- sickgear/metadata/generic.py | 2 +- sickgear/show_queue.py | 4 ++-- sickgear/tv.py | 14 ++++++++------ sickgear/webserve.py | 4 +++- 8 files changed, 52 insertions(+), 25 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e094277f..137d2b4f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,10 @@ -### 3.27.5 (2023-02-16 18:30:00 UTC) +### 3.27.6 (2023-02-18 20:10:00 UTC) + +* Fix show view edit language +* Fix TVDb image parsing + + +### 3.27.5 (2023-02-16 18:30:00 UTC) * Fix network for persons diff --git a/lib/api_tmdb/tmdb_api.py b/lib/api_tmdb/tmdb_api.py index 824cd7d3..c7db1dfc 100644 --- a/lib/api_tmdb/tmdb_api.py +++ b/lib/api_tmdb/tmdb_api.py @@ -604,7 +604,7 @@ class TmdbIndexer(TVInfoBase): # type: (integer_types, AnyStr, bool, bool, bool, bool, bool, bool, bool, Optional[Any]) -> bool # note: this is only working for images fetching currently self.show_not_found = False - to_append = ['external_ids', 'alternative_titles', 'content_ratings'] + to_append = ['external_ids', 'alternative_titles', 'content_ratings', 'translations'] tmdb_lang = ('en-US', language)[language in self._tmdb_supported_lang_list] if any((banners, posters, seasons, seasonwides, fanart)): to_append.append('images') @@ -615,7 +615,7 @@ class TmdbIndexer(TVInfoBase): try: tmdb = tmdbsimple.TV(sid) show_data = tmdb.info(append_to_response=','.join(to_append), language=tmdb_lang) - if tmdb_lang not in show_data.get('languages'): + if tmdb_lang not in (_l['iso_639_1'] for _l in show_data['translations'].get('translations', []) or []): tmdb_lang = 'en' show_data = tmdb.info(append_to_response=','.join(to_append), language=tmdb_lang) except (BaseException, Exception): diff --git a/lib/api_tvdb/tvdb_api.py b/lib/api_tvdb/tvdb_api.py index 02792c9a..009b91d7 100644 --- a/lib/api_tvdb/tvdb_api.py +++ b/lib/api_tvdb/tvdb_api.py @@ -141,6 +141,8 @@ class Tvdb(TVInfoBase): >> t['Scrubs'][1][24]['episodename'] u'My Last Day' """ + map_languages = {} + reverse_map_languages = {v: k for k, v in iteritems(map_languages)} supported_id_searches = [TVINFO_TVDB, TVINFO_TVDB_SLUG] # noinspection PyUnusedLocal @@ -839,10 +841,10 @@ class Tvdb(TVInfoBase): k, v = k.lower(), v.lower() if isinstance(v, string_types) else v if 'filename' == k: k = 'bannerpath' - v = self.config['url_artworks'] % v + v = self._make_image(self.config['url_artworks'], v) elif 'thumbnail' == k: k = 'thumbnailpath' - v = self.config['url_artworks'] % v + v = self._make_image(self.config['url_artworks'], v) elif 'keytype' == k: k = 'bannertype' banners.setdefault(btype, OrderedDict()).setdefault(btype2, OrderedDict()).setdefault(bid, {})[ @@ -853,6 +855,13 @@ class Tvdb(TVInfoBase): self._set_show_data(sid, '_banners', banners, add=True) + @staticmethod + def _make_image(base_url, url): + # type: (str, str) -> str + if not url or url.lower().startswith('http'): + return url or '' + return base_url % url + def _parse_actors(self, sid, actor_list, actor_list_alt): a = [] @@ -937,7 +946,7 @@ class Tvdb(TVInfoBase): role_image = (alts.get(n['id'], {}).get('image'), n.get('image'))[ any([n.get('image')]) and 1 == c_p_list.count((n['name'], n['role']))] if role_image: - role_image = self.config['url_artworks'] % role_image + role_image = self._make_image(self.config['url_artworks'], role_image) character_name = n.get('role', '').strip() or alts.get(n['id'], {}).get('role', '') person_name = n.get('name', '').strip() or alts.get(n['id'], {}).get('name', '') try: @@ -986,7 +995,7 @@ class Tvdb(TVInfoBase): if None is not v: if 'filename' == k and v: - v = self.config['url_artworks'] % v + v = self._make_image(self.config['url_artworks'], v) else: v = clean_data(v) data[k] = v @@ -1004,8 +1013,8 @@ class Tvdb(TVInfoBase): image_data['data'] = sorted(image_data['data'], reverse=True, key=lambda x: (x['ratingsinfo']['average'], x['ratingsinfo']['count'])) if not excluded_main_data: - url_image = self.config['url_artworks'] % image_data['data'][0]['filename'] - url_thumb = self.config['url_artworks'] % image_data['data'][0]['thumbnail'] + url_image = self._make_image(self.config['url_artworks'], image_data['data'][0]['filename']) + url_thumb = self._make_image(self.config['url_artworks'], image_data['data'][0]['thumbnail']) self._set_show_data(sid, image_type, url_image) self._set_show_data(sid, u'%s_thumb' % image_type, url_thumb) excluded_main_data = True # artwork found so prevent fallback @@ -1037,7 +1046,7 @@ class Tvdb(TVInfoBase): # Parse show information url = self.config['url_series_info'] % sid - if direct_data or sid not in self.shows or None is self.shows[sid].id: + if direct_data or sid not in self.shows or None is self.shows[sid].id or language != self.shows[sid].language: log.debug('Getting all series data for %s' % sid) show_data = self._getetsrc(url, language=language) if not show_data or not show_data.get('data'): @@ -1200,7 +1209,7 @@ class Tvdb(TVInfoBase): if None is not v: if 'filename' == k and v: if '://' not in v: - v = self.config['url_artworks'] % v + v = self._make_image(self.config['url_artworks'], v) else: v = clean_data(v) diff --git a/lib/tvinfo_base/base.py b/lib/tvinfo_base/base.py index 32914381..a1d57bc4 100644 --- a/lib/tvinfo_base/base.py +++ b/lib/tvinfo_base/base.py @@ -332,6 +332,7 @@ class TVInfoShow(dict): self.vote_count = None # type: Optional[integer_types] self.vote_average = None # type: Optional[Union[integer_types, float]] self.origin_countries = [] # type: List[AnyStr] + self.requested_language = '' # type: AnyStr def __str__(self): nr_seasons = len(self) @@ -905,8 +906,8 @@ class TVInfoBase(object): 'cache_search': kwargs.get('cache_search'), } # type: Dict[AnyStr, Any] - def _must_load_data(self, sid, load_episodes, banners, posters, seasons, seasonwides, fanart, actors): - # type: (integer_types, bool, bool, bool, bool, bool, bool, bool) -> bool + def _must_load_data(self, sid, load_episodes, banners, posters, seasons, seasonwides, fanart, actors, lang): + # type: (integer_types, bool, bool, bool, bool, bool, bool, bool, str) -> bool """ returns if show data has to be fetched for (extra) data (episodes, images, ...) or can taken from self.shows cache @@ -918,10 +919,16 @@ class TVInfoBase(object): :param seasonwides: should load season wide images :param fanart: should load fanart :param actors: should load actors + :param lang: requested language """ if sid not in self.shows or None is self.shows[sid].id or \ (load_episodes and not getattr(self.shows[sid], 'ep_loaded', False)): return True + _show = self.shows[sid] # type: TVInfoShow + if _show.requested_language != lang: + _show.ep_loaded = _show.poster_loaded = _show.banner_loaded = _show.actors_loaded = _show.fanart_loaded = \ + _show.seasonwide_images_loaded = _show.season_images_loaded = False + return True for data_type, en_type, p_type in [(u'poster', 'posters_enabled', posters), (u'banner', 'banners_enabled', banners), (u'fanart', 'fanart_enabled', fanart), @@ -929,7 +936,7 @@ class TVInfoBase(object): (u'seasonwide', 'seasonwides_enabled', seasonwides), (u'actors', 'actors_enabled', actors)]: if (p_type or self.config.get(en_type, False)) and \ - not getattr(self.shows[sid], '%s_loaded' % data_type, False): + not getattr(_show, '%s_loaded' % data_type, False): return True return False @@ -1102,7 +1109,8 @@ class TVInfoBase(object): self.shows.lock.release() try: if self._must_load_data(show_id, load_episodes, banners, posters, seasons, seasonwides, fanart, - actors): + actors, self.config['language']): + self.shows[show_id].requested_language = self.config['language'] self._get_show_data(show_id, self.map_languages.get(self.config['language'], self.config['language']), load_episodes, banners, posters, seasons, seasonwides, fanart, actors) diff --git a/sickgear/metadata/generic.py b/sickgear/metadata/generic.py index a182a389..8b61869f 100644 --- a/sickgear/metadata/generic.py +++ b/sickgear/metadata/generic.py @@ -870,7 +870,7 @@ class GenericMetadata(object): t = sickgear.TVInfoAPI(tv_id).setup(**tvinfo_config) return t.get_show((show_obj.ids[tv_id]['id'], show_obj.prodid)[tv_src == show_obj.tvid], - load_episodes=False, banners=True, posters=True, fanart=True) + load_episodes=False, banners=True, posters=True, fanart=True, language=show_obj.lang) except (BaseTVinfoError, IOError) as e: logger.log(u"Unable to look up show on " + sickgear.TVInfoAPI( tv_id).name + ", not downloading images: " + ex(e), logger.WARNING) diff --git a/sickgear/show_queue.py b/sickgear/show_queue.py index 0bdacfdf..03fbec9a 100644 --- a/sickgear/show_queue.py +++ b/sickgear/show_queue.py @@ -980,7 +980,7 @@ class QueueItemAdd(ShowQueueItem): logger.log(u'' + str(sickgear.TVInfoAPI(self.tvid).name) + ': ' + repr(tvinfo_config)) t = sickgear.TVInfoAPI(self.tvid).setup(**tvinfo_config) - s = t.get_show(self.prodid, load_episodes=False) + s = t.get_show(self.prodid, load_episodes=False, language=self.lang) if getattr(t, 'show_not_found', False): logger.log('Show %s was not found on %s, maybe show was deleted' % @@ -1694,7 +1694,7 @@ class QueueItemSwitchSource(ShowQueueItem): if new_prodid != self.show_obj.ids.get(self.new_tvid, {}).get('id') is not None: new_prodid = self.show_obj.ids.get(self.new_tvid, {}).get('id') try: - td = t.get_show(show_id=new_prodid, actors=True) + td = t.get_show(show_id=new_prodid, actors=True, language=self.show_obj.lang) except (BaseException, Exception): td = None logger.log('Failed to get new tv show id (%s) from source %s' % diff --git a/sickgear/tv.py b/sickgear/tv.py index ab0155a3..3dce3dd7 100644 --- a/sickgear/tv.py +++ b/sickgear/tv.py @@ -2234,7 +2234,7 @@ class TVShow(TVShowBase): cached_show = None try: - cached_show = t.get_show(self.prodid) + cached_show = t.get_show(self.prodid, language=self._lang) except BaseTVinfoError as e: logger.log('Unable to find cached seasons from %s: %s' % ( sickgear.TVInfoAPI(self.tvid).name, ex(e)), logger.WARNING) @@ -2334,7 +2334,7 @@ class TVShow(TVShowBase): else: try: t = sickgear.TVInfoAPI(self.tvid).setup(**tvinfo_config) - show_obj = t.get_show(self.prodid) + show_obj = t.get_show(self.prodid, language=self._lang) except BaseTVinfoError: logger.log('%s timed out, unable to update episodes for [%s] from %s' % (sickgear.TVInfoAPI(self.tvid).name, self._name, sickgear.TVInfoAPI(self.tvid).name), @@ -2598,7 +2598,7 @@ class TVShow(TVShowBase): if self._lang: tvinfo_config['language'] = self._lang t = sickgear.TVInfoAPI(self.tvid).setup(**tvinfo_config) - cached_show = t.get_show(self.prodid, load_episodes=False) + cached_show = t.get_show(self.prodid, load_episodes=False, language=self._lang) vals = (self.prodid, '' if not cached_show else ' [%s]' % cached_show['seriesname'].strip()) if len(sql_result): logger.log('%s: Loading show info%s from database' % vals) @@ -2793,7 +2793,7 @@ class TVShow(TVShowBase): if getattr(tvinfo_data, 'id', None) == self.prodid: show_info = tvinfo_data else: - show_info = t.get_show(self.prodid, actors=True) # type: Optional[TVInfoShow] + show_info = t.get_show(self.prodid, actors=True, language=self._lang) # type: Optional[TVInfoShow] if None is show_info or getattr(t, 'show_not_found', False): if getattr(t, 'show_not_found', False): self.inc_not_found_count() @@ -2890,7 +2890,8 @@ class TVShow(TVShowBase): if not show_info_cast: tvinfo_config = sickgear.TVInfoAPI(self.tvid).api_params.copy() t = sickgear.TVInfoAPI(self.tvid).setup(**tvinfo_config) - show_info = t.get_show(self.prodid, load_episodes=False, actors=True) # type: Optional[TVInfoShow] + show_info = t.get_show(self.prodid, load_episodes=False, actors=True, + language=self._lang) # type: Optional[TVInfoShow] if None is show_info: return show_info_cast = show_info.cast @@ -4283,7 +4284,8 @@ class TVEpisode(TVEpisodeBase): t = sickgear.TVInfoAPI(self.tvid).setup(**tvinfo_config) else: t = tvapi - ep_info = t.get_show(self._show_obj.prodid)[season][episode] # type: TVInfoEpisode + ep_info = t.get_show(self._show_obj.prodid, + language=self.show_obj.lang)[season][episode] # type: TVInfoEpisode else: ep_info = cached_season[episode] # type: TVInfoEpisode diff --git a/sickgear/webserve.py b/sickgear/webserve.py index 180dc025..ff2475cc 100644 --- a/sickgear/webserve.py +++ b/sickgear/webserve.py @@ -2792,7 +2792,9 @@ class Home(MainHandler): del sickgear.FANART_RATINGS[tvid_prodid] sickgear.save_config() - if tvinfo_lang and tvinfo_lang in sickgear.TVInfoAPI(show_obj.tvid).setup().config['valid_languages']: + t = sickgear.TVInfoAPI(show_obj.tvid).setup() + if tvinfo_lang and (tvinfo_lang in t.config['valid_languages'] or + tvinfo_lang in (_l.get('sg_lang') for _l in t.get_languages() or [])): infosrc_lang = tvinfo_lang else: infosrc_lang = show_obj.lang