Support metadata provider ids (e.g. IMDB) for new Plex Movie Agent

This commit is contained in:
croneter 2020-11-05 15:47:04 +01:00
parent 3f74113e02
commit 5d67d4a602
6 changed files with 102 additions and 111 deletions

View file

@ -145,3 +145,27 @@ class ItemBase(object):
encountered by PKC encountered by PKC
""" """
return section_id in app.SYNC.section_ids return section_id in app.SYNC.section_ids
def update_provider_ids(self, api, kodi_id):
"""
Updates the unique metadata provider ids (such as the IMDB id). Returns
a dict of the Kodi unique ids
"""
# We might have an old provider id stored!
self.kodidb.remove_uniqueid(kodi_id, api.kodi_type)
return self.add_provider_ids(api, kodi_id)
def add_provider_ids(self, api, kodi_id):
"""
Adds the unique ids for all metadata providers to the Kodi database,
such as IMDB or The Movie Database TMDB.
Returns a dict of the Kodi ids: {<provider>: <kodi_unique_id>}
"""
kodi_unique_ids = api.guids.copy()
for provider, provider_id in api.guids.iteritems():
kodi_unique_ids[provider] = self.kodidb.add_uniqueid(
kodi_id,
api.kodi_type,
provider_id,
provider)
return kodi_unique_ids

View file

@ -56,19 +56,7 @@ class Movie(ItemBase):
"default", "default",
api.rating(), api.rating(),
api.votecount()) api.votecount())
if api.provider('imdb') is not None: unique_id = self.update_provider_ids(api, kodi_id)
uniqueid = self.kodidb.update_uniqueid(kodi_id,
v.KODI_TYPE_MOVIE,
'imdb',
api.provider('imdb'))
elif api.provider('tmdb') is not None:
uniqueid = self.kodidb.update_uniqueid(kodi_id,
v.KODI_TYPE_MOVIE,
'tmdb',
api.provider('tmdb'))
else:
self.kodidb.remove_uniqueid(kodi_id, v.KODI_TYPE_MOVIE)
uniqueid = -1
self.kodidb.modify_people(kodi_id, self.kodidb.modify_people(kodi_id,
v.KODI_TYPE_MOVIE, v.KODI_TYPE_MOVIE,
api.people()) api.people())
@ -86,18 +74,7 @@ class Movie(ItemBase):
"default", "default",
api.rating(), api.rating(),
api.votecount()) api.votecount())
if api.provider('imdb') is not None: unique_id = self.add_provider_ids(api, kodi_id)
uniqueid = self.kodidb.add_uniqueid(kodi_id,
v.KODI_TYPE_MOVIE,
api.provider('imdb'),
"imdb")
elif api.provider('tmdb') is not None:
uniqueid = self.kodidb.add_uniqueid(kodi_id,
v.KODI_TYPE_MOVIE,
api.provider('tmdb'),
"tmdb")
else:
uniqueid = -1
self.kodidb.add_people(kodi_id, self.kodidb.add_people(kodi_id,
v.KODI_TYPE_MOVIE, v.KODI_TYPE_MOVIE,
api.people()) api.people())
@ -106,6 +83,8 @@ class Movie(ItemBase):
kodi_id, kodi_id,
v.KODI_TYPE_MOVIE) v.KODI_TYPE_MOVIE)
unique_id = self._prioritize_provider_id(unique_id)
# Update Kodi's main entry # Update Kodi's main entry
self.kodidb.add_movie(kodi_id, self.kodidb.add_movie(kodi_id,
file_id, file_id,
@ -117,7 +96,7 @@ class Movie(ItemBase):
rating_id, rating_id,
api.list_to_string(api.writers()), api.list_to_string(api.writers()),
api.year(), api.year(),
uniqueid, unique_id,
api.sorttitle(), api.sorttitle(),
api.runtime(), api.runtime(),
api.content_rating(), api.content_rating(),
@ -246,3 +225,13 @@ class Movie(ItemBase):
db_item['kodi_type'], db_item['kodi_type'],
api.userrating()) api.userrating())
return True return True
@staticmethod
def _prioritize_provider_id(unique_ids):
"""
Prioritize which ID ends up in the SHOW table (there can only be 1)
tvdb > imdb > tmdb
"""
return unique_ids.get('imdb',
unique_ids.get('tmdb',
unique_ids.get('tvdb')))

View file

@ -194,19 +194,8 @@ class Show(TvShowMixin, ItemBase):
"default", "default",
api.rating(), api.rating(),
api.votecount()) api.votecount())
if api.provider('tvdb') is not None: unique_id = self._prioritize_provider_id(
uniqueid = self.kodidb.update_uniqueid(kodi_id, self.update_provider_ids(api, kodi_id))
v.KODI_TYPE_SHOW,
'tvdb',
api.provider('tvdb'))
elif api.provider('tmdb') is not None:
uniqueid = self.kodidb.update_uniqueid(kodi_id,
v.KODI_TYPE_SHOW,
'tmdb',
api.provider('tmdb'))
else:
self.kodidb.remove_uniqueid(kodi_id, v.KODI_TYPE_SHOW)
uniqueid = -1
self.kodidb.modify_people(kodi_id, self.kodidb.modify_people(kodi_id,
v.KODI_TYPE_SHOW, v.KODI_TYPE_SHOW,
api.people()) api.people())
@ -221,7 +210,7 @@ class Show(TvShowMixin, ItemBase):
api.premiere_date(), api.premiere_date(),
api.list_to_string(api.genres()), api.list_to_string(api.genres()),
api.title(), api.title(),
uniqueid, unique_id,
api.content_rating(), api.content_rating(),
api.list_to_string(api.studios()), api.list_to_string(api.studios()),
api.sorttitle(), api.sorttitle(),
@ -236,18 +225,8 @@ class Show(TvShowMixin, ItemBase):
"default", "default",
api.rating(), api.rating(),
api.votecount()) api.votecount())
if api.provider('tvdb'): unique_id = self._prioritize_provider_id(
uniqueid = self.kodidb.add_uniqueid(kodi_id, self.add_provider_ids(api, kodi_id))
v.KODI_TYPE_SHOW,
api.provider('tvdb'),
'tvdb')
if api.provider('tmdb'):
uniqueid = self.kodidb.add_uniqueid(kodi_id,
v.KODI_TYPE_SHOW,
api.provider('tmdb'),
'tmdb')
else:
uniqueid = -1
self.kodidb.add_people(kodi_id, self.kodidb.add_people(kodi_id,
v.KODI_TYPE_SHOW, v.KODI_TYPE_SHOW,
api.people()) api.people())
@ -263,7 +242,7 @@ class Show(TvShowMixin, ItemBase):
api.premiere_date(), api.premiere_date(),
api.list_to_string(api.genres()), api.list_to_string(api.genres()),
api.title(), api.title(),
uniqueid, unique_id,
api.content_rating(), api.content_rating(),
api.list_to_string(api.studios()), api.list_to_string(api.studios()),
api.sorttitle()) api.sorttitle())
@ -281,6 +260,15 @@ class Show(TvShowMixin, ItemBase):
kodi_pathid=kodi_pathid, kodi_pathid=kodi_pathid,
last_sync=self.last_sync) last_sync=self.last_sync)
@staticmethod
def _prioritize_provider_id(unique_ids):
"""
Prioritize which ID ends up in the SHOW table (there can only be 1)
tvdb > imdb > tmdb
"""
return unique_ids.get('tvdb',
unique_ids.get('imdb',
unique_ids.get('tmdb')))
class Season(TvShowMixin, ItemBase): class Season(TvShowMixin, ItemBase):
def add_update(self, xml, section_name=None, section_id=None, def add_update(self, xml, section_name=None, section_id=None,
@ -459,19 +447,8 @@ class Episode(TvShowMixin, ItemBase):
"default", "default",
api.rating(), api.rating(),
api.votecount()) api.votecount())
if api.provider('tvdb'): unique_id = self._prioritize_provider_id(
uniqueid = self.kodidb.update_uniqueid(kodi_id, self.update_provider_ids(api, kodi_id))
v.KODI_TYPE_EPISODE,
'tvdb',
api.provider('tvdb'))
elif api.provider('tmdb'):
uniqueid = self.kodidb.update_uniqueid(kodi_id,
v.KODI_TYPE_EPISODE,
'tmdb',
api.provider('tmdb'))
else:
self.kodidb.remove_uniqueid(kodi_id, v.KODI_TYPE_EPISODE)
uniqueid = -1
self.kodidb.modify_people(kodi_id, self.kodidb.modify_people(kodi_id,
v.KODI_TYPE_EPISODE, v.KODI_TYPE_EPISODE,
api.people()) api.people())
@ -493,7 +470,7 @@ class Episode(TvShowMixin, ItemBase):
airs_before_episode, airs_before_episode,
fullpath, fullpath,
kodi_pathid, kodi_pathid,
uniqueid, unique_id,
kodi_fileid, # and NOT kodi_fileid_2 kodi_fileid, # and NOT kodi_fileid_2
parent_id, parent_id,
api.userrating(), api.userrating(),
@ -539,18 +516,8 @@ class Episode(TvShowMixin, ItemBase):
"default", "default",
api.rating(), api.rating(),
api.votecount()) api.votecount())
if api.provider('tvdb'): unique_id = self._prioritize_provider_id(
uniqueid = self.kodidb.add_uniqueid(kodi_id, self.add_provider_ids(api, kodi_id))
v.KODI_TYPE_EPISODE,
api.provider('tvdb'),
"tvdb")
elif api.provider('tmdb'):
uniqueid = self.kodidb.add_uniqueid(kodi_id,
v.KODI_TYPE_EPISODE,
api.provider('tmdb'),
"tmdb")
else:
uniqueid = -1
self.kodidb.add_people(kodi_id, self.kodidb.add_people(kodi_id,
v.KODI_TYPE_EPISODE, v.KODI_TYPE_EPISODE,
api.people()) api.people())
@ -575,7 +542,7 @@ class Episode(TvShowMixin, ItemBase):
airs_before_episode, airs_before_episode,
fullpath, fullpath,
kodi_pathid, kodi_pathid,
uniqueid, unique_id,
parent_id, parent_id,
api.userrating()) api.userrating())
self.kodidb.set_resume(kodi_fileid, self.kodidb.set_resume(kodi_fileid,
@ -605,3 +572,13 @@ class Episode(TvShowMixin, ItemBase):
self.kodidb.modify_streams(kodi_fileid, # and NOT kodi_fileid_2 self.kodidb.modify_streams(kodi_fileid, # and NOT kodi_fileid_2
api.mediastreams(), api.mediastreams(),
api.runtime()) api.runtime())
@staticmethod
def _prioritize_provider_id(unique_ids):
"""
Prioritize which ID ends up in the SHOW table (there can only be 1)
tvdb > imdb > tmdb
"""
return unique_ids.get('tvdb',
unique_ids.get('imdb',
unique_ids.get('tmdb')))

View file

@ -186,9 +186,9 @@ class Artwork(object):
# Always seek collection's ids since not provided by PMS # Always seek collection's ids since not provided by PMS
if collection is False: if collection is False:
if media_type == v.PLEX_TYPE_MOVIE: if media_type == v.PLEX_TYPE_MOVIE:
media_id = self.provider('imdb') media_id = self.guids.get('imdb')
elif media_type == v.PLEX_TYPE_SHOW: elif media_type == v.PLEX_TYPE_SHOW:
media_id = self.provider('tvdb') media_id = self.guids.get('tvdb')
if media_id is not None: if media_id is not None:
return media_id, None, None return media_id, None, None
LOG.info('Plex did not provide ID for IMDB or TVDB. Start ' LOG.info('Plex did not provide ID for IMDB or TVDB. Start '

View file

@ -13,6 +13,9 @@ from .. import widgets
LOG = getLogger('PLEX.api') LOG = getLogger('PLEX.api')
METADATA_PROVIDERS = (('imdb', utils.REGEX_IMDB),
('tvdb', utils.REGEX_TVDB),
('tmdb', utils.REGEX_TMDB))
class Base(object): class Base(object):
""" """
@ -40,6 +43,7 @@ class Base(object):
self._writers = [] self._writers = []
self._producers = [] self._producers = []
self._locations = [] self._locations = []
self._guids = {}
self._coll_match = None self._coll_match = None
# Plex DB attributes # Plex DB attributes
self._section_id = None self._section_id = None
@ -131,6 +135,11 @@ class Base(object):
self.check_db() self.check_db()
return self._fanart_synced return self._fanart_synced
@property
def guids(self):
self._scan_children()
return self._guids
def check_db(self, plexdb=None): def check_db(self, plexdb=None):
""" """
Check's whether we synched this item to Kodi. If so, then retrieve the Check's whether we synched this item to Kodi. If so, then retrieve the
@ -457,6 +466,24 @@ class Base(object):
elif child.tag == 'Collection': elif child.tag == 'Collection':
self._collections.append((cast(int, child.get('id')), self._collections.append((cast(int, child.get('id')),
child.get('tag'))) child.get('tag')))
elif child.tag == 'Guid':
guid = child.get('id')
guid = guid.split('://', 1)
self._guids[guid[0]] = guid[1]
# Plex Movie agent (legacy) or "normal" Plex tv show agent
if not self._guids:
guid = self.xml.get('guid')
if not guid:
return
for provider, regex in METADATA_PROVIDERS:
provider_id = regex.findall(guid)
try:
self._guids[provider] = provider_id[0]
except IndexError:
pass
else:
# There will only ever be one entry
break
def cast(self): def cast(self):
""" """
@ -544,33 +571,6 @@ class Base(object):
'writer': [(x, ) for x in self._writers] 'writer': [(x, ) for x in self._writers]
} }
def provider(self, providername=None):
"""
providername: e.g. 'imdb', 'tvdb'
Return IMDB, e.g. "tt0903624". Returns None if not found
"""
item = self.xml.get('guid')
if not item:
return
if providername == 'imdb':
regex = utils.REGEX_IMDB
elif providername == 'tvdb':
# originally e.g. com.plexapp.agents.thetvdb://276564?lang=en
regex = utils.REGEX_TVDB
elif providername == 'tmdb':
# originally e.g. com.plexapp.agents.themoviedb://603?lang=en
regex = utils.REGEX_TMDB
else:
raise NotImplementedError('Not implemented: %s' % providername)
provider = regex.findall(item)
try:
provider = provider[0]
except IndexError:
provider = None
return provider
def extras(self): def extras(self):
""" """
Returns an iterator for etree elements for each extra, e.g. trailers Returns an iterator for etree elements for each extra, e.g. trailers

View file

@ -168,8 +168,9 @@ def _generate_content(api):
'trailer': api.trailer(), 'trailer': api.trailer(),
'tvshowtitle': api.show_title(), 'tvshowtitle': api.show_title(),
'uniqueid': { 'uniqueid': {
'imdbnumber': api.provider('imdb') or '', 'imdbnumber': api.guids.get('imdb') or '',
'tvdb_id': api.provider('tvdb') or '' 'tvdb_id': api.guids.get('tvdb') or '',
'tmdb_id': api.guids.get('tmdb') or ''
}, },
'votes': '0', # [str]! 'votes': '0', # [str]!
'writer': api.writers(), # list of [str] 'writer': api.writers(), # list of [str]