Merge pull request #1304 from croneter/beta-version

Bump master
This commit is contained in:
croneter 2021-01-24 17:35:00 +01:00 committed by GitHub
commit 94a86b43c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 117 additions and 75 deletions

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.12.9" provider-name="croneter">
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.12.10" provider-name="croneter">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
<import addon="script.module.requests" version="2.9.1" />
@ -83,7 +83,10 @@
<summary lang="lt_LT">Natūralioji „Plex“ integracija į „Kodi“</summary>
<description lang="lt_LT">Prijunkite „Kodi“ prie „Plex Medija Serverio“. Šiame papildinyje daroma prielaida, kad valdote visus savo vaizdo įrašus naudodami „Plex“ (ir nė vieno su „Kodi“). Galite prarasti jau saugomus „Kodi“ vaizdo įrašų ir muzikos duomenų bazių duomenis (kadangi šis papildinys juos tiesiogiai pakeičia). Naudokite savo pačių rizika!</description>
<disclaimer lang="lt_LT">Naudokite savo pačių rizika</disclaimer>
<news>version 2.12.9:
<news>version 2.12.10:
- Fix pictures from Plex picture libraries not working/displaying
version 2.12.9:
- Fix Local variable 'user' referenced before assignement
version 2.12.8:

View file

@ -1,3 +1,6 @@
version 2.12.10:
- Fix pictures from Plex picture libraries not working/displaying
version 2.12.9:
- Fix Local variable 'user' referenced before assignement

View file

@ -62,6 +62,25 @@ class Media(object):
answ['bitDepth'] = None
return answ
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):
"""
Returns the media streams for metadata purposes

View file

@ -136,74 +136,84 @@ def _generate_content(api):
# other fields - let's use the PMS answer to be safe
# See https://github.com/croneter/PlexKodiConnect/issues/1129
if not api.kodi_id or 'title' not in item:
cast = [{
'name': x[0],
'thumbnail': x[1],
'role': x[2],
'order': x[3],
} for x in api.people()['actor']]
item = {
'cast': cast,
'country': api.countries(),
'dateadded': api.date_created(), # e.g '2019-01-03 19:40:59'
'director': api.directors(), # list of [str]
'duration': api.runtime(),
'episode': api.index(),
# 'file': '', # e.g. 'videodb://tvshows/titles/20'
'genre': api.genres(),
# 'imdbnumber': '', # e.g.'341663'
'label': api.title(), # e.g. '1x05. Category 55 Emergency Doomsday Crisis'
'lastplayed': api.lastplayed(), # e.g. '2019-01-04 16:05:03'
'mpaa': api.content_rating(), # e.g. 'TV-MA'
'originaltitle': '', # e.g. 'Titans (2018)'
'playcount': api.viewcount(), # [int]
'plot': api.plot(), # [str]
'plotoutline': api.tagline(),
'premiered': api.premiere_date(), # '2018-10-12'
'rating': api.rating(), # [float]
'season': api.season_number(),
'sorttitle': api.sorttitle(), # 'Titans (2018)'
'studio': api.studios(),
'tag': [], # List of tags this item belongs to
'tagline': api.tagline(),
'thumbnail': '', # e.g. 'image://https%3a%2f%2fassets.tv'
'title': api.title(), # 'Titans (2018)'
'type': api.kodi_type,
'trailer': api.trailer(),
'tvshowtitle': api.show_title(),
'uniqueid': {
'imdbnumber': api.guids.get('imdb') or '',
'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]
}
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
if api.plex_type == v.PLEX_TYPE_PHOTO:
item = {
'title': api.title(),
'label': api.title(),
'type': api.kodi_type,
'dateadded': api.date_created(), # e.g '2019-01-03 19:40:59'
'lastplayed': api.lastplayed(), # e.g. '2019-01-04 16:05:03'
'playcount': api.viewcount(),
}
item.update(api.picture_codec())
else:
cast = [{
'name': x[0],
'thumbnail': x[1],
'role': x[2],
'order': x[3],
} for x in api.people()['actor']]
item = {
'cast': cast,
'country': api.countries(),
'dateadded': api.date_created(), # e.g '2019-01-03 19:40:59'
'director': api.directors(), # list of [str]
'duration': api.runtime(),
'episode': api.index(),
# 'file': '', # e.g. 'videodb://tvshows/titles/20'
'genre': api.genres(),
# 'imdbnumber': '', # e.g.'341663'
'label': api.title(), # e.g. '1x05. Category 55 Emergency Doomsday Crisis'
'lastplayed': api.lastplayed(), # e.g. '2019-01-04 16:05:03'
'mpaa': api.content_rating(), # e.g. 'TV-MA'
'originaltitle': '', # e.g. 'Titans (2018)'
'playcount': api.viewcount(), # [int]
'plot': api.plot(), # [str]
'plotoutline': api.tagline(),
'premiered': api.premiere_date(), # '2018-10-12'
'rating': api.rating(), # [float]
'season': api.season_number(),
'sorttitle': api.sorttitle(), # 'Titans (2018)'
'studio': api.studios(),
'tag': [], # List of tags this item belongs to
'tagline': api.tagline(),
'thumbnail': '', # e.g. 'image://https%3a%2f%2fassets.tv'
'title': api.title(), # 'Titans (2018)'
'type': api.kodi_type,
'trailer': api.trailer(),
'tvshowtitle': api.show_title(),
'uniqueid': {
'imdbnumber': api.guids.get('imdb') or '',
'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
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]
# Some customization
@ -472,16 +482,18 @@ def create_listitem(item, as_tuple=True, offscreen=True,
elif "plugin://script.skin.helper" not in item['file']:
liz.setProperty('IsPlayable', 'true')
nodetype = "Video"
if item["type"] in ["song", "album", "artist"]:
nodetype = "Music"
nodetype = "music"
elif item['type'] == 'photo':
nodetype = 'pictures'
else:
nodetype = 'video'
# extra properties
for key, value in item["extraproperties"].iteritems():
liz.setProperty(key, value)
# video infolabels
if nodetype == "Video":
if nodetype == 'video':
infolabels = {
"title": item.get("title"),
"size": item.get("size"),
@ -532,8 +544,7 @@ def create_listitem(item, as_tuple=True, offscreen=True,
if "date" in item:
infolabels["date"] = item["date"]
# music infolabels
else:
elif nodetype == 'music':
infolabels = {
"title": item.get("title"),
"size": item.get("size"),
@ -553,12 +564,18 @@ def create_listitem(item, as_tuple=True, offscreen=True,
if "lastplayed" in item:
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
# PKC hack: ignore empty type
if item["type"] not in ["recording", "channel", "favourite", ""]:
infolabels["mediatype"] = item["type"]
# 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"]
if "lastplayed" in item: