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,
'deviceid': entrypoint.resetDeviceId,
'reConnect': entrypoint.reConnect,
'delete': entrypoint.deleteItem
'delete': entrypoint.deleteItem,
'browseplex': entrypoint.BrowsePlexContent
}
if "/extrafanart" in sys.argv[0]:
@ -98,6 +99,12 @@ class Main:
elif mode == "browsecontent":
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":
folderid = params['folderid'][0]
modes[mode](itemid, folderid)

View file

@ -411,4 +411,8 @@
<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>
<!-- Plex videonodes.py -->
<string id="39500">On Deck</string>
</strings>

View file

@ -343,4 +343,7 @@
<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>
<!-- Plex videonodes.py -->
<string id="39500">Aktuell</string>
</strings>

View file

@ -2194,8 +2194,75 @@ class API():
mapping[kodiindex] = index
externalsubs.append(url)
kodiindex += 1
mapping = json.dumps(mapping)
utils.window('emby_%s.indexMapping' % playurl, value=mapping)
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) + '&'
else:
url += '?'
return DownloadChunks(url, containerSize)
def GetPlexOnDeck(viewId, containerSize=None):
"""
"""
url = "{server}/library/sections/%s/onDeck?" % viewId
return DownloadChunks(url, containerSize)
@ -329,31 +335,31 @@ def GetPlexCollections(mediatype):
"""
collections = []
url = "{server}/library/sections"
jsondata = downloadutils.DownloadUtils().downloadUrl(url)
xml = downloadutils.DownloadUtils().downloadUrl(url)
try:
result = jsondata['_children']
except KeyError:
pass
else:
for item in result:
contentType = item['type']
if contentType in mediatype:
name = item['title']
contentId = item['key']
uuid = item['uuid']
collections.append({
'name': name,
'type': contentType,
'id': str(contentId),
'uuid': uuid
})
xml.attrib
except AttributeError:
logMsg(title, 'Could not download PMS sections for %s' % url, -1)
return {}
for item in xml:
contentType = item['type']
if contentType in mediatype:
name = item['title']
contentId = item['key']
uuid = item['uuid']
collections.append({
'name': name,
'type': contentType,
'id': str(contentId),
'uuid': uuid
})
return collections
def GetPlexPlaylist(itemid, librarySectionUUID, mediatype='movie'):
"""
Returns raw API metadata XML dump for a playlist with e.g. trailers.
"""
"""
trailerNumber = settings('trailerNumber')
if not trailerNumber:
trailerNumber = '3'

View file

@ -23,6 +23,7 @@ import playutils
import playlist
import PlexFunctions
import PlexAPI
###############################################################################
@ -670,13 +671,19 @@ def GetSubFolders(nodeindex):
##### BROWSE EMBY NODES DIRECTLY #####
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()
art = artwork.Artwork()
doUtils = downloadutils.DownloadUtils()
#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
folderid = ""
else:
@ -685,7 +692,7 @@ def BrowseContent(viewname, type="", folderid=""):
xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname)
#get views for root level
if not folderid:
views = emby.getViews(type)
views = PlexFunctions.GetPlexCollections()
for view in views:
if view.get("name") == viewname.decode('utf-8'):
folderid = view.get("id")
@ -1278,3 +1285,66 @@ def RunLibScan(mode):
line1=string(39205))
else:
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")
listitem.setPath(playurl)
self.setArtwork(listitem)
self.setListItem(listitem)
API.CreateListItemFromPlexItem(listitem)
self.setProperties(playurl, listitem)
return xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
@ -159,7 +159,7 @@ class PlaybackUtils():
self.setProperties(additionalPlayurl, additionalListItem)
self.setArtwork(additionalListItem)
# NEW to Plex
self.setListItem(additionalListItem)
API.CreateListItemFromPlexItem(additionalListItem)
playlist.add(additionalPlayurl, additionalListItem, index=self.currentPosition)
self.pl.verifyPlaylist()
@ -194,7 +194,7 @@ class PlaybackUtils():
if homeScreen and seektime and window('emby_customPlaylist') != "true":
log("Play as a widget item.", 1)
self.setListItem(listitem)
API.CreateListItemFromPlexItem(listitem)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
elif ((introsPlaylist and window('emby_customPlaylist') == "true") or
@ -368,45 +368,3 @@ class PlaybackUtils():
listItem.setProperty(arttype, path)
else:
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",
'10': "random",
'11': "recommended",
'12': "ondeck"
}
mediatypes = {
# label according to nodetype per mediatype
@ -152,10 +153,11 @@ class VideoNodes(object):
'7': 30179,
'9': 135,
'10': 30229,
'11': 30230
'11': 30230,
'12': 39500
},
'homevideoss':
'homevideos':
{
'1': tagname,
'2': 30251,
@ -211,6 +213,10 @@ class VideoNodes(object):
elif kodiversion == 14 and nodetype == "inprogressepisodes":
# Custom query
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:
path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
@ -248,7 +254,7 @@ class VideoNodes(object):
continue
# 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'))):
# Folder type with plugin path
root = self.commonRoot(order=node, label=label, tagname=tagname, roottype=2)