Prep On Deck

This commit is contained in:
tomkat83 2016-03-14 17:47:05 +01:00
parent a4673b0377
commit 037925a030
8 changed files with 192 additions and 71 deletions

View file

@ -68,7 +68,8 @@ class Main:
'switchuser': entrypoint.switchPlexUser, 'switchuser': entrypoint.switchPlexUser,
'deviceid': entrypoint.resetDeviceId, 'deviceid': entrypoint.resetDeviceId,
'reConnect': entrypoint.reConnect, 'reConnect': entrypoint.reConnect,
'delete': entrypoint.deleteItem 'delete': entrypoint.deleteItem,
'browseplex': entrypoint.BrowsePlexContent
} }
if "/extrafanart" in sys.argv[0]: if "/extrafanart" in sys.argv[0]:
@ -98,6 +99,12 @@ class Main:
elif mode == "browsecontent": elif mode == "browsecontent":
modes[mode]( itemid, params.get('type',[""])[0], params.get('folderid',[""])[0] ) modes[mode]( itemid, params.get('type',[""])[0], params.get('folderid',[""])[0] )
elif mode == 'browseplex':
modes[mode](
itemid,
params.get('type', [""])[0],
params.get('folderid', [""])[0])
elif mode == "channelsfolder": elif mode == "channelsfolder":
folderid = params['folderid'][0] folderid = params['folderid'][0]
modes[mode](itemid, folderid) modes[mode](itemid, folderid)

View file

@ -411,4 +411,8 @@
<string id="39407">Full library sync finished</string> <string id="39407">Full library sync finished</string>
<string id="39408">Sync had to skip some items because they could not be processed. Kodi may be instable now!! Please post your Kodi logs to the Plex forum.</string> <string id="39408">Sync had to skip some items because they could not be processed. Kodi may be instable now!! Please post your Kodi logs to the Plex forum.</string>
<!-- Plex videonodes.py -->
<string id="39500">On Deck</string>
</strings> </strings>

View file

@ -343,4 +343,7 @@
<string id="39407">Plex Bibliotheken aktualisiert</string> <string id="39407">Plex Bibliotheken aktualisiert</string>
<string id="39408">Einige Plex Einträge mussten übersprungen werden, da sie nicht verarbeitet werden konnten. Kodi ist nun möglicherweise instabil!! Bitte teilen Sie Ihr Kodi log im Plex Forum.</string> <string id="39408">Einige Plex Einträge mussten übersprungen werden, da sie nicht verarbeitet werden konnten. Kodi ist nun möglicherweise instabil!! Bitte teilen Sie Ihr Kodi log im Plex Forum.</string>
<!-- Plex videonodes.py -->
<string id="39500">Aktuell</string>
</strings> </strings>

View file

@ -2194,8 +2194,75 @@ class API():
mapping[kodiindex] = index mapping[kodiindex] = index
externalsubs.append(url) externalsubs.append(url)
kodiindex += 1 kodiindex += 1
mapping = json.dumps(mapping) mapping = json.dumps(mapping)
utils.window('emby_%s.indexMapping' % playurl, value=mapping) utils.window('emby_%s.indexMapping' % playurl, value=mapping)
return externalsubs return externalsubs
def CreateListItemFromPlexItem(self, listItem=None):
"""
Call on a child level of PMS xml response (e.g. in a for loop)
listItem: existing xbmcgui.ListItem to work with
otherwise, a new one is created
Returns XBMC listitem for this PMS library item
"""
people = self.getPeople()
userdata = self.getUserData()
title, sorttitle = self.getTitle()
if listItem is None:
listItem = xbmcgui.ListItem()
metadata = {
'genre': self.joinList(self.getGenres()),
'year': self.getYear(),
'rating': self.getAudienceRating(),
'playcount': userdata['PlayCount'],
'cast': people['Cast'],
'director': self.joinList(people.get('Director')),
'plot': self.getPlot(),
'title': title,
'sorttitle': sorttitle,
'duration': userdata['Runtime'],
'studio': self.joinList(self.getStudios()),
'tagline': self.getTagline(),
'writer': self.joinList(people.get('Writer')),
'premiered': self.getPremiereDate(),
'dateadded': self.getDateCreated(),
'lastplayed': userdata['LastPlayedDate'],
'mpaa': self.getMpaa(),
'aired': self.getPremiereDate()
}
if "episode" in self.getType():
# Only for tv shows
key, show, season, episode = self.getEpisodeDetails()
metadata['episode'] = episode
metadata['season'] = season
metadata['tvshowtitle'] = show
listItem.setProperty('IsPlayable', 'true')
listItem.setProperty('IsFolder', 'false')
listItem.setProperty('embyid', self.getRatingKey())
listItem.setLabel(title)
listItem.setInfo('video', infoLabels=metadata)
return listItem
def AddStreamInfo(self, listItem):
"""
Add media stream information to xbmcgui.ListItem
"""
mediastreams = self.getMediaStreams()
videostreamFound = False
if mediastreams:
for key, value in mediastreams.iteritems():
if key == "video" and value:
videostreamFound = True
if value:
listItem.addStreamInfo(key, value)
if not videostreamFound:
# just set empty streamdetails to prevent errors in the logs
listItem.addStreamInfo(
"video", {'duration': self.getRuntime()[1]})

View file

@ -307,7 +307,13 @@ def GetAllPlexLeaves(viewId, lastViewedAt=None, updatedAt=None,
url += '?' + '&'.join(args) + '&' url += '?' + '&'.join(args) + '&'
else: else:
url += '?' url += '?'
return DownloadChunks(url, containerSize)
def GetPlexOnDeck(viewId, containerSize=None):
"""
"""
url = "{server}/library/sections/%s/onDeck?" % viewId
return DownloadChunks(url, containerSize) return DownloadChunks(url, containerSize)
@ -329,31 +335,31 @@ def GetPlexCollections(mediatype):
""" """
collections = [] collections = []
url = "{server}/library/sections" url = "{server}/library/sections"
jsondata = downloadutils.DownloadUtils().downloadUrl(url) xml = downloadutils.DownloadUtils().downloadUrl(url)
try: try:
result = jsondata['_children'] xml.attrib
except KeyError: except AttributeError:
pass logMsg(title, 'Could not download PMS sections for %s' % url, -1)
else: return {}
for item in result: for item in xml:
contentType = item['type'] contentType = item['type']
if contentType in mediatype: if contentType in mediatype:
name = item['title'] name = item['title']
contentId = item['key'] contentId = item['key']
uuid = item['uuid'] uuid = item['uuid']
collections.append({ collections.append({
'name': name, 'name': name,
'type': contentType, 'type': contentType,
'id': str(contentId), 'id': str(contentId),
'uuid': uuid 'uuid': uuid
}) })
return collections return collections
def GetPlexPlaylist(itemid, librarySectionUUID, mediatype='movie'): def GetPlexPlaylist(itemid, librarySectionUUID, mediatype='movie'):
""" """
Returns raw API metadata XML dump for a playlist with e.g. trailers. Returns raw API metadata XML dump for a playlist with e.g. trailers.
""" """
trailerNumber = settings('trailerNumber') trailerNumber = settings('trailerNumber')
if not trailerNumber: if not trailerNumber:
trailerNumber = '3' trailerNumber = '3'

View file

@ -23,6 +23,7 @@ import playutils
import playlist import playlist
import PlexFunctions import PlexFunctions
import PlexAPI
############################################################################### ###############################################################################
@ -670,13 +671,19 @@ def GetSubFolders(nodeindex):
##### BROWSE EMBY NODES DIRECTLY ##### ##### BROWSE EMBY NODES DIRECTLY #####
def BrowseContent(viewname, type="", folderid=""): def BrowseContent(viewname, type="", folderid=""):
"""
Plex:
viewname: PMS name of the library
type: PMS library section ID
folderid: e.g. 'ondeck'
"""
emby = embyserver.Read_EmbyServer() emby = embyserver.Read_EmbyServer()
art = artwork.Artwork() art = artwork.Artwork()
doUtils = downloadutils.DownloadUtils() doUtils = downloadutils.DownloadUtils()
#folderid used as filter ? #folderid used as filter ?
if folderid in ["recent","recentepisodes","inprogress","inprogressepisodes","unwatched","nextepisodes","sets","genres","random","recommended"]: if folderid in ["recent","recentepisodes","inprogress","inprogressepisodes","unwatched","nextepisodes","sets","genres","random","recommended",
"ondeck"]:
filter = folderid filter = folderid
folderid = "" folderid = ""
else: else:
@ -685,7 +692,7 @@ def BrowseContent(viewname, type="", folderid=""):
xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname) xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname)
#get views for root level #get views for root level
if not folderid: if not folderid:
views = emby.getViews(type) views = PlexFunctions.GetPlexCollections()
for view in views: for view in views:
if view.get("name") == viewname.decode('utf-8'): if view.get("name") == viewname.decode('utf-8'):
folderid = view.get("id") folderid = view.get("id")
@ -1278,3 +1285,66 @@ def RunLibScan(mode):
line1=string(39205)) line1=string(39205))
else: else:
utils.window('plex_runLibScan', value='full') utils.window('plex_runLibScan', value='full')
def BrowsePlexContent(viewid, mediatype="", nodetype=""):
"""
Plex:
viewid: PMS name of the library
mediatype: mediatype, e.g. 'movies', 'tvshows', 'photos'
nodetype: e.g. 'ondeck'
"""
utils.logMsg(title, "BrowsePlexContent called with viewid: %s, mediatype: %s, nodetype: %s" % (viewid, mediatype, nodetype), 1)
if nodetype == 'ondeck':
xml = PlexFunctions.GetPlexOnDeck(
viewid,
containerSize=int(utils.settings('limitindex')))
if not xml:
utils.logMsg(title, "Cannot get view for section %s" % viewid, -1)
return
viewname = xml.attrib.get('librarySectionTitle')
xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname)
# set the correct params for the content type
if mediatype.lower() == "homevideos, tvshows":
xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
itemtype = "Video,Folder,PhotoAlbum"
elif mediatype.lower() == "photos":
xbmcplugin.setContent(int(sys.argv[1]), 'files')
itemtype = "Photo,PhotoAlbum,Folder"
else:
itemtype = ""
# process the listing
for item in xml:
API = PlexAPI.API(item)
li = API.CreateListItemFromPlexItem()
if item.tag == 'Directory':
# for folders we add an additional browse request, passing the
# folderId
li.setProperty('IsFolder', 'true')
li.setProperty('IsPlayable', 'false')
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0].decode('utf-8'), viewname.decode('utf-8'), type.decode('utf-8'), item.get("Id").decode('utf-8'))
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
else:
# playable item, set plugin path and mediastreams
path = "%s?id=%s&mode=play" % (sys.argv[0], API.getRatingKey())
li.setProperty("path", path)
API.AddStreamInfo(li)
pbutils.PlaybackUtils(item).setArtwork(li)
xbmcplugin.addDirectoryItem(
handle=int(sys.argv[1]),
url=li.getProperty("path"),
listitem=li)
if filter == "recent":
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
else:
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_TITLE)
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RATING)
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RUNTIME)
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))

View file

@ -70,7 +70,7 @@ class PlaybackUtils():
window('emby_%s.playmethod' % playurl, "Transcode") window('emby_%s.playmethod' % playurl, "Transcode")
listitem.setPath(playurl) listitem.setPath(playurl)
self.setArtwork(listitem) self.setArtwork(listitem)
self.setListItem(listitem) API.CreateListItemFromPlexItem(listitem)
self.setProperties(playurl, listitem) self.setProperties(playurl, listitem)
return xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem) return xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
@ -159,7 +159,7 @@ class PlaybackUtils():
self.setProperties(additionalPlayurl, additionalListItem) self.setProperties(additionalPlayurl, additionalListItem)
self.setArtwork(additionalListItem) self.setArtwork(additionalListItem)
# NEW to Plex # NEW to Plex
self.setListItem(additionalListItem) API.CreateListItemFromPlexItem(additionalListItem)
playlist.add(additionalPlayurl, additionalListItem, index=self.currentPosition) playlist.add(additionalPlayurl, additionalListItem, index=self.currentPosition)
self.pl.verifyPlaylist() self.pl.verifyPlaylist()
@ -194,7 +194,7 @@ class PlaybackUtils():
if homeScreen and seektime and window('emby_customPlaylist') != "true": if homeScreen and seektime and window('emby_customPlaylist') != "true":
log("Play as a widget item.", 1) log("Play as a widget item.", 1)
self.setListItem(listitem) API.CreateListItemFromPlexItem(listitem)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
elif ((introsPlaylist and window('emby_customPlaylist') == "true") or elif ((introsPlaylist and window('emby_customPlaylist') == "true") or
@ -368,45 +368,3 @@ class PlaybackUtils():
listItem.setProperty(arttype, path) listItem.setProperty(arttype, path)
else: else:
listItem.setArt({arttype: path}) listItem.setArt({arttype: path})
def setListItem(self, listItem):
API = self.API
mediaType = API.getType()
people = API.getPeople()
userdata = API.getUserData()
title, sorttitle = API.getTitle()
metadata = {
'genre': API.joinList(API.getGenres()),
'year': API.getYear(),
'rating': API.getAudienceRating(),
'playcount': userdata['PlayCount'],
'cast': people['Cast'],
'director': API.joinList(people.get('Director')),
'plot': API.getPlot(),
'title': title,
'sorttitle': sorttitle,
'duration': userdata['Runtime'],
'studio': API.joinList(API.getStudios()),
'tagline': API.getTagline(),
'writer': API.joinList(people.get('Writer')),
'premiered': API.getPremiereDate(),
'dateadded': API.getDateCreated(),
'lastplayed': userdata['LastPlayedDate'],
'mpaa': API.getMpaa(),
'aired': API.getPremiereDate()
}
if "episode" in mediaType:
# Only for tv shows
key, show, season, episode = API.getEpisodeDetails()
metadata['episode'] = episode
metadata['season'] = season
metadata['tvshowtitle'] = show
listItem.setProperty('IsPlayable', 'true')
listItem.setProperty('IsFolder', 'false')
listItem.setLabel(metadata['title'])
listItem.setInfo('video', infoLabels=metadata)

View file

@ -127,6 +127,7 @@ class VideoNodes(object):
'9': "genres", '9': "genres",
'10': "random", '10': "random",
'11': "recommended", '11': "recommended",
'12': "ondeck"
} }
mediatypes = { mediatypes = {
# label according to nodetype per mediatype # label according to nodetype per mediatype
@ -152,10 +153,11 @@ class VideoNodes(object):
'7': 30179, '7': 30179,
'9': 135, '9': 135,
'10': 30229, '10': 30229,
'11': 30230 '11': 30230,
'12': 39500
}, },
'homevideoss': 'homevideos':
{ {
'1': tagname, '1': tagname,
'2': 30251, '2': 30251,
@ -211,6 +213,10 @@ class VideoNodes(object):
elif kodiversion == 14 and nodetype == "inprogressepisodes": elif kodiversion == 14 and nodetype == "inprogressepisodes":
# Custom query # Custom query
path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=inprogressepisodes&limit=50"% tagname path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=inprogressepisodes&limit=50"% tagname
elif nodetype == 'ondeck':
# PLEX custom query
path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=browseplex&type=%s&folderid=%s"
% (viewid, mediatype, nodetype))
else: else:
path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype) path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
@ -248,7 +254,7 @@ class VideoNodes(object):
continue continue
# Create the root # Create the root
if (nodetype == "nextepisodes" or mediatype == "homevideos" or if (nodetype in ("nextepisodes", "ondeck") or mediatype == "homevideos" or
(kodiversion == 14 and nodetype in ('recentepisodes', 'inprogressepisodes'))): (kodiversion == 14 and nodetype in ('recentepisodes', 'inprogressepisodes'))):
# Folder type with plugin path # Folder type with plugin path
root = self.commonRoot(order=node, label=label, tagname=tagname, roottype=2) root = self.commonRoot(order=node, label=label, tagname=tagname, roottype=2)