New Playlists menu item for video libraries
This commit is contained in:
parent
cc01f3009c
commit
6e6d6cc110
4 changed files with 94 additions and 25 deletions
|
@ -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'))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue