Merge pull request #1298 from croneter/fix-pix

Fix pictures from Plex picture libraries not working/displaying
This commit is contained in:
croneter 2021-01-24 16:51:03 +01:00 committed by GitHub
commit 43921b1f9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 73 deletions

View file

@ -89,6 +89,25 @@ class Media(object):
'gain': cast(float, self._from_stream_or_part('gain')) 'gain': cast(float, self._from_stream_or_part('gain'))
} }
def picture_codec(self):
"""
Returns the exif metadata of pictures. This does NOT seem to be used
reliably by Kodi skins! (e.g. not at all)
"""
return {
'exif:CameraMake': self.xml[0].get('make'), # e.g. 'Canon'
'exif:CameraModel': self.xml[0].get('model'), # e.g. 'Canon XYZ'
'exif:DateTime': self.xml.get('originallyAvailableAt', '').replace('-', ':') or None, # e.g. '2017-11-05'
'exif:Height': self.xml[0].get('height'), # e.g. '2160'
'exif:Width': self.xml[0].get('width'), # e.g. '3240'
'exif:Orientation': self.xml[0][self.part].get('orientation'), # e.g. '1'
'exif:FocalLength': self.xml[0].get('focalLength'), # TO BE VALIDATED
'exif:ExposureTime': self.xml[0].get('exposure'), # e.g. '1/1000'
'exif:ApertureFNumber': self.xml[0].get('aperture'), # e.g. 'f/5.0'
'exif:ISOequivalent': self.xml[0].get('iso'), # e.g. '1600'
# missing on Kodi side: lens, e.g. "EF50mm f/1.8 II"
}
def mediastreams(self): def mediastreams(self):
""" """
Returns the media streams for metadata purposes Returns the media streams for metadata purposes

View file

@ -133,74 +133,84 @@ def _generate_content(api):
# other fields - let's use the PMS answer to be safe # other fields - let's use the PMS answer to be safe
# See https://github.com/croneter/PlexKodiConnect/issues/1129 # See https://github.com/croneter/PlexKodiConnect/issues/1129
if not api.kodi_id or 'title' not in item: if not api.kodi_id or 'title' not in item:
cast = [{ if api.plex_type == v.PLEX_TYPE_PHOTO:
'name': x[0], item = {
'thumbnail': x[1], 'title': api.title(),
'role': x[2], 'label': api.title(),
'order': x[3], 'type': api.kodi_type,
} for x in api.people()['actor']] 'dateadded': api.date_created(), # e.g '2019-01-03 19:40:59'
item = { 'lastplayed': api.lastplayed(), # e.g. '2019-01-04 16:05:03'
'cast': cast, 'playcount': api.viewcount(),
'country': api.countries(), }
'dateadded': api.date_created(), # e.g '2019-01-03 19:40:59' item.update(api.picture_codec())
'director': api.directors(), # list of [str] else:
'duration': api.runtime(), cast = [{
'episode': api.index(), 'name': x[0],
# 'file': '', # e.g. 'videodb://tvshows/titles/20' 'thumbnail': x[1],
'genre': api.genres(), 'role': x[2],
# 'imdbnumber': '', # e.g.'341663' 'order': x[3],
'label': api.title(), # e.g. '1x05. Category 55 Emergency Doomsday Crisis' } for x in api.people()['actor']]
'lastplayed': api.lastplayed(), # e.g. '2019-01-04 16:05:03' item = {
'mpaa': api.content_rating(), # e.g. 'TV-MA' 'cast': cast,
'originaltitle': '', # e.g. 'Titans (2018)' 'country': api.countries(),
'playcount': api.viewcount(), # [int] 'dateadded': api.date_created(), # e.g '2019-01-03 19:40:59'
'plot': api.plot(), # [str] 'director': api.directors(), # list of [str]
'plotoutline': api.tagline(), 'duration': api.runtime(),
'premiered': api.premiere_date(), # '2018-10-12' 'episode': api.index(),
'rating': api.rating(), # [float] # 'file': '', # e.g. 'videodb://tvshows/titles/20'
'season': api.season_number(), 'genre': api.genres(),
'sorttitle': api.sorttitle(), # 'Titans (2018)' # 'imdbnumber': '', # e.g.'341663'
'studio': api.studios(), 'label': api.title(), # e.g. '1x05. Category 55 Emergency Doomsday Crisis'
'tag': [], # List of tags this item belongs to 'lastplayed': api.lastplayed(), # e.g. '2019-01-04 16:05:03'
'tagline': api.tagline(), 'mpaa': api.content_rating(), # e.g. 'TV-MA'
'thumbnail': '', # e.g. 'image://https%3a%2f%2fassets.tv' 'originaltitle': '', # e.g. 'Titans (2018)'
'title': api.title(), # 'Titans (2018)' 'playcount': api.viewcount(), # [int]
'type': api.kodi_type, 'plot': api.plot(), # [str]
'trailer': api.trailer(), 'plotoutline': api.tagline(),
'tvshowtitle': api.show_title(), 'premiered': api.premiere_date(), # '2018-10-12'
'uniqueid': { 'rating': api.rating(), # [float]
'imdbnumber': api.guids.get('imdb') or '', 'season': api.season_number(),
'tvdb_id': api.guids.get('tvdb') or '', 'sorttitle': api.sorttitle(), # 'Titans (2018)'
'tmdb_id': api.guids.get('tmdb') or '' 'studio': api.studios(),
}, 'tag': [], # List of tags this item belongs to
'votes': '0', # [str]! 'tagline': api.tagline(),
'writer': api.writers(), # list of [str] 'thumbnail': '', # e.g. 'image://https%3a%2f%2fassets.tv'
'year': api.year(), # [int] 'title': api.title(), # 'Titans (2018)'
} 'type': api.kodi_type,
'trailer': api.trailer(),
if plex_type in (v.PLEX_TYPE_EPISODE, v.PLEX_TYPE_SEASON, v.PLEX_TYPE_SHOW): 'tvshowtitle': api.show_title(),
leaves = api.leave_count() 'uniqueid': {
if leaves: 'imdbnumber': api.guids.get('imdb') or '',
item['extraproperties'] = leaves 'tvdb_id': api.guids.get('tvdb') or '',
'tmdb_id': api.guids.get('tmdb') or ''
},
'votes': '0', # [str]!
'writer': api.writers(), # list of [str]
'year': api.year(), # [int]
}
# Add all info for e.g. video and audio streams
item['streamdetails'] = api.mediastreams()
# Cleanup required due to the way metadatautils works
if not item['lastplayed']:
del item['lastplayed']
for stream in item['streamdetails']['video']:
stream['height'] = utils.cast(int, stream['height'])
stream['width'] = utils.cast(int, stream['width'])
stream['aspect'] = utils.cast(float, stream['aspect'])
item['streamdetails']['subtitle'] = [{'language': x} for x in item['streamdetails']['subtitle']]
# Resume point
resume = api.resume_point()
if resume:
item['resume'] = {
'position': resume,
'total': api.runtime()
}
if plex_type in (v.PLEX_TYPE_EPISODE, v.PLEX_TYPE_SEASON, v.PLEX_TYPE_SHOW):
leaves = api.leave_count()
if leaves:
item['extraproperties'] = leaves
# Add all the artwork we can # Add all the artwork we can
item['art'] = api.artwork(full_artwork=True) item['art'] = api.artwork(full_artwork=True)
# Add all info for e.g. video and audio streams
item['streamdetails'] = api.mediastreams()
# Cleanup required due to the way metadatautils works
if not item['lastplayed']:
del item['lastplayed']
for stream in item['streamdetails']['video']:
stream['height'] = utils.cast(int, stream['height'])
stream['width'] = utils.cast(int, stream['width'])
stream['aspect'] = utils.cast(float, stream['aspect'])
item['streamdetails']['subtitle'] = [{'language': x} for x in item['streamdetails']['subtitle']]
# Resume point
resume = api.resume_point()
if resume:
item['resume'] = {
'position': resume,
'total': api.runtime()
}
item['icon'] = v.ICON_FROM_PLEXTYPE[plex_type] item['icon'] = v.ICON_FROM_PLEXTYPE[plex_type]
# Some customization # Some customization
@ -462,16 +472,18 @@ def create_listitem(item, as_tuple=True, offscreen=True,
elif "plugin://script.skin.helper" not in item['file']: elif "plugin://script.skin.helper" not in item['file']:
liz.setProperty('IsPlayable', 'true') liz.setProperty('IsPlayable', 'true')
nodetype = "Video"
if item["type"] in ["song", "album", "artist"]: if item["type"] in ["song", "album", "artist"]:
nodetype = "Music" nodetype = "music"
elif item['type'] == 'photo':
nodetype = 'pictures'
else:
nodetype = 'video'
# extra properties # extra properties
for key, value in item["extraproperties"].items(): for key, value in item["extraproperties"].items():
liz.setProperty(key, value) liz.setProperty(key, value)
# video infolabels if nodetype == 'video':
if nodetype == "Video":
infolabels = { infolabels = {
"title": item.get("title"), "title": item.get("title"),
"size": item.get("size"), "size": item.get("size"),
@ -522,8 +534,7 @@ def create_listitem(item, as_tuple=True, offscreen=True,
if "date" in item: if "date" in item:
infolabels["date"] = item["date"] infolabels["date"] = item["date"]
# music infolabels elif nodetype == 'music':
else:
infolabels = { infolabels = {
"title": item.get("title"), "title": item.get("title"),
"size": item.get("size"), "size": item.get("size"),
@ -543,12 +554,18 @@ def create_listitem(item, as_tuple=True, offscreen=True,
if "lastplayed" in item: if "lastplayed" in item:
infolabels["lastplayed"] = item["lastplayed"] infolabels["lastplayed"] = item["lastplayed"]
else:
# Pictures
infolabels = {
"title": item.get("title"),
'picturepath': item['file']
}
# setting the dbtype and dbid is supported from kodi krypton and up # setting the dbtype and dbid is supported from kodi krypton and up
# PKC hack: ignore empty type # PKC hack: ignore empty type
if item["type"] not in ["recording", "channel", "favourite", ""]: if item["type"] not in ["recording", "channel", "favourite", ""]:
infolabels["mediatype"] = item["type"] infolabels["mediatype"] = item["type"]
# setting the dbid on music items is not supported ? # setting the dbid on music items is not supported ?
if nodetype == "Video" and "DBID" in item["extraproperties"]: if nodetype == "video" and "DBID" in item["extraproperties"]:
infolabels["dbid"] = item["extraproperties"]["DBID"] infolabels["dbid"] = item["extraproperties"]["DBID"]
if "lastplayed" in item: if "lastplayed" in item: