From b4716ba5115728af745e5654ff9509d272b4da99 Mon Sep 17 00:00:00 2001 From: croneter Date: Sat, 3 Mar 2018 14:40:12 +0100 Subject: [PATCH] Artwork overhaul part 1 --- resources/lib/PlexAPI.py | 105 ++++++++++++++++-------------- resources/lib/itemtypes.py | 30 ++++----- resources/lib/kodidb_functions.py | 19 ++++++ resources/lib/variables.py | 15 +++++ 4 files changed, 104 insertions(+), 65 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index b9d7e6a8..1710a093 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -44,6 +44,7 @@ from utils import window, settings, language as lang, try_decode, try_encode, \ unix_date_to_kodi, exists_dir, slugify, dialog, escape_html import PlexFunctions as PF import plexdb_functions as plexdb +import kodidb_functions as kodidb import variables as v import state @@ -732,51 +733,66 @@ class API(object): 'subtitle': subtitlelanguages } - def _one_artwork(self, entry): - if entry not in self.item.attrib: - return '' - artwork = self.item.attrib[entry] - if artwork.startswith('http'): - pass - else: + def _one_artwork(self, art_kind): + artwork = self.item.get(art_kind) + if artwork and not artwork.startswith('http'): artwork = self.attach_plex_token_to_url( '%s/photo/:/transcode?width=4000&height=4000&' 'minSize=1&upscale=0&url=%s' % (self.server, artwork)) return artwork - def artwork(self, parent_info=False): + def artwork(self, kodi_id=None, kodi_type=None): """ - Gets the URLs to the Plex artwork, or empty string if not found. - parent_info=True will check for parent's artwork if None is found + Gets the URLs to the Plex artwork. Dict keys will be missing if there + is no corresponding artwork. + Pass kodi_id and kodi_type to grab the artwork saved in the Kodi DB + (thus potentially more artwork, e.g. clearart, discart) - Output: + Output ('max' version) { - 'Primary' - 'Art' - 'Banner' - 'Logo' - 'Thumb' - 'Disc' - 'Backdrop' : LIST with the first entry xml key "art" + 'thumb' + 'poster' + 'banner' + 'clearart' + 'clearlogo' + 'landscape' + 'icon' + 'fanart' } """ - allartworks = { - 'Primary': self._one_artwork('thumb'), - 'Art': "", - 'Banner': self._one_artwork('banner'), - 'Logo': "", - 'Thumb': self._one_artwork('grandparentThumb'), - 'Disc': "", - 'Backdrop': [self._one_artwork('art')] - } - # Process parent items if the main item is missing artwork - if parent_info: - # Process parent backdrops - if not allartworks['Backdrop']: - allartworks['Backdrop'].append(self._one_artwork('parentArt')) - if not allartworks['Primary']: - allartworks['Primary'] = self._one_artwork('parentThumb') - return allartworks + if kodi_id: + # in Kodi database, potentially with additional e.g. clearart + if self.plex_type() in v.PLEX_VIDEOTYPES: + with kodidb.GetKodiDB('video') as kodi_db: + return kodi_db.get_art(kodi_id, kodi_type) + else: + with kodidb.GetKodiDB('music') as kodi_db: + return kodi_db.get_art(kodi_id, kodi_type) + + # Grab artwork from Plex + artworks = {} + for kodi_artwork, plex_artwork in v.KODI_TO_PLEX_ARTWORK.iteritems(): + art = self._one_artwork(plex_artwork) + if art: + artworks[kodi_artwork] = art + if self.plex_type() in (v.PLEX_TYPE_EPISODE, + v.PLEX_TYPE_SONG, + v.PLEX_TYPE_ALBUM): + # Process parent item's poster + art = self._one_artwork('grandparentThumb') + if art: + artworks['tvshow.poster'] = art + # Get parent item artwork if the main item is missing artwork + if 'fanart1' not in artworks: + art = self._one_artwork('parentArt') + if art: + artworks['fanart1'] = art + if 'poster' not in artworks: + art = self._one_artwork('parentThumb') + if art: + artworks['poster'] = art + LOG.debug('artworks: %s', artworks) + return artworks def fanart_artwork(self, allartworks): """ @@ -1339,7 +1355,9 @@ class API(object): append_show_title, append_sxxexx) self.add_video_streams(listitem) - self.set_listitem_artwork(listitem) + artwork = self.artwork() + LOG.debug('artwork: %s', artwork) + listitem.setArt(artwork) return listitem def _create_photo_listitem(self, listitem=None): @@ -1545,19 +1563,8 @@ class API(object): """ Set all artwork to the listitem """ - allartwork = self.artwork(parent_info=True) - arttypes = { - 'poster': "Primary", - 'tvshow.poster': "Thumb", - 'clearart': "Primary", - 'tvshow.clearart': "Primary", - 'clearlogo': "Logo", - 'tvshow.clearlogo': "Logo", - 'discart': "Disc", - 'fanart_image': "Backdrop", - 'landscape': "Backdrop", - "banner": "Banner" - } + allartwork = self.artwork() + listitem.setArt(self.artwork()) for arttype in arttypes: art = arttypes[arttype] if art == "Backdrop": diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index c53fb002..d73bd5f2 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -1306,16 +1306,15 @@ class Music(Items): bio = api.plot() # Associate artwork - artworks = api.artwork(parent_info=True) - thumb = artworks['Primary'] - backdrops = artworks['Backdrop'] # List - - if thumb: - thumb = "%s" % thumb - if backdrops: - fanart = "%s" % backdrops[0] + artworks = api.artwork() + if 'poster' in artworks: + thumb = "%s" % artworks['poster'] else: - fanart = "" + thumb = None + if 'fanart1' in artworks: + fanart = "%s" % artworks['fanart1'] + else: + fanart = None # UPDATE THE ARTIST ##### if update_item: @@ -1412,10 +1411,11 @@ class Music(Items): self.compilation = 1 break # Associate artwork - artworks = api.artwork(parent_info=True) - thumb = artworks['Primary'] - if thumb: - thumb = "%s" % thumb + artworks = api.artwork() + if 'poster' in artworks: + thumb = "%s" % artworks['poster'] + else: + thumb = None # UPDATE THE ALBUM ##### if update_item: @@ -1847,9 +1847,7 @@ class Music(Items): # Add genres if genres: self.kodi_db.addMusicGenres(songid, genres, v.KODI_TYPE_SONG) - # Update artwork - allart = api.artwork(parent_info=True) - artwork.addArtwork(allart, songid, v.KODI_TYPE_SONG, kodicursor) + artwork.addArtwork(api.artwork(), songid, v.KODI_TYPE_SONG, kodicursor) if item.get('parentKey') is None: # Update album artwork artwork.addArtwork(allart, albumid, v.KODI_TYPE_ALBUM, kodicursor) diff --git a/resources/lib/kodidb_functions.py b/resources/lib/kodidb_functions.py index 8f98d442..cb535e83 100644 --- a/resources/lib/kodidb_functions.py +++ b/resources/lib/kodidb_functions.py @@ -461,6 +461,25 @@ class KodiDBMethods(object): self.cursor) return actor_id + def get_art(self, kodi_id, kodi_type): + """ + Returns a dict of all available artwork with unicode urls/paths: + { + 'thumb' + 'poster' + 'banner' + 'fanart' + 'clearart' + 'clearlogo' + 'landscape' + 'icon' + } + Missing fanart will not appear in the dict. + """ + query = 'SELECT type, url FROM art WHERE media_id=? AND media_type=?' + self.cursor.execute(query, (kodi_id, kodi_type)) + return dict(self.cursor.fetchall()) + def existingArt(self, kodiId, mediaType, refresh=False): """ For kodiId, returns an artwork dict with already existing art from diff --git a/resources/lib/variables.py b/resources/lib/variables.py index 1674e67e..e1ed163e 100644 --- a/resources/lib/variables.py +++ b/resources/lib/variables.py @@ -180,6 +180,14 @@ KODI_VIDEOTYPES = ( KODI_TYPE_SET ) +PLEX_VIDEOTYPES = ( + PLEX_TYPE_MOVIE, + PLEX_TYPE_CLIP, + PLEX_TYPE_EPISODE, + PLEX_TYPE_SEASON, + PLEX_TYPE_SHOW +) + KODI_AUDIOTYPES = ( KODI_TYPE_SONG, KODI_TYPE_ALBUM, @@ -310,6 +318,13 @@ PLEX_TYPE_FROM_WEBSOCKET = { } +KODI_TO_PLEX_ARTWORK = { + 'poster': 'thumb', + 'banner': 'banner', + 'fanart1': 'art' +} + + # extensions from: # http://kodi.wiki/view/Features_and_supported_codecs#Format_support (RAW image # formats, BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX and Targa/TGA)