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')
Example #2
0
 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)