Support for Plex collection artwork (PKC settings toggle under Artwork )

- Fixes #408
This commit is contained in:
Croneter 2018-07-05 12:46:40 +02:00
parent 70ffc7b826
commit e62b909a75
7 changed files with 102 additions and 24 deletions

View file

@ -574,6 +574,11 @@ msgctxt "#30542"
msgid "Always pick best quality for trailers"
msgstr ""
# PKC Settings - Artwork
msgctxt "#30543"
msgid "Prefer Kodi artwork for collections/sets"
msgstr ""
msgctxt "#30544"
msgid "Artwork"
msgstr ""

View file

@ -114,14 +114,23 @@ class Items(object):
self.kodicursor)
# Also get artwork for collections/movie sets
if kodi_type == v.KODI_TYPE_MOVIE:
for setname in api.collection_list():
for _, setname in api.collection_list():
LOG.debug('Getting artwork for movie set %s', setname)
setid = self.kodi_db.create_collection(setname)
self.artwork.modify_artwork(api.set_artwork(),
external_set_artwork = api.set_artwork()
if (external_set_artwork and
utils.settings('PreferKodiCollectionArt') == 'false'):
# Need to make sure we are not overwriting existing Plex
# collection artwork
plex_artwork = api.artwork(kodi_id=setid,
kodi_type=v.KODI_TYPE_SET)
for art in plex_artwork:
if art in external_set_artwork:
del external_set_artwork[art]
self.artwork.modify_artwork(external_set_artwork,
setid,
v.KODI_TYPE_SET,
self.kodicursor)
self.kodi_db.assign_collection(setid, kodi_id)
return True
def updateUserdata(self, xml):
@ -440,14 +449,32 @@ class Movies(Items):
self.kodi_db.modify_streams(fileid, api.mediastreams(), runtime)
# Process studios
self.kodi_db.modify_studios(movieid, v.KODI_TYPE_MOVIE, studios)
# Process tags: view, Plex collection tags
tags = [viewtag]
tags.extend(collections)
if userdata['Favorite']:
tags.append("Favorite movies")
self.kodi_db.modify_tags(movieid, v.KODI_TYPE_MOVIE, tags)
if collections:
collections_match = api.collections_match()
for plex_set_id, set_name in collections:
tags.append(set_name)
# Add any sets from Plex collection tags
self.kodi_db.add_sets(movieid, collections)
kodi_set_id = self.kodi_db.create_collection(set_name)
self.kodi_db.assign_collection(kodi_set_id, movieid)
for index, plex_id in collections_match:
# Get Plex artwork for collections - a pain
if index == plex_set_id:
set_xml = PF.GetPlexMetadata(plex_id)
try:
set_xml.attrib
except AttributeError:
LOG.error('Could not get set metadata %s', plex_id)
continue
set_api = API(set_xml[0])
artwork.modify_artwork(set_api.artwork(),
kodi_set_id,
v.KODI_TYPE_SET,
kodicursor)
break
self.kodi_db.modify_tags(movieid, v.KODI_TYPE_MOVIE, tags)
# Process playstates
self.kodi_db.set_resume(fileid,
resume,
@ -718,7 +745,7 @@ class TVShows(Items):
self.kodi_db.modify_studios(showid, v.KODI_TYPE_SHOW, studios)
# Process tags: view, PMS collection tags
tags = [viewtag]
tags.extend(collections)
tags.extend([i for _, i in collections])
self.kodi_db.modify_tags(showid, v.KODI_TYPE_SHOW, tags)
@utils.catch_exceptions(warnuser=True)

View file

@ -813,14 +813,6 @@ class KodiDBMethods(object):
'''
self.cursor.execute(query, (kodiid, mediatype, oldtag,))
def add_sets(self, movieid, collections):
"""
Will add the movie to all collections (a list of unicodes)
"""
for setname in collections:
setid = self.create_collection(setname)
self.assign_collection(setid, movieid)
def create_collection(self, set_name):
"""
Returns the collection/set id for set_name [unicode]

View file

@ -31,7 +31,8 @@ http://stackoverflow.com/questions/111945/is-there-any-way-to-do-http-put-in-pyt
"""
from logging import getLogger
from re import sub
from urllib import urlencode, unquote
from urllib import urlencode, unquote, quote
from urlparse import parse_qsl
from xbmcgui import ListItem
from .downloadutils import DownloadUtils as DU
@ -326,13 +327,13 @@ class API(object):
def collection_list(self):
"""
Returns a list of PMS collection tags or an empty list
Returns a list of tuples of the collection id and tags or an empty list
[(<collection id 1>, <collection name 1>), ...]
"""
collections = []
for child in self.item:
if child.tag == 'Collection':
if child.attrib['tag']:
collections.append(child.attrib['tag'])
collections.append((child.get('id'), child.get('tag')))
return collections
def people(self):
@ -816,9 +817,22 @@ class API(object):
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))
if '/composite/' in artwork:
# e.g. Plex collections where artwork already contains width
# and height. Need to upscale for better resolution
artwork, args = artwork.split('?')
args = dict(parse_qsl(args))
width = int(args.get('width', 400))
height = int(args.get('height', 400))
# Adjust to 4k resolution 3,840x2,160
scaling = 3840.0 / float(max(width, height))
width = int(scaling * width)
height = int(scaling * height)
artwork = '%s?width=%s&height=%s' % (artwork, width, height)
artwork = ('%s/photo/:/transcode?width=3840&height=3840&'
'minSize=1&upscale=0&url=%s'
% (self.server, quote(artwork)))
artwork = self.attach_plex_token_to_url(artwork)
return artwork
def artwork(self, kodi_id=None, kodi_type=None, full_artwork=False):
@ -1189,6 +1203,25 @@ class API(object):
break
return artworks
def library_section_id(self):
"""
Returns the id of the Plex library section (for e.g. a movies section)
or None
"""
return self.item.get('librarySectionID')
def collections_match(self):
"""
Downloads one additional xml from the PMS in order to return a list of
tuples [(collection_id, plex_id), ...] for all collections of the
current item's Plex library sectin
Pass in the collection id of e.g. the movie's metadata
"""
xml = PF.collections(self.library_section_id())
if not xml:
return []
return [(i.get('index'), i.get('ratingKey')) for i in xml]
def set_artwork(self):
"""
Gets the URLs to the Plex artwork, or empty string if not found.

View file

@ -735,6 +735,24 @@ def GetPMSStatus(token):
return answer
def collections(section_id):
"""
Returns an etree with list of collections or None.
"""
url = '{server}/library/sections/%s/all' % section_id
params = {
'type': 18, # Collections
'includeCollections': 1,
}
xml = DU().downloadUrl(url, parameters=params)
try:
xml.attrib
except AttributeError:
LOG.error("Error retrieving collections for %s", url)
xml = None
return xml
def scrobble(ratingKey, state):
"""
Tells the PMS to set an item's watched state to state="watched" or

View file

@ -143,6 +143,7 @@ PLEX_PLAYLIST_TYPE_FROM_KODI = {
PLEX_TYPE_VIDEO = 'video'
PLEX_TYPE_MOVIE = 'movie'
PLEX_TYPE_CLIP = 'clip' # e.g. trailers
PLEX_TYPE_SET = 'collection' # sets/collections
PLEX_TYPE_EPISODE = 'episode'
PLEX_TYPE_SEASON = 'season'
@ -257,6 +258,7 @@ KODITYPE_FROM_PLEXTYPE = {
PLEX_TYPE_FROM_KODI_TYPE = {
KODI_TYPE_VIDEO: PLEX_TYPE_VIDEO,
KODI_TYPE_MOVIE: PLEX_TYPE_MOVIE,
KODI_TYPE_SET: PLEX_TYPE_SET,
KODI_TYPE_EPISODE: PLEX_TYPE_EPISODE,
KODI_TYPE_SEASON: PLEX_TYPE_SEASON,
KODI_TYPE_SHOW: PLEX_TYPE_SHOW,

View file

@ -132,7 +132,8 @@
<category label="30544"><!-- artwork -->
<setting id="enableTextureCache" label="30512" type="bool" default="true" /> <!-- Cache all artwork for a smooth Kodi experience -->
<setting id="FanartTV" label="30539" type="bool" default="false" /><!-- Download additional art from FanArtTV -->
<setting label="39222" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect/?mode=fanart)" option="close" visible="eq(-1,true)" subsetting="true" /> <!-- Look for missing fanart on FanartTV now -->
<setting id="PreferKodiCollectionArt" label="30543" type="bool" default="true" visible="eq(-1,true)" subsetting="true"/><!-- Prefer Kodi artwork for collections -->
<setting label="39222" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect/?mode=fanart)" option="close" visible="eq(-2,true)" subsetting="true" /> <!-- Look for missing fanart on FanartTV now -->
<setting id="imageSyncNotifications" label="30008" type="bool" default="true" /><!-- Enable notifications for image caching -->
<setting id="imageSyncDuringPlayback" label="30009" type="bool" default="true" /><!-- Enable image caching during Kodi playback (restart Kodi!) -->
<setting label="39020" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect/?mode=texturecache)" option="close" /> <!-- Cache all images to Kodi texture cache now -->