def watchlater(): """ Listing for plex.tv Watch Later section (if signed in to plex.tv) """ if window('plex_token') == '': log.error('No watch later - not signed in to plex.tv') return xbmcplugin.endOfDirectory(HANDLE, False) if window('plex_restricteduser') == 'true': log.error('No watch later - restricted user') return xbmcplugin.endOfDirectory(HANDLE, False) xml = downloadutils.DownloadUtils().downloadUrl( 'https://plex.tv/pms/playlists/queue/all', authenticate=False, headerOptions={'X-Plex-Token': window('plex_token')}) if xml in (None, 401): log.error('Could not download watch later list from plex.tv') return xbmcplugin.endOfDirectory(HANDLE, False) log.info('Displaying watch later plex.tv items') xbmcplugin.setContent(HANDLE, 'movies') url = "plugin://plugin.video.plexkodiconnect/" params = { 'mode': "Plex_Node", } for item in xml: api = API(item) listitem = api.CreateListItemFromPlexItem() api.AddStreamInfo(listitem) api.set_listitem_artwork(listitem) params['id'] = item.attrib.get('key') params['viewOffset'] = item.attrib.get('viewOffset', '0') params['plex_type'] = item.attrib.get('type') xbmcplugin.addDirectoryItem(handle=HANDLE, url="%s?%s" % (url, urlencode(params)), listitem=listitem) xbmcplugin.endOfDirectory( handle=HANDLE, cacheToDisc=settings('enableTextureCache') == 'true')
def process_play(self, plex_id, kodi_id=None): """ Processes Kodi playback init for ONE item """ log.info("Process_play called with plex_id %s, kodi_id %s" % (plex_id, kodi_id)) if window('plex_authenticated') != "true": log.error('Not yet authenticated for PMS, abort starting playback') # Todo: Warn user with dialog return xml = GetPlexMetadata(plex_id) try: xml[0].attrib except (TypeError, AttributeError): log.error('Could not get a PMS xml for plex id %s' % plex_id) return api = API(xml[0]) if api.getType() == v.PLEX_TYPE_PHOTO: # Photo result = Playback_Successful() listitem = PKC_ListItem() listitem = api.CreateListItemFromPlexItem(listitem) api.AddStreamInfo(listitem) api.set_listitem_artwork(listitem) result.listitem = listitem else: # Video and Music playqueue = self.playqueue.get_playqueue_from_type( v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()]) with lock: result = PlaybackUtils(xml, playqueue).play( plex_id, kodi_id, xml.attrib.get('librarySectionUUID')) log.info('Done process_play, playqueues: %s' % self.playqueue.playqueues) return result
def getOnDeck(viewid, mediatype, tagname, limit): """ Retrieves Plex On Deck items, currently only for TV shows Input: viewid: Plex id of the library section, e.g. '1' mediatype: Kodi mediatype, e.g. 'tvshows', 'movies', 'homevideos', 'photos' tagname: Name of the Plex library, e.g. "My Movies" limit: Max. number of items to retrieve, e.g. 50 """ xbmcplugin.setContent(HANDLE, 'episodes') appendShowTitle = settings('OnDeckTvAppendShow') == 'true' appendSxxExx = settings('OnDeckTvAppendSeason') == 'true' directpaths = settings('useDirectPaths') == 'true' if settings('OnDeckTVextended') == 'false': # Chances are that this view is used on Kodi startup # Wait till we've connected to a PMS. At most 30s counter = 0 while window('plex_authenticated') != 'true': counter += 1 if counter >= 300: log.error('Aborting On Deck view, we were not authenticated ' 'for the PMS') return xbmcplugin.endOfDirectory(HANDLE, False) sleep(100) xml = downloadutils.DownloadUtils().downloadUrl( '{server}/library/sections/%s/onDeck' % viewid) if xml in (None, 401): log.error('Could not download PMS xml for view %s' % viewid) return xbmcplugin.endOfDirectory(HANDLE) for item in xml: api = API(item) listitem = api.CreateListItemFromPlexItem( appendShowTitle=appendShowTitle, appendSxxExx=appendSxxExx) api.AddStreamInfo(listitem) api.set_listitem_artwork(listitem) if directpaths: url = api.getFilePath() else: params = { 'mode': "play", 'id': api.getRatingKey(), 'dbid': listitem.getProperty('dbid') } url = "plugin://plugin.video.plexkodiconnect/tvshows/?%s" \ % urlencode(params) xbmcplugin.addDirectoryItem(handle=HANDLE, url=url, listitem=listitem) return xbmcplugin.endOfDirectory( handle=HANDLE, cacheToDisc=settings('enableTextureCache') == 'true') # if the addon is called with nextup parameter, # we return the nextepisodes list of the given tagname # First we get a list of all the TV shows - filtered by tag params = { 'sort': { 'order': "descending", 'method': "lastplayed" }, 'filter': { 'and': [{ 'operator': "true", 'field': "inprogress", 'value': "" }, { 'operator': "is", 'field': "tag", 'value': "%s" % tagname }] } } result = JSONRPC('VideoLibrary.GetTVShows').execute(params) # If we found any, find the oldest unwatched show for each one. try: items = result['result'][mediatype] except (KeyError, TypeError): # Now items retrieved - empty directory xbmcplugin.endOfDirectory(handle=HANDLE) return params = { 'sort': { 'method': "episode" }, 'limits': { "end": 1 }, 'properties': [ "title", "playcount", "season", "episode", "showtitle", "plot", "file", "rating", "resume", "tvshowid", "art", "streamdetails", "firstaired", "runtime", "cast", "writer", "dateadded", "lastplayed" ], } if settings('ignoreSpecialsNextEpisodes') == "true": params['filter'] = { 'and': [{ 'operator': "lessthan", 'field': "playcount", 'value': "1" }, { 'operator': "greaterthan", 'field': "season", 'value': "0" }] } else: params['filter'] = { 'or': [{ 'operator': "lessthan", 'field': "playcount", 'value': "1" }, { 'operator': "true", 'field': "inprogress", 'value': "" }] } # Are there any episodes still in progress/not yet finished watching?!? # Then we should show this episode, NOT the "next up" inprog_params = { 'sort': { 'method': "episode" }, 'filter': { 'operator': "true", 'field': "inprogress", 'value': "" }, 'properties': params['properties'] } count = 0 for item in items: inprog_params['tvshowid'] = item['tvshowid'] result = JSONRPC('VideoLibrary.GetEpisodes').execute(inprog_params) try: episodes = result['result']['episodes'] except (KeyError, TypeError): # No, there are no episodes not yet finished. Get "next up" params['tvshowid'] = item['tvshowid'] result = JSONRPC('VideoLibrary.GetEpisodes').execute(params) try: episodes = result['result']['episodes'] except (KeyError, TypeError): # Also no episodes currently coming up continue for episode in episodes: # There will always be only 1 episode ('limit=1') li = createListItem(episode, appendShowTitle=appendShowTitle, appendSxxExx=appendSxxExx) xbmcplugin.addDirectoryItem(handle=HANDLE, url=episode['file'], listitem=li, isFolder=False) count += 1 if count >= limit: break xbmcplugin.endOfDirectory(handle=HANDLE)