Skip to content

Commit

Permalink
Python tmdb3: Add API to get correct release dates
Browse files Browse the repository at this point in the history
The Movie Database deprecates the API call to `movie/{id}/releases`
and favours `movie/{id}/release_dates` instead.

The fetched dates are now sorted according the rules of themoviedb,
if a release for a country is available.
Otherwise, the primaray release date reported by `movie/{id}` is used.

See
https://www.themoviedb.org/
https://developers.themoviedb.org/3/
https://developers.themoviedb.org/3/movies/get-movie-release-dates
https://developers.themoviedb.org/3/movies/get-movie-details
  • Loading branch information
rcrdnalor committed Jun 17, 2022
1 parent 3538be1 commit 6c3260c
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 15 deletions.
3 changes: 2 additions & 1 deletion mythtv/bindings/python/tmdb3/tmdb3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from .tmdb_api import Configuration, searchMovie, searchMovieWithYear, \
searchPerson, searchStudio, searchList, searchCollection, \
searchSeries, Person, Movie, Collection, Genre, List, \
Series, Studio, Network, Episode, Season, __version__
Series, Studio, Network, Episode, Season, ReleaseType, \
__version__
from .request import Request, set_key, set_cache
from .locales import get_locale, set_locale
from .tmdb_auth import get_session, set_session
Expand Down
45 changes: 33 additions & 12 deletions mythtv/bindings/python/tmdb3/tmdb3/lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#-----------------------
__title__ = "TheMovieDB.org V3"
__author__ = "Raymond Wagner, Roland Ernst"
__version__ = "0.3.9"
__version__ = "0.3.10"
# 0.1.0 Initial version
# 0.2.0 Add language support, move cache to home directory
# 0.3.0 Enable version detection to allow use in MythTV
Expand All @@ -30,6 +30,7 @@
# 0.3.7.a : Added compatibiliy to python3, tested with python 3.6 and 2.7
# 0.3.8 Sort posters by system language or 'en', if not found for given language
# 0.3.9 Support TV lookup
# 0.3.10 Use new API for release dates for movies

# ~ from optparse import OptionParser
import sys
Expand All @@ -45,7 +46,7 @@ def timeouthandler(signal, frame):

def buildSingle(inetref, opts):
from MythTV.tmdb3.tmdb_exceptions import TMDBRequestInvalid
from MythTV.tmdb3 import Movie, get_locale
from MythTV.tmdb3 import Movie, ReleaseType, get_locale
from MythTV import VideoMetadata
from lxml import etree

Expand Down Expand Up @@ -75,12 +76,11 @@ def buildSingle(inetref, opts):
if movie.title:
m.title = movie.title

releases = list(movie.releases.items())
if movie.releasedate:
m.releasedate = movie.releasedate

releases = list(movie.cert_releases.items())

# get the release date for the wanted country
# TODO if that is not part of the reply use the primary release date (Primary=true)
# if that is not part of the reply use whatever release date is first in list
# if there is not a single release date in the reply, then leave it empty
if len(releases) > 0:
if opts.country:
# resort releases with selected country at top to ensure it
Expand All @@ -89,17 +89,34 @@ def buildSingle(inetref, opts):
if opts.country in r[0]:
index = r[0].index(opts.country)
releases.insert(0, releases.pop(index))

m.releasedate = releases[0][1].releasedate
r_dates_country = releases[0][1].cert_release_dates
r_types_country = [x.releasetype for x in r_dates_country]
# from the mailing list:
# https://www.themoviedb.org/talk/585ad032925141724d0514f4
# sort order for release dates: 2, 3, 1, min (4 ,5, 6)
sorted_dates = []
for rt in [ ReleaseType.Theatrical_limited, # 2
ReleaseType.Theatrical, # 3
ReleaseType.Premiere, # 1
ReleaseType.Digital, # 4
ReleaseType.Physical, # 5
ReleaseType.TV] : # 6
if rt in r_types_country:
r_index = r_types_country.index(rt)
sorted_dates.append(r_dates_country[r_index].releasedate)
if rt < ReleaseType.Digital:
break
if len(sorted_dates) > 0:
m.releasedate = min(sorted_dates)

m.inetref = str(movie.id)
if movie.collection:
m.collectionref = str(movie.collection.id)
if m.releasedate:
m.year = m.releasedate.year
for country, release in releases:
if release.certification:
m.certifications[country] = release.certification
for country, releaseitem in releases:
if releaseitem.cert_release_dates[0].certification:
m.certifications[country] = releaseitem.cert_release_dates[0].certification
for genre in movie.genres:
m.categories.append(genre.name)
for studio in movie.studios:
Expand All @@ -126,10 +143,14 @@ def buildSingle(inetref, opts):
# if no poster of given language was found,
# try to sort by system language and then by language "en"
system_language = py_locale.getdefaultlocale()[0].split("_")[0]
system_country = py_locale.getdefaultlocale()[0].split("_")[1]
locale_language = get_locale().language
locale_country = get_locale().country
if opts.debug:
print("system_language : ", system_language)
print("locale_language : ", locale_language)
print("system_country : ", system_country)
print("locale_country : ", locale_country)

loc_posters = movie.posters
if len(loc_posters) and loc_posters[0].language != locale_language \
Expand Down
46 changes: 44 additions & 2 deletions mythtv/bindings/python/tmdb3/tmdb3/tmdb_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
Preliminary API specifications can be found at
http://help.themoviedb.org/kb/api/about-3"""

__version__ = "v0.7.1"
__version__ = "v0.7.3"
# 0.1.0 Initial development
# 0.2.0 Add caching mechanism for API queries
# 0.2.1 Temporary work around for broken search paging
Expand Down Expand Up @@ -64,6 +64,7 @@
# 0.7.0.a Added compatibility to python3, tested with python 3.6 and 2.7
# 0.7.1 Changes to support TV series lookup.
# 0.7.2 Removed support for python2.
# 0.7.3 Added API for release dates


from .request import set_key, Request
Expand All @@ -75,13 +76,14 @@

import json
import datetime
from enum import IntEnum

DEBUG = False


def process_date(datestr):
try:
return datetime.date(*[int(x) for x in datestr.split('-')])
return datetime.date(*[int(x) for x in datestr.split("T")[0].split('-')])
except (TypeError, ValueError):
import sys
import warnings
Expand Down Expand Up @@ -316,6 +318,41 @@ def __repr__(self):
return "<{0.__class__.__name__} '{0.title}' ({0.country})>".format(self)


class ReleaseType(IntEnum):
"""
Release dates support for different types.
Proposed sort order for release dates: 2, 3, 1, min (4 ,5, 6)
"""
Premiere = 1
Theatrical_limited = 2
Theatrical = 3
Digital = 4
Physical = 5
TV = 6


class CertReleaseItem(Element):
certification = Datapoint("certification")
language = Datapoint("iso_639_1")
releasedate = Datapoint("release_date", handler=process_date)
releasetype = Datapoint("type")

def __repr__(self):
return (
f"<{self.__class__.__name__} "
f"'{self.certification}', "
f"'{ReleaseType(self.releasetype).name}', "
f"{self.releasedate}>"
)

class CertRelease(Element):
country = Datapoint("iso_3166_1")
cert_release_dates = Datalist("release_dates", handler=CertReleaseItem)

def __repr__(self):
return f"<{self.__class__.__name__} '{self.country}'>"


class Person(Element):
id = Datapoint('id', initarg=1)
name = Datapoint('name')
Expand Down Expand Up @@ -622,6 +659,9 @@ def _populate_keywords(self):
def _populate_releases(self):
return Request('movie/{0}/releases'.format(self.id))

def _populate_cert_releases(self):
return Request(f"movie/{self.id}/release_dates")

def _populate_trailers(self):
return Request('movie/{0}/trailers'.format(self.id),
language=self._locale.language)
Expand All @@ -645,6 +685,8 @@ def _populate_translations(self):
poller=_populate_keywords)
releases = Datadict('countries', handler=Release,
poller=_populate_releases, attr='country')
cert_releases = Datadict("results", handler=CertRelease,
poller=_populate_cert_releases, attr="country")
youtube_trailers = Datalist('youtube', handler=YoutubeTrailer,
poller=_populate_trailers)
apple_trailers = Datalist('quicktime', handler=AppleTrailer,
Expand Down

0 comments on commit 6c3260c

Please sign in to comment.