From: E.Smith <31170571+azlm8t@users.noreply.github.com> Date: Fri, 5 Oct 2018 01:11:13 +0000 (+0100) Subject: fanart: Pass programme title language to grabber so it can use it. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f47166a12e5d7c7eed5999c4a496d3787101b4f2;p=thirdparty%2Ftvheadend.git fanart: Pass programme title language to grabber so it can use it. --- diff --git a/lib/py/tvh/tv_meta_tmdb.py b/lib/py/tvh/tv_meta_tmdb.py index 936b6277e..e01f8b3c8 100755 --- a/lib/py/tvh/tv_meta_tmdb.py +++ b/lib/py/tvh/tv_meta_tmdb.py @@ -25,7 +25,7 @@ def get_capabilities(): return { "name": "tv_meta_tmdb", "version": "0.1", - "description": "Grab movie details from TMDB.", + "description": "Grab movie/tv details from TMDB.", "supports_tv": True, "supports_movie": True, "required_config" : { @@ -47,7 +47,7 @@ class Tv_meta_tmdb(object): self.poster_size = "w342" if 'poster-size' not in args else args["poster-size"] # Fanart sizes: w300, w780, w1280, original self.fanart_size = "original" if 'poster-size' not in args else args["fanart-size"] - self.languages = "en" + self.languages = None if 'languages' in args and args["languages"] is not None: self.languages = args["languages"] @@ -86,8 +86,8 @@ class Tv_meta_tmdb(object): def _search_tv(self, title, year, lang = "en"): return self._search_common(title, year, lang, "search/tv", "first_air_date_year") - def _search_all_languages_common(self, title, year, cb): - for lang in self.languages.split(","): + def _search_all_languages_common(self, title, year, language, cb): + for lang in language.split(","): try: res = cb(title, year, lang) if res: @@ -97,17 +97,17 @@ class Tv_meta_tmdb(object): pass return None - def _search_movie_all_languages(self, title, year): - return self._search_all_languages_common(title, year, self._search_movie) + def _search_movie_all_languages(self, title, year, language): + return self._search_all_languages_common(title, year, language, self._search_movie) - def _search_tv_all_languages(self, title, year): - return self._search_all_languages_common(title, year, self._search_tv) + def _search_tv_all_languages(self, title, year, language): + return self._search_all_languages_common(title, year, language, self._search_tv) - def _search_all_languages(self, title, year, cb1, cb2): - res = cb1(title, year) + def _search_all_languages(self, title, year, language, cb1, cb2): + res = cb1(title, year, language) if res is None and cb2 is not None: logging.debug("Trying again with other type") - res = cb2(title, year) + res = cb2(title, year, language) return res @@ -115,6 +115,12 @@ class Tv_meta_tmdb(object): logging.debug("Fetching with details %s " % args); title = args["title"] year = args["year"] + if self.languages: # User override + language = self.languages + elif "language" in args: + language = args["language"] + else: + language = "en" type = "movie" if 'type' not in args else args["type"] if title is None: @@ -126,9 +132,9 @@ class Tv_meta_tmdb(object): # tv show instead. We don't do the opposite for tv shows since # they never get identified as a movie due to season and episode. if type is None or type == 'movie': - res = self._search_all_languages(title, year, self._search_movie_all_languages, self._search_tv_all_languages) + res = self._search_all_languages(title, year, language, self._search_movie_all_languages, self._search_tv_all_languages) else: - res = self._search_all_languages(title, year, self._search_tv_all_languages, None) + res = self._search_all_languages(title, year, language, self._search_tv_all_languages, None) logging.debug(res) if res is None or len(res) == 0: logging.info("Could not find any match for %s" % title); diff --git a/lib/py/tvh/tv_meta_tvdb.py b/lib/py/tvh/tv_meta_tvdb.py index 59da74877..64bf96d77 100755 --- a/lib/py/tvh/tv_meta_tvdb.py +++ b/lib/py/tvh/tv_meta_tvdb.py @@ -34,7 +34,7 @@ def get_capabilities(): return { "name": "tv_meta_tvdb", "version": "0.1", - "description": "Grab movie details from TVDB.", + "description": "Grab tv details from TVDB.", "supports_tv": True, "supports_movie": False, "required_config" : { @@ -44,6 +44,20 @@ def get_capabilities(): +class AcceptLanguage(object): + """Add a language to the session headers and remove after scope.""" + def __init__(self, session, language): + self.session = session + self.language = language + + def __enter__(self): + self.session.headers.update({'Accept-Language': self.language}) + return self + + def __exit__(self, exc_type, exc_value, tb): + self.session.headers.pop('Accept-Language', None) + + class Tvdb(object): """Basic tvdb wrapper. @@ -57,7 +71,7 @@ Exceptions are thrown to indicate data could not be retrieved. logging.critical("Need a tvdb-" + arg + ". No lookup available with this module.") raise RuntimeError("Need a tvdb-" + arg); - self.languages = "en" + self.languages = None # 2 character language code. At time of writing, valid languages on the server are: # ['da', 'fi', 'nl', 'de', 'it', 'es', 'fr', 'pl', 'hu', 'el', 'tr', 'ru', 'he', 'ja', 'pt', 'zh', 'cs', 'sl', 'hr', 'ko', 'en', 'sv', 'no'] # We accept a csv of languages. @@ -77,8 +91,7 @@ Exceptions are thrown to indicate data could not be retrieved. self.auth = self._get_auth() def _get_headers(self): - headers = { 'Content-Type': 'application/json', - 'Accept-Language': self.languages } + headers = { 'Content-Type': 'application/json' } if self.auth: headers['Authorization'] = 'Bearer ' + self.auth return headers @@ -92,13 +105,14 @@ Exceptions are thrown to indicate data could not be retrieved. self.session.headers.update({'Authorization' : 'Bearer ' + token}) return token - def get_tvdbid(self, title): + def get_tvdbid(self, title, language = "en"): """Return episode tvdb id""" - r=self.session.get( - self.base_url + 'search/series', - timeout = self.timeout, - params={'name': title}) - return r.json()['data'][0]['id'] + with AcceptLanguage(self.session, language): + r=self.session.get( + self.base_url + 'search/series', + timeout = self.timeout, + params={'name': title}) + return r.json()['data'][0]['id'] def _get_art(self, title = None, tvdbid = None, artworkType = 'fanart'): if tvdbid is None: @@ -117,17 +131,22 @@ Exceptions are thrown to indicate data could not be retrieved. filename = "https://thetvdb.com/banners/" + filename return filename - def get_fanart(self, title = None, tvdbid = None): - return self._get_art(title = title, tvdbid = tvdbid, artworkType = 'fanart') + def get_fanart(self, title = None, tvdbid = None, language = "en"): + with AcceptLanguage(self.session, language): + return self._get_art(title = title, tvdbid = tvdbid, artworkType = 'fanart') - def get_poster(self, title = None, tvdbid = None): - return self._get_art(title = title, tvdbid = tvdbid, artworkType = 'poster') + def get_poster(self, title = None, tvdbid = None, languague = "en"): + with AcceptLanguage(self.session, language): + return self._get_art(title = title, tvdbid = tvdbid, artworkType = 'poster') class Tv_meta_tvdb(object): def __init__(self, args): self.tvdb = Tvdb(args) + self.languages = None + if 'languages' in args and args["languages"] is not None: + self.languages = args["languages"] def fetch_details(self, args): logging.debug("Fetching with details %s " % args); @@ -138,6 +157,13 @@ class Tv_meta_tvdb(object): logging.critical("Need a title"); raise RuntimeError("Need a title"); + if self.languages is not None: + language = self.languages + elif "language" in args: + language = args["language"] + else: + language = "en" + tvdbid = None query = title @@ -145,13 +171,13 @@ class Tv_meta_tvdb(object): if year is not None: query = query + " (%s)" % year try: - tvdbid = self.tvdb.get_tvdbid(query) + tvdbid = self.tvdb.get_tvdbid(query, language) except: pass if tvdbid is None: try: - tvdbid = self.tvdb.get_tvdbid(title) + tvdbid = self.tvdb.get_tvdbid(title, language) except: logging.info("Could not find any matching episode for " + title); raise LookupError("Could not find match for " + title); @@ -159,12 +185,12 @@ class Tv_meta_tvdb(object): poster = fanart = None # We don't want failure to process one image to affect the other. try: - poster = self.tvdb.get_poster(tvdbid = tvdbid) + poster = self.tvdb.get_poster(tvdbid = tvdbid, language=language) except Exception: pass try: - fanart = self.tvdb.get_fanart(tvdbid = tvdbid) + fanart = self.tvdb.get_fanart(tvdbid = tvdbid, language=language) except: pass diff --git a/support/tvhmeta b/support/tvhmeta index 898866a5c..ae205fee9 100755 --- a/support/tvhmeta +++ b/support/tvhmeta @@ -162,6 +162,55 @@ class TvhMeta(object): replace = self.request("api/idnode/save", new_data) return replace + def _lang3_to_lang2(self, lang3): + """Convert from ISO 639-2 (3 letter code) + region to ISO 639-1 (2 letter code)""" + # This is taken from tvh_locale.c, but "_" is replaced with "-" on the mapped side. + iso_map = { + "ach": "ach", + "ady": "ady", + "ara": "ar", + "bul": "bg", + "cze": "cs", + "dan": "da", + "ger": "de", + "eng": "en-US", + "eng_GB": "en-GB", + "eng_US": "en-US", + "spa": "es", + "est": "et", + "per": "fa", + "fin": "fi", + "fre": "fr", + "heb": "he", + "hrv": "hr", + "hun": "hu", + "ita": "it", + "kor": "ko", + "lav": "lv", + "lit": "lt", + "dut": "nl", + "nor": "no", + "pol": "pl", + "por": "pt", + "rum": "ro", + "rus": "ru", + "slv": "sl", + "slo": "sk", + "srp": "sr", + "alb": "sq", + "swe": "sv", + "tur": "tr", + "ukr": "uk", + "chi": "zh", + "chi_CN": "zh-Hans", + } + try: + return iso_map[lang] + except: + # No mapping. Return "English" as default. + return "en" + + def fetch_and_persist_artwork(self, uuid, force_refresh, modules_movie, modules_tv): """Fetch artwork for the given uuid.""" data = urlencode( @@ -269,6 +318,7 @@ class TvhMeta(object): type = "movie" art = obj.fetch_details({ "title": title, + "language": self._lang3_to_lang2(lang), "year": year, "type": type, "episode_disp": episode_disp, # @todo Need to break this out in to season/episode, maybe subtitle too.