Prep On Deck
This commit is contained in:
parent
a4673b0377
commit
037925a030
8 changed files with 192 additions and 71 deletions
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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]})
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue