]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
fanart: Rewrite to remove dependency on external tmdb module.
authorE.Smith <31170571+azlm8t@users.noreply.github.com>
Wed, 3 Oct 2018 22:39:58 +0000 (23:39 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 8 Oct 2018 12:01:16 +0000 (14:01 +0200)
The information we need can easily be retrieved via a
query so avoid the dependency on an external module and
implement the tmdb api retrieval logic ourselves. This
also means we are no longer constrained to be python2.7 only.

lib/py/tvh/tv_meta_tmdb.py

index 7341ee968b739ba6e14d92fa8bc839b90c63bdbf..39d5858f0b0ff9c187e6cc9b320196ea9755609b 100755 (executable)
@@ -1,4 +1,4 @@
-#! /usr/bin/env python2.7
+#! /usr/bin/env python
 # Retrieve details for a movie from tmdb.
 #
 # This product uses the TMDb API but is not endorsed or certified by TMDb.
@@ -19,7 +19,7 @@
 import os,sys
 import json
 import logging
-import tmdb3;                   # pip install tmdb3 - only supports python2.7 atm
+import requests
 
 def get_capabilities():
     return {
@@ -40,23 +40,53 @@ class Tv_meta_tmdb(object):
       if args is None or "key" not in args or args["key"] is None or args["key"] == "":
           logging.critical("Need a tmdb-key")
           raise RuntimeError("Need a tmdb key");
-      tmdb_key = args["key"]
-      tmdb3.set_key(tmdb_key)
-
-  def _get_image_url(self, img):
+      self.tmdb_key = args["key"]
+      self.base_url = "https://api.themoviedb.org/3/" if 'base-url' not in args else args['base-url']
+      self.image_base_url = "https://image.tmdb.org/t/p/" if 'image-base-url' not in args else args["image-base-url"]
+      # Poster sizes: w92, w154, w185, w342, w500, w780, original
+      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"
+      if 'languages' in args and args["languages"] is not None:
+          self.languages = args["languages"]
+
+  def _get_image_url(self, img, size='original'):
     """Try and get a reasonable size poster image"""
-    # Start with small sizes since posters are normally displayed in
-    # small boxes so no point loading big images.
     if not img:
         return None
-    for size in ('w342', 'w500', 'w780', 'original'):
-        try:
-            ret = img.geturl(size)
-            return ret
-        except:
-            pass
-    # Failed to get a standard size, so return any size
-    return img.geturl()
+    return self.image_base_url + size + "/" + img
+
+
+  def _search_movie(self, title, year, lang = "en"):
+      params = {
+          'api_key' : self.tmdb_key,
+          'language' : lang,
+          'query' : title,
+      };
+      if year:
+          params['primary_release_year'] = year
+
+      logging.debug(params)
+      r = requests.get(
+          self.base_url + "search/movie",
+          params = params,
+          headers = {'Content-Type': 'application/json',
+                     # Does not support this: 'Accept-Language': self.languages
+          })
+      # List of matches
+      return r.json()['results']
+
+  def _search_movie_all_languages(self, title, year):
+      for lang in self.languages.split(","):
+          try:
+              res = self._search_movie(title, year, lang)
+              if res:
+                  return res
+          except:
+              logging.exception("Got exception")
+              pass
+      return None
 
   def fetch_details(self, args):
     logging.debug("Fetching with details %s " % args);
@@ -67,13 +97,9 @@ class Tv_meta_tmdb(object):
         logging.critical("Need a title");
         raise RuntimeError("Need a title");
 
-    # Keep our temporary cache in /tmp, but one per user
-    tmdb3.set_cache(filename='tmdb3.' + str(os.getuid()) + '.cache')
-    # tmdb.set_locale(....) Should be automatic from environment
-
-    res = tmdb3.searchMovie(title, year=year)
+    res = self._search_movie_all_languages(title, year=year)
     logging.debug(res)
-    if len(res) == 0:
+    if res is None or len(res) == 0:
         logging.error("Could not find any matching movie");
         raise LookupError("Could not find match for " + title);
 
@@ -81,10 +107,16 @@ class Tv_meta_tmdb(object):
     res0 = res[0]
     poster = None
     fanart = None
-    poster = self._get_image_url(res0.poster)
-    # Want the biggest image by default for fanart
-    if res0.backdrop:
-        fanart = res0.backdrop.geturl()
+    try:
+        poster = self._get_image_url(res0['poster_path'], self.poster_size)
+    except:
+        pass
+
+    try:
+        fanart = self._get_image_url(res0['backdrop_path'], self.fanart_size)
+    except:
+        pass
+
     logging.debug("poster=%s fanart=%s title=%s year=%s" % (poster, fanart, title, year))
     return {"poster": poster, "fanart": fanart}
 
@@ -98,6 +130,8 @@ if __name__ == '__main__':
                     help='Title to search for.')
     optp.add_option('--year', default=None, type="int",
                     help='Year to search for.')
+    optp.add_option('--tmdb-languages', default=None,
+                    help='Specify tmdb language codes separated by commas, such as "en,sv".')
     optp.add_option('--capabilities', default=None, action="store_true",
                     help='Display program capabilities (for PVR grabber)')
     optp.add_option('--debug', default=None, action="store_true",
@@ -115,7 +149,9 @@ if __name__ == '__main__':
         print("Need a title to search for and a tmdb-key.")
         sys.exit(1)
 
-    grabber = Tv_meta_tmdb({"key" : opts.tmdb_key})
+    grabber = Tv_meta_tmdb({"key" : opts.tmdb_key,
+                            'languages' : opts.tmdb_languages
+    })
     print(json.dumps(grabber.fetch_details({
         "title": opts.title,
         "year" : opts.year,
@@ -125,5 +161,5 @@ if __name__ == '__main__':
       logging.basicConfig(level=logging.INFO, format='%(asctime)s:%(levelname)s:%(module)s:%(message)s')
       sys.exit(process(sys.argv))
   except KeyboardInterrupt: pass
-  except RuntimeError,LookupError:
+  except (RuntimeError,LookupError):
       sys.exit(1)