New Playlists menu item for video libraries

This commit is contained in:
croneter 2018-07-17 13:48:09 +02:00
parent cc01f3009c
commit 6e6d6cc110
4 changed files with 94 additions and 25 deletions

View file

@ -136,6 +136,9 @@ class Main():
plexId = itemid or None plexId = itemid or None
entrypoint.get_video_files(plexId, params) entrypoint.get_video_files(plexId, params)
elif mode == 'playlists':
entrypoint.playlists(params.get('type'))
else: else:
entrypoint.show_main_menu(content_type=params.get('content_type')) entrypoint.show_main_menu(content_type=params.get('content_type'))

View file

@ -524,6 +524,24 @@ def extra_fanart(plex_id, plex_path):
xbmcplugin.endOfDirectory(int(argv[1])) xbmcplugin.endOfDirectory(int(argv[1]))
def _wait_for_auth():
"""
Call to be sure that PKC is authenticated, e.g. for widgets on Kodi
startup. Will wait for at most 30s, then fail if not authenticated.
Will set xbmcplugin.endOfDirectory(int(argv[1]), False) if failed
"""
counter = 0
while utils.window('plex_authenticated') != 'true':
counter += 1
if counter == 300:
LOG.error('Aborting view, we were not authenticated for PMS')
xbmcplugin.endOfDirectory(int(argv[1]), False)
return False
sleep(100)
return True
def on_deck_episodes(viewid, tagname, limit): def on_deck_episodes(viewid, tagname, limit):
""" """
Retrieves Plex On Deck items, currently only for TV shows Retrieves Plex On Deck items, currently only for TV shows
@ -539,15 +557,8 @@ def on_deck_episodes(viewid, tagname, limit):
if utils.settings('OnDeckTVextended') == 'false': if utils.settings('OnDeckTVextended') == 'false':
# Chances are that this view is used on Kodi startup # Chances are that this view is used on Kodi startup
# Wait till we've connected to a PMS. At most 30s # Wait till we've connected to a PMS. At most 30s
counter = 0 if not _wait_for_auth():
while utils.window('plex_authenticated') != 'true':
counter += 1
if counter == 300:
LOG.error('Aborting On Deck view, we were not authenticated '
'for the PMS')
xbmcplugin.endOfDirectory(int(argv[1]), False)
return return
sleep(100)
xml = DU().downloadUrl('{server}/library/sections/%s/onDeck' % viewid) xml = DU().downloadUrl('{server}/library/sections/%s/onDeck' % viewid)
if xml in (None, 401): if xml in (None, 401):
LOG.error('Could not download PMS xml for view %s', viewid) LOG.error('Could not download PMS xml for view %s', viewid)
@ -659,6 +670,41 @@ def on_deck_episodes(viewid, tagname, limit):
xbmcplugin.endOfDirectory(handle=int(argv[1])) xbmcplugin.endOfDirectory(handle=int(argv[1]))
def playlists(kodi_playlist_type):
"""
Lists all Plex playlists of the media type kodi_playlist_type
"""
LOG.debug('Listing Plex %s playlists', kodi_playlist_type)
if not _wait_for_auth():
return
xbmcplugin.setContent(int(argv[1]), 'files')
from .playlists.pms import all_playlists
xml = all_playlists()
if xml is None:
return
for item in xml:
api = API(item)
if not v.KODI_PLAYLIST_TYPE_FROM_PLEX[api.playlist_type()] \
== kodi_playlist_type:
continue
listitem = ListItem(api.title())
listitem.setArt({'thumb': api._one_artwork('composite')})
url = "plugin://%s/" % v.ADDON_ID
key = api.path_and_plex_id()
params = {
'mode': "browseplex",
'key': key,
}
LOG.debug('adding item: %s', params)
xbmcplugin.addDirectoryItem(handle=int(argv[1]),
url="%s?%s" % (url, urlencode(params)),
isFolder=True,
listitem=listitem)
xbmcplugin.endOfDirectory(
handle=int(argv[1]),
cacheToDisc=utils.settings('enableTextureCache') == 'true')
def watchlater(): def watchlater():
""" """
Listing for plex.tv Watch Later section (if signed in to plex.tv) Listing for plex.tv Watch Later section (if signed in to plex.tv)

View file

@ -820,8 +820,9 @@ class API(object):
artwork = self.item.get(art_kind) artwork = self.item.get(art_kind)
if artwork and not artwork.startswith('http'): if artwork and not artwork.startswith('http'):
if '/composite/' in artwork: if '/composite/' in artwork:
# e.g. Plex collections where artwork already contains width try:
# and height. Need to upscale for better resolution # e.g. Plex collections where artwork already contains
# width and height. Need to upscale for better resolution
artwork, args = artwork.split('?') artwork, args = artwork.split('?')
args = dict(parse_qsl(args)) args = dict(parse_qsl(args))
width = int(args.get('width', 400)) width = int(args.get('width', 400))
@ -830,6 +831,10 @@ class API(object):
scaling = 3840.0 / float(max(width, height)) scaling = 3840.0 / float(max(width, height))
width = int(scaling * width) width = int(scaling * width)
height = int(scaling * height) height = int(scaling * height)
except ValueError:
# e.g. playlists
width = 3840
height = 3840
artwork = '%s?width=%s&height=%s' % (artwork, width, height) artwork = '%s?width=%s&height=%s' % (artwork, width, height)
artwork = ('%s/photo/:/transcode?width=3840&height=3840&' artwork = ('%s/photo/:/transcode?width=3840&height=3840&'
'minSize=1&upscale=0&url=%s' 'minSize=1&upscale=0&url=%s'

View file

@ -135,7 +135,8 @@ class VideoNodes(object):
'10': "random", '10': "random",
'11': "recommended", '11': "recommended",
'12': "ondeck", '12': "ondeck",
'13': 'browsefiles' '13': 'browsefiles',
'14': 'playlists'
} }
mediatypes = { mediatypes = {
# label according to nodetype per mediatype # label according to nodetype per mediatype
@ -150,7 +151,8 @@ class VideoNodes(object):
'10': 30227, '10': 30227,
'11': 30230, '11': 30230,
'12': 39500, '12': 39500,
'13': 39702 '13': 39702,
'14': 136
}, },
'tvshows': 'tvshows':
@ -165,7 +167,8 @@ class VideoNodes(object):
'10': 30227, '10': 30227,
# '11': 30230, # '11': 30230,
'12': 39500, '12': 39500,
'13': 39702 '13': 39702,
'14': 136
}, },
'homevideos': 'homevideos':
@ -173,7 +176,8 @@ class VideoNodes(object):
'1': tagname, '1': tagname,
'2': 30251, '2': 30251,
'11': 30253, '11': 30253,
'13': 39702 '13': 39702,
'14': 136
}, },
'photos': 'photos':
@ -209,7 +213,8 @@ class VideoNodes(object):
'10': '8', # "random", '10': '8', # "random",
'11': '5', # "recommended", '11': '5', # "recommended",
'12': '1', # "ondeck" '12': '1', # "ondeck"
'13': '9' # browse by folder '13': '9', # browse by folder
'14': '10' # Playlists
} }
nodes = mediatypes[mediatype] nodes = mediatypes[mediatype]
@ -257,6 +262,12 @@ class VideoNodes(object):
nodetype = 'inprogress' nodetype = 'inprogress'
elif nodetype == 'browsefiles': elif nodetype == 'browsefiles':
path = 'plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s/folder' % viewid path = 'plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s/folder' % viewid
elif nodetype == 'playlists':
path = 'plugin://plugin.video.plexkodiconnect?mode=playlists'
if mediatype in ('movies', 'tvshows', 'homevideos'):
path += '&type=%s' % v.KODI_PLAYLIST_TYPE_VIDEO
else:
path += '&type=%s' % v.KODI_PLAYLIST_TYPE_AUDIO
else: else:
path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype) path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
@ -298,7 +309,11 @@ class VideoNodes(object):
continue continue
# Create the root # Create the root
if (nodetype in ("nextepisodes", "ondeck", 'recentepisodes', 'browsefiles') or mediatype == "homevideos"): if (nodetype in ("nextepisodes",
"ondeck",
'recentepisodes',
'browsefiles',
'playlists') or mediatype == "homevideos"):
# Folder type with plugin path # Folder type with plugin path
root = self.commonRoot(order=sortorder[node], root = self.commonRoot(order=sortorder[node],
label=label, label=label,