Exemplo n.º 1
0
    def externalSubs(self, playurl):

        externalsubs = []
        mapping = {}

        itemid = self.API.getRatingKey()
        mediastreams = self.API.getMediaStreams()

        kodiindex = 0
        for stream in mediastreams:

            index = stream['Index']
            # Since Emby returns all possible tracks together, have to pull only external subtitles.
            # IsTextSubtitleStream if true, is available to download from emby.
            if (stream['Type'] == "Subtitle" and 
                    stream['IsExternal'] and stream['IsTextSubtitleStream']):

                # Direct stream
                url = ("%s/Videos/%s/%s/Subtitles/%s/Stream.srt"
                        % (self.server, itemid, itemid, index))
                
                # map external subtitles for mapping
                mapping[kodiindex] = index
                externalsubs.append(url)
                kodiindex += 1
        
        mapping = json.dumps(mapping)
        utils.window('emby_%s.indexMapping' % playurl, value=mapping)

        return externalsubs
Exemplo n.º 2
0
    def _report_progress(self):
        # Update and report playback progress
        kodi_player = self.kodi_player
        try:
            play_time = kodi_player.getTime()
            filename = kodi_player.currentFile

            # Update positionticks
            if filename in kodi_player.played_info:
                kodi_player.played_info[filename]['currentPosition'] = play_time

            difference = datetime.today() - self.last_progress
            difference_seconds = difference.seconds

            # Report progress to Emby server
            if difference_seconds > 3:
                kodi_player.reportPlayback()
                self.last_progress = datetime.today()

            elif window('emby_command') == "true":
                # Received a remote control command that
                # requires updating immediately
                window('emby_command', clear=True)
                kodi_player.reportPlayback()
                self.last_progress = datetime.today()

        except Exception as error:
            log.exception(error)
Exemplo n.º 3
0
 def onSettingsChanged(self):
     """
     Monitor the PKC settings for changes made by the user
     """
     # settings: window-variable
     items = {
         'logLevel': 'plex_logLevel',
         'enableContext': 'plex_context',
         'plex_restricteduser': '******',
         'dbSyncIndicator': 'dbSyncIndicator',
         'remapSMB': 'remapSMB',
         'replaceSMB': 'replaceSMB',
         'force_transcode_pix': 'plex_force_transcode_pix',
         'fetch_pms_item_number': 'fetch_pms_item_number'
     }
     # Path replacement
     for typus in REMAP_TYPE_FROM_PLEXTYPE.values():
         for arg in ('Org', 'New'):
             key = 'remapSMB%s%s' % (typus, arg)
             items[key] = key
     # Reset the window variables from the settings variables
     for settings_value, window_value in items.iteritems():
         if window(window_value) != settings(settings_value):
             log.debug('PKC settings changed: %s is now %s' %
                       (settings_value, settings(settings_value)))
             window(window_value, value=settings(settings_value))
             if settings_value == 'fetch_pms_item_number':
                 log.info('Requesting playlist/nodes refresh')
                 window('plex_runLibScan', value="views")
Exemplo n.º 4
0
 def onPlayBackStopped( self ):
     # Will be called when user stops xbmc playing a file
     self.logMsg("ONPLAYBACK_STOPPED", 2)
     utils.window('emby_customPlaylist', clear=True)
     utils.window('emby_playbackProps', clear=True)
     self.logMsg("Clear playlist properties.", 1)
     self.stopAll()
Exemplo n.º 5
0
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')
    for item in xml:
        __build_item(item)

    xbmcplugin.endOfDirectory(
        handle=HANDLE, cacheToDisc=settings('enableTextureCache') == 'true')
Exemplo n.º 6
0
 def play_all(self):
     """
     Play all items contained in the xml passed in. Called by Plex Companion
     """
     log.info("Playbackutils play_all called")
     window('plex_playbackProps', value="true")
     self.currentPosition = 0
     for item in self.xml:
         api = API(item)
         successful = True
         if api.getType() == v.PLEX_TYPE_CLIP:
             self.add_trailer(item)
         else:
             with Get_Plex_DB() as plex_db:
                 db_item = plex_db.getItem_byId(api.getRatingKey())
             if db_item is not None:
                 successful = add_item_to_kodi_playlist(
                     self.playqueue,
                     self.currentPosition,
                     kodi_id=db_item[0],
                     kodi_type=db_item[4])
                 if successful is True:
                     self.currentPosition += 1
                     if len(item[0]) > 1:
                         self.add_part(item,
                                       api,
                                       db_item[0],
                                       db_item[4])
             else:
                 # Item not in Kodi DB
                 self.add_trailer(item)
         if successful is True:
             self.playqueue.items[self.currentPosition - 1].ID = item.get(
                 '%sItemID' % self.playqueue.kind)
Exemplo n.º 7
0
    def externalSubs(self, playurl):
        externalsubs = []
        mapping = {}

        itemid = self.API.getRatingKey()
        mediastreams = self.API.getMediaStreams()

        kodiindex = 0
        for stream in mediastreams:

            index = stream['Index']
            # Since Emby returns all possible tracks together, have to pull
            # only external subtitles. IsTextSubtitleStream if true, is
            # available to download from emby.
            if (stream['Type'] == "Subtitle" and stream['IsExternal']
                    and stream['IsTextSubtitleStream']):
                # Direct stream
                url = ("%s/Videos/%s/%s/Subtitles/%s/Stream.srt" %
                       (self.server, itemid, itemid, index))
                # map external subtitles for mapping
                mapping[kodiindex] = index
                externalsubs.append(url)
                kodiindex += 1
        mapping = json.dumps(mapping)
        window('emby_%s.indexMapping' % playurl, value=mapping)
        return externalsubs
Exemplo n.º 8
0
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')
    for item in xml:
        __build_item(item)

    xbmcplugin.endOfDirectory(
        handle=HANDLE,
        cacheToDisc=settings('enableTextureCache') == 'true')
Exemplo n.º 9
0
 def onScanFinished(self, library):
     """
     Will be called when Kodi finished scanning the library
     """
     LOG.debug("Kodi library scan %s finished.", library)
     if library == "video":
         window('plex_kodiScan', clear=True)
Exemplo n.º 10
0
 def setUserPref(self):
     self.logMsg('Setting user preferences', 0)
     # Only try to get user avatar if there is a token
     if self.currToken:
         url = PlexAPI.PlexAPI().GetUserArtworkURL(self.currUser)
         if url:
             utils.window('EmbyUserImage', value=url)
Exemplo n.º 11
0
    def getXArgsDeviceInfo(self, options=None):
        """
        Returns a dictionary that can be used as headers for GET and POST
        requests. An authentication option is NOT yet added.

        Inputs:
            options:        dictionary of options that will override the
                            standard header options otherwise set.
        Output:
            header dictionary
        """
        # Get addon infos
        xargs = {
            'Accept': '*/*',
            'Connection': 'keep-alive',
            "Content-Type": "application/x-www-form-urlencoded",
            # "Access-Control-Allow-Origin": "*",
            # 'X-Plex-Language': 'en',
            'X-Plex-Device': self.getAddonName(),
            'X-Plex-Client-Platform': self.getPlatform(),
            'X-Plex-Device-Name': self.getDeviceName(),
            'X-Plex-Platform': self.getPlatform(),
            # 'X-Plex-Platform-Version': 'unknown',
            # 'X-Plex-Model': 'unknown',
            'X-Plex-Product': self.getAddonName(),
            'X-Plex-Version': self.getVersion(),
            'X-Plex-Client-Identifier': self.getDeviceId(),
            'X-Plex-Provides': 'player',
        }

        if window('pms_token'):
            xargs['X-Plex-Token'] = window('pms_token')
        if options is not None:
            xargs.update(options)
        return xargs
Exemplo n.º 12
0
    def playAll(self, items, startitem, offset):
        """
        items: list of dicts of the form
        {
            'playQueueItemID':      Plex playQueueItemID, e.g. '29175'
            'plexId':       Plex ratingKey, e.g. '125'
            'kodiId':       Kodi's db id of the same item
        }

        startitem:  tuple (typus, id), where typus is either
                    'playQueueItemID' or 'plexId' and id is the corresponding
                    id as a string
        offset:     First item's time offset to play in Kodi time (an int)
        """
        log.info("---*** PLAY ALL ***---")
        log.debug('Startitem: %s, offset: %s, items: %s' %
                  (startitem, offset, items))
        self.items = items
        if self.playlist is None:
            self._initiatePlaylist()
        if self.playlist is None:
            log.error('Could not create playlist, abort')
            return

        window('plex_customplaylist', value="true")
        if offset != 0:
            # Seek to the starting position
            window('plex_customplaylist.seektime', str(offset))
        self._processItems(startitem, startPlayer=True)
        # Log playlist
        self._verifyPlaylist()
        log.debug('Internal playlist: %s' % self.items)
Exemplo n.º 13
0
 def setUserPref(self):
     self.logMsg('Setting user preferences', 0)
     # Only try to get user avatar if there is a token
     if self.currToken:
         url = PlexAPI.PlexAPI().GetUserArtworkURL(self.currUser)
         if url:
             utils.window('PlexUserImage', value=url)
Exemplo n.º 14
0
    def _playstate(cls, data):

        command = data['Command']
        player = xbmc.Player()

        actions = {
            'Stop': player.stop,
            'Unpause': player.pause,
            'Pause': player.pause,
            'NextTrack': player.playnext,
            'PreviousTrack': player.playprevious
        }
        if command == 'Seek':

            if player.isPlaying():
                seek_to = data['SeekPositionTicks']
                seek_time = seek_to / 10000000.0
                player.seekTime(seek_time)
                log.info("Seek to %s", seek_time)

        elif command in actions:
            actions[command]()
            log.info("Command: %s completed", command)

        else:
            log.info("Unknown command: %s", command)
            return

        window('emby_command', value="true")
Exemplo n.º 15
0
    def externalSubs(self, playurl):

        externalsubs = []
        mapping = {}

        item = self.item
        itemid = item['Id']
        try:
            mediastreams = item['MediaSources'][0]['MediaStreams']
        except (TypeError, KeyError, IndexError):
            return

        kodiindex = 0
        for stream in mediastreams:

            index = stream['Index']
            # Since Emby returns all possible tracks together, have to pull only external subtitles.
            # IsTextSubtitleStream if true, is available to download from emby.
            if (stream['Type'] == "Subtitle" and 
                    stream['IsExternal'] and stream['IsTextSubtitleStream']):

                # Direct stream
                url = ("%s/Videos/%s/%s/Subtitles/%s/Stream.srt"
                        % (self.server, itemid, itemid, index))
                
                # map external subtitles for mapping
                mapping[kodiindex] = index
                externalsubs.append(url)
                kodiindex += 1
        
        mapping = json.dumps(mapping)
        utils.window('emby_%s.indexMapping' % playurl, value=mapping)

        return externalsubs
Exemplo n.º 16
0
    def getToken(self):

        username = self.getUsername()
        userId = self.getUserId()
        w_token = window('emby_accessToken%s' % userId)
        s_token = settings('accessToken')

        # Verify the window property
        if w_token:
            if not s_token:
                # Save access token if it's missing from settings
                settings('accessToken', value=w_token)
                log(
                    "Returning accessToken from WINDOW for username: %s accessToken: %s"
                    % (username, w_token), 2)
            return w_token
        # Verify the settings
        elif s_token:
            log(
                "Returning accessToken from SETTINGS for username: %s accessToken: %s"
                % (username, s_token), 2)
            window('emby_accessToken%s' % username, value=s_token)
            return s_token
        else:
            log("No token found.", 1)
            return ""
Exemplo n.º 17
0
 def setUserPref(self):
     log.debug('Setting user preferences')
     # Only try to get user avatar if there is a token
     if self.currToken:
         url = PlexAPI.PlexAPI().GetUserArtworkURL(self.currUser)
         if url:
             window('PlexUserImage', value=url)
Exemplo n.º 18
0
    def playAll(self, items, startitem, offset):
        """
        items: list of dicts of the form
        {
            'playQueueItemID':      Plex playQueueItemID, e.g. '29175'
            'plexId':       Plex ratingKey, e.g. '125'
            'kodiId':       Kodi's db id of the same item
        }

        startitem:  tuple (typus, id), where typus is either
                    'playQueueItemID' or 'plexId' and id is the corresponding
                    id as a string
        offset:     First item's time offset to play in Kodi time (an int)
        """
        log.info("---*** PLAY ALL ***---")
        log.debug('Startitem: %s, offset: %s, items: %s'
                  % (startitem, offset, items))
        self.items = items
        if self.playlist is None:
            self._initiatePlaylist()
        if self.playlist is None:
            log.error('Could not create playlist, abort')
            return

        window('plex_customplaylist', value="true")
        if offset != 0:
            # Seek to the starting position
            window('plex_customplaylist.seektime', str(offset))
        self._processItems(startitem, startPlayer=True)
        # Log playlist
        self._verifyPlaylist()
        log.debug('Internal playlist: %s' % self.items)
Exemplo n.º 19
0
    def _action_menu(self):

        selected = self._selected_option

        if selected == OPTIONS['Transcode']:
            window('plex_forcetranscode', value='true')
            self._PMS_play()

        elif selected == OPTIONS['PMS_Play']:
            self._PMS_play()

        # elif selected == OPTIONS['Refresh']:
        #     self.emby.refreshItem(self.item_id)

        # elif selected == OPTIONS['AddFav']:
        #     self.emby.updateUserRating(self.item_id, favourite=True)

        # elif selected == OPTIONS['RemoveFav']:
        #     self.emby.updateUserRating(self.item_id, favourite=False)

        # elif selected == OPTIONS['RateSong']:
        #     self._rate_song()

        elif selected == OPTIONS['Addon']:
            xbmc.executebuiltin('Addon.OpenSettings(plugin.video.plexkodiconnect)')

        elif selected == OPTIONS['Delete']:
            self._delete_item()
Exemplo n.º 20
0
    def onNotification(self, sender, method, data):

        if method not in ('Playlist.OnAdd', 'Player.OnStop', 'Player.OnClear'):
            log.info("Method: %s Data: %s", method, data)

        try:
            if data:
                data = json.loads(data, 'utf-8')
        except:
            log.info("Error parsing message data: %s", data)
            return

        if method == 'Player.OnPlay':
            self._on_play_(data)

        elif method == 'VideoLibrary.OnUpdate':
            self._video_update(data)

        elif method == 'System.OnSleep':
            # Connection is going to sleep
            log.info("Marking the server as offline. System.OnSleep activated.")
            window('emby_online', value="sleep")

        elif method == 'System.OnWake':
            self._system_wake()

        elif method == 'GUI.OnScreensaverDeactivated':
            self._screensaver_deactivated()
Exemplo n.º 21
0
 def onSettingsChanged(self):
     """
     Monitor the PKC settings for changes made by the user
     """
     # settings: window-variable
     items = {
         'logLevel': 'plex_logLevel',
         'enableContext': 'plex_context',
         'plex_restricteduser': '******',
         'dbSyncIndicator': 'dbSyncIndicator',
         'remapSMB': 'remapSMB',
         'replaceSMB': 'replaceSMB',
         'force_transcode_pix': 'plex_force_transcode_pix',
         'fetch_pms_item_number': 'fetch_pms_item_number'
     }
     # Path replacement
     for typus in REMAP_TYPE_FROM_PLEXTYPE.values():
         for arg in ('Org', 'New'):
             key = 'remapSMB%s%s' % (typus, arg)
             items[key] = key
     # Reset the window variables from the settings variables
     for settings_value, window_value in items.iteritems():
         if window(window_value) != settings(settings_value):
             log.debug('PKC settings changed: %s is now %s'
                       % (settings_value, settings(settings_value)))
             window(window_value, value=settings(settings_value))
             if settings_value == 'fetch_pms_item_number':
                 log.info('Requesting playlist/nodes refresh')
                 window('plex_runLibScan', value="views")
Exemplo n.º 22
0
 def play_all(self):
     """
     Play all items contained in the xml passed in. Called by Plex Companion
     """
     log.info("Playbackutils play_all called")
     window('plex_playbackProps', value="true")
     self.currentPosition = 0
     for item in self.xml:
         api = API(item)
         successful = True
         if api.getType() == v.PLEX_TYPE_CLIP:
             self.add_trailer(item)
         else:
             with Get_Plex_DB() as plex_db:
                 db_item = plex_db.getItem_byId(api.getRatingKey())
             if db_item is not None:
                 successful = add_item_to_kodi_playlist(
                     self.playqueue,
                     self.currentPosition,
                     kodi_id=db_item[0],
                     kodi_type=db_item[4])
                 if successful is True:
                     self.currentPosition += 1
                     if len(item[0]) > 1:
                         self.add_part(item, api, db_item[0], db_item[4])
             else:
                 # Item not in Kodi DB
                 self.add_trailer(item)
         if successful is True:
             self.playqueue.items[self.currentPosition - 1].ID = item.get(
                 '%sItemID' % self.playqueue.kind)
Exemplo n.º 23
0
    def getPlayerProperties(self, playerid):
        info = {}
        try:
            # get info from the player
            props = self.js.jsonrpc("Player.GetProperties", {"playerid": playerid, "properties": ["time", "totaltime", "speed", "shuffled", "repeat"]})
            self.logMsg(self.js.jsonrpc("Player.GetItem", {"playerid": playerid, "properties": ["file", "showlink", "episode", "season"]}), 2)
            info['time'] = timeToMillis(props['time'])
            info['duration'] = timeToMillis(props['totaltime'])
            info['state'] = ("paused", "playing")[int(props['speed'])]
            info['shuffle'] = ("0","1")[props.get('shuffled', False)]
            info['repeat'] = pf.getPlexRepeat(props.get('repeat'))
            # New PMS playQueue attributes
            cf = self.xbmcplayer.getPlayingFile()
            info['playQueueID'] = window('playQueueID')
            info['playQueueVersion'] = window('playQueueVersion')
            info['playQueueItemID'] = window('plex_%s.playQueueItemID' % cf)
            info['guid'] = window('plex_%s.guid' % cf)

        except:
            info['time'] = 0
            info['duration'] = 0
            info['state'] = "stopped"
            info['shuffle'] = False
        # get the volume from the application
        info['volume'] = self.volume
        info['mute'] = self.mute

        return info
Exemplo n.º 24
0
    def _playstate(cls, data):

        command = data['Command']
        player = xbmc.Player()

        actions = {

            'Stop': player.stop,
            'Unpause': player.pause,
            'Pause': player.pause,
            'NextTrack': player.playnext,
            'PreviousTrack': player.playprevious
        }
        if command == 'Seek':

            if player.isPlaying():
                seek_to = data['SeekPositionTicks']
                seek_time = seek_to / 10000000.0
                player.seekTime(seek_time)
                log.info("Seek to %s", seek_time)

        elif command in actions:
            actions[command]()
            log.info("Command: %s completed", command)

        else:
            log.info("Unknown command: %s", command)
            return

        window('emby_command', value="true")
Exemplo n.º 25
0
 def __init__(self, header, errors):
     '''
     Sets title of the dialog and fills the tree with information stored
     in given list of ErrorBox instances.
     '''
     QtCore.QObject.__init__(self)
     elements = loadUi(self._DIALOG_UI, parent=window())
     self._dialog = elements["dialog"]
     self._dialog.setWindowTitle(header)
     tree = elements["treeWidgetErrors"]
     items = []
     for error in errors:
         item = QtGui.QTreeWidgetItem(tree)
         infos = []
         fields = vars(error)
         for name in sorted(fields):
             if name != "traceback":
                 infos.append(fields[name])
         item.setText(0, ", ".join(infos))
         QtGui.QTreeWidgetItem(item, [error.traceback])
         item.setExpanded(True)
         items.append(item)
     tree.resizeColumnToContents(0)
     size = QtCore.QSize(min(window().size().width(),
                             tree.columnWidth(0) + 40),
                         min(window().size().height(),
                             self._dialog.size().height()))
     self._dialog.resize(size)
     for item in items:
         item.setExpanded(False)
Exemplo n.º 26
0
    def run(self):

        # websocket.enableTrace(True)
        user_id = window('emby_currUser')
        server = window('emby_server%s' % user_id)
        token = window('emby_accessToken%s' % user_id)
        # Get the appropriate prefix for the websocket
        if "https" in server:
            server = server.replace('https', "wss")
        else:
            server = server.replace('http', "ws")

        websocket_url = "%s?api_key=%s&deviceId=%s" % (server, token, self.device_id)
        log.info("websocket url: %s", websocket_url)

        self._client = websocket.WebSocketApp(websocket_url,
                                              on_message=self.on_message,
                                              on_error=self.on_error,
                                              on_close=self.on_close)
        self._client.on_open = self.on_open
        log.warn("----===## Starting WebSocketClient ##===----")

        while not self.monitor.abortRequested():

            if window('emby_online') == "true":
                self._client.run_forever(ping_interval=10)

            if self._stop_websocket:
                break

            if self.monitor.waitForAbort(5):
                # Abort was requested, exit
                break

        log.warn("##===---- WebSocketClient Stopped ----===##")
Exemplo n.º 27
0
    def getDeviceId(self):

        clientId = utils.window('emby_deviceId')
        if clientId:
            return clientId

        addon_path = self.addon.getAddonInfo('path').decode('utf-8')
        GUID_file = xbmc.translatePath("%s\machine_guid" % addon_path).decode('utf-8')

        try:
            GUID = open(GUID_file)
        
        except IOError: # machine_guid does not exists.
            clientId = str("%012X" % uuid4())
            GUID = open(GUID_file, 'w')
            GUID.write(clientId)

        else: # machine_guid already exists. Get guid.
            clientId = GUID.read()
        
        finally:
            GUID.close()

        self.logMsg("DeviceId loaded: %s" % clientId, 1)
        utils.window('emby_deviceId', value=clientId)
        
        return clientId
Exemplo n.º 28
0
 def onScanStarted(self, library):
     """
     Will be called when Kodi starts scanning the library
     """
     LOG.debug("Kodi library scan %s running.", library)
     if library == "video":
         window('plex_kodiScan', value="true")
Exemplo n.º 29
0
    def getDeviceId(self):

        clientId = utils.window('emby_deviceId')
        if clientId:
            return clientId

        addon_path = self.addon.getAddonInfo('path').decode('utf-8')
        if os.path.supports_unicode_filenames:
            GUID_file = xbmc.translatePath(os.path.join(addon_path, "machine_guid")).decode('utf-8')
        else:
            GUID_file = xbmc.translatePath(os.path.join(addon_path.encode("utf-8"), "machine_guid")).decode('utf-8')

        GUID = xbmcvfs.File(GUID_file)
        clientId = GUID.read()
        if not clientId:
            self.logMsg("Generating a new deviceid...", 1)
            clientId = str("%012X" % uuid4())
            GUID = xbmcvfs.File(GUID_file, 'w')
            GUID.write(clientId)

        GUID.close()

        self.logMsg("DeviceId loaded: %s" % clientId, 1)
        utils.window('emby_deviceId', value=clientId)
        
        return clientId
Exemplo n.º 30
0
def getXArgsDeviceInfo(options=None):
    """
    Returns a dictionary that can be used as headers for GET and POST
    requests. An authentication option is NOT yet added.

    Inputs:
        options:        dictionary of options that will override the
                        standard header options otherwise set.
    Output:
        header dictionary
    """
    xargs = {
        'Accept': '*/*',
        'Connection': 'keep-alive',
        "Content-Type": "application/x-www-form-urlencoded",
        # "Access-Control-Allow-Origin": "*",
        # 'X-Plex-Language': 'en',
        'X-Plex-Device': v.ADDON_NAME,
        'X-Plex-Client-Platform': v.PLATFORM,
        'X-Plex-Device-Name': v.DEVICENAME,
        'X-Plex-Platform': v.PLATFORM,
        # 'X-Plex-Platform-Version': 'unknown',
        # 'X-Plex-Model': 'unknown',
        'X-Plex-Product': v.ADDON_NAME,
        'X-Plex-Version': v.ADDON_VERSION,
        'X-Plex-Client-Identifier': getDeviceId(),
        'X-Plex-Provides': 'client,controller,player,pubsub-player',
    }
    if window('pms_token'):
        xargs['X-Plex-Token'] = window('pms_token')
    if options is not None:
        xargs.update(options)
    return xargs
Exemplo n.º 31
0
    def _report_progress(self):
        # Update and report playback progress
        kodi_player = self.kodi_player
        try:
            play_time = kodi_player.getTime()
            filename = kodi_player.currentFile

            # Update positionticks
            if filename in kodi_player.played_info:
                kodi_player.played_info[filename][
                    'currentPosition'] = play_time

            difference = datetime.today() - self.last_progress
            difference_seconds = difference.seconds

            # Report progress to Emby server
            if difference_seconds > 3:
                kodi_player.reportPlayback()
                self.last_progress = datetime.today()

            elif window('emby_command') == "true":
                # Received a remote control command that
                # requires updating immediately
                window('emby_command', clear=True)
                kodi_player.reportPlayback()
                self.last_progress = datetime.today()

        except Exception as error:
            log.exception(error)
Exemplo n.º 32
0
    def getPlayUrlNew(self):
        '''
            New style to retrieve the best playback method based on sending the profile to the server
            Based on capabilities the correct path is returned, including livestreams that need to be opened by the server
            TODO: Close livestream if needed (RequiresClosing in livestream source)
        '''
        playurl = None
        pbinfo = self.getPlaybackInfo()
        if pbinfo:
            xbmc.log("getPlayUrl pbinfo: %s" %(pbinfo))
            
            if pbinfo["Protocol"] == "SupportsDirectPlay":
                playmethod = "DirectPlay"
            elif pbinfo["Protocol"] == "SupportsDirectStream":
                playmethod = "DirectStream"
            elif pbinfo.get('LiveStreamId'):
                playmethod = "LiveStream"
            else:
                playmethod = "Transcode"

            playurl = pbinfo["Path"]
            xbmc.log("getPlayUrl playmethod: %s - playurl: %s" %(playmethod, playurl))
            window('emby_%s.playmethod' % playurl, value=playmethod)
            if pbinfo["RequiresClosing"] and pbinfo.get('LiveStreamId'):
                window('emby_%s.livestreamid' % playurl, value=pbinfo["LiveStreamId"])

        return playurl
Exemplo n.º 33
0
 def _video_update(self, data):
     # Manually marking as watched/unwatched
     try:
         item = data['item']
         kodi_id = item['id']
         item_type = item['type']
     except (KeyError, TypeError):
         log.info("Item is invalid for playstate update")
     else:
         # Send notification to the server.
         item_id = self._get_item_id(kodi_id, item_type)
         if item_id:
             # Stop from manually marking as watched unwatched, with actual playback.
             if window('emby_skipWatched%s' % item_id) == "true":
                 # property is set in player.py
                 window('emby_skipWatched%s' % item_id, clear=True)
             else:
                 # notify the server
                 url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % item_id
                 if data.get('playcount') != 0:
                     self.download(url, action_type="POST")
                     log.info("Mark as watched for itemid: %s", item_id)
                 else:
                     self.download(url, action_type="DELETE")
                     log.info("Mark as unwatched for itemid: %s", item_id)
Exemplo n.º 34
0
    def __init__(self):

        self.__dict__ = self._shared_state

        client_info = clientinfo.ClientInfo()
        self.emby = embyserver.Read_EmbyServer()

        version = client_info.get_version()
        device_name = client_info.get_device_name()
        device_id = client_info.get_device_id()
        self._connect = connectionmanager.ConnectionManager(appName="Kodi",
                                                            appVersion=version,
                                                            deviceName=device_name,
                                                            deviceId=device_id)
        path = xbmc.translatePath(
                   "special://profile/addon_data/plugin.video.emby/").decode('utf-8')

        if not xbmcvfs.exists(path):
            xbmcvfs.mkdirs(path)

        self._connect.setFilePath(path)

        if window('emby_state.json'):
            self.state = window('emby_state.json')

        elif not self.state:
            self.state = self._connect.connect()
            log.info("Started with: %s", self.state)
            window('emby_state.json', value=self.state)
Exemplo n.º 35
0
    def __run(self):
        """
        Do the work
        """
        log.debug('Starting get metadata thread')
        # cache local variables because it's faster
        queue = self.queue
        out_queue = self.out_queue
        stopped = self.stopped
        while stopped() is False:
            # grabs Plex item from queue
            try:
                item = queue.get(block=False)
            # Empty queue
            except Empty:
                sleep(20)
                continue
            # Download Metadata
            xml = GetPlexMetadata(item['itemId'])
            if xml is None:
                # Did not receive a valid XML - skip that item for now
                log.error("Could not get metadata for %s. Skipping that item "
                          "for now" % item['itemId'])
                # Increase BOTH counters - since metadata won't be processed
                with sync_info.LOCK:
                    sync_info.GET_METADATA_COUNT += 1
                    sync_info.PROCESS_METADATA_COUNT += 1
                queue.task_done()
                continue
            elif xml == 401:
                log.error('HTTP 401 returned by PMS. Too much strain? '
                          'Cancelling sync for now')
                window('plex_scancrashed', value='401')
                # Kill remaining items in queue (for main thread to cont.)
                queue.task_done()
                break

            item['XML'] = xml
            if item.get('get_children') is True:
                children_xml = GetAllPlexChildren(item['itemId'])
                try:
                    children_xml[0].attrib
                except (TypeError, IndexError, AttributeError):
                    log.error('Could not get children for Plex id %s'
                              % item['itemId'])
                    item['children'] = []
                else:
                    item['children'] = children_xml

            # place item into out queue
            out_queue.put(item)
            # Keep track of where we are at
            with sync_info.LOCK:
                sync_info.GET_METADATA_COUNT += 1
            # signals to queue job is done
            queue.task_done()
        # Empty queue in case PKC was shut down (main thread hangs otherwise)
        self.terminate_now()
        log.debug('Get metadata thread terminated')
Exemplo n.º 36
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.userid = window('currUserId')
        self.server = window('pms_server')
        self.machineIdentifier = window('plex_machineIdentifier')
Exemplo n.º 37
0
 def getUri(self):
     self.plex_client_Id = window('plex_client_Id')
     uri = (
         'wss://pubsub.plex.tv/sub/websockets/%s/%s?X-Plex-Token=%s' %
         (window('currUserId'), self.plex_client_Id, window('plex_token')))
     sslopt = {}
     log.debug("Uri: %s, sslopt: %s" % (uri, sslopt))
     return uri, sslopt
Exemplo n.º 38
0
def resetAuth():
    # User tried login and failed too many times
    resp = xbmcgui.Dialog().yesno(heading=lang(30132), line1=lang(33050))
    if resp:
        log("Reset login attempts.", 1)
        window('emby_serverStatus', value="Auth")
    else:
        xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')
Exemplo n.º 39
0
 def threadSuspended(self):
     """
     Overwrite to ignore library sync stuff and allow to check for
     plex_restricteduser
     """
     return (self._threadSuspended or
             window('plex_restricteduser') == 'true' or
             not window('plex_token'))
Exemplo n.º 40
0
def resetAuth():
    # User tried login and failed too many times
    resp = dialog('yesno', heading="{plex}", line1=lang(39206))
    if resp == 1:
        log.info("Reset login attempts.")
        window('plex_serverStatus', value="Auth")
    else:
        executebuiltin('Addon.OpenSettings(plugin.video.plexkodiconnect)')
Exemplo n.º 41
0
def GetSubFolders(nodeindex):
    nodetypes = ["",".recent",".recentepisodes",".inprogress",".inprogressepisodes",".unwatched",".nextepisodes",".sets",".genres",".random",".recommended"]
    for node in nodetypes:
        title = utils.window('Emby.nodes.%s%s.title' %(nodeindex,node))
        if title:
            path = utils.window('Emby.nodes.%s%s.content' %(nodeindex,node))
            addDirectoryItem(title, path)
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
    def __init__(self):

        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()
        self.doUtils = downloadutils.DownloadUtils().downloadUrl

        self.userId = utils.window('emby_currUser')
        self.server = utils.window('emby_server%s' % self.userId)
Exemplo n.º 43
0
    def __init__(self, item):

        self.item = item
        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()

        self.userid = utils.window('emby_currUser')
        self.server = utils.window('emby_server%s' % self.userid)
Exemplo n.º 44
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.userid = window('currUserId')
        self.server = window('pms_server')
        self.machineIdentifier = window('plex_machineIdentifier')
Exemplo n.º 45
0
def resetAuth():
    # User tried login and failed too many times
    resp = dialog('yesno', heading="{plex}", line1=lang(39206))
    if resp == 1:
        log.info("Reset login attempts.")
        window('plex_serverStatus', value="Auth")
    else:
        executebuiltin('Addon.OpenSettings(plugin.video.plexkodiconnect)')
Exemplo n.º 46
0
 def threadSuspended(self):
     """
     Overwrite to ignore library sync stuff and allow to check for
     plex_restricteduser
     """
     return (self._threadSuspended
             or window('plex_restricteduser') == 'true'
             or not window('plex_token'))
Exemplo n.º 47
0
 def reset_server(self, server_id):
     # Reserved for userclient only
     for server in self.servers:
         if server['ServerId'] == server_id:
             self.servers.pop(server)
             window('emby_server%s.json' % server_id, clear=True)
             window('emby_server%s.name' % server_id, clear=True)
             log.info("removing %s from available servers", server_id)
Exemplo n.º 48
0
    def _server_restarting(cls):

        if settings('supressRestartMsg') == "true":
            dialog(type_="notification",
                   heading="{emby}",
                   message=lang(33006),
                   icon="{emby}")
        window('emby_online', value="false")
Exemplo n.º 49
0
def GetSubFolders(nodeindex):
    nodetypes = ["",".recent",".recentepisodes",".inprogress",".inprogressepisodes",".unwatched",".nextepisodes",".sets",".genres",".random",".recommended"]
    for node in nodetypes:
        title = window('Plex.nodes.%s%s.title' %(nodeindex,node))
        if title:
            path = window('Plex.nodes.%s%s.content' %(nodeindex,node))
            addDirectoryItem(title, path)
    xbmcplugin.endOfDirectory(HANDLE)
Exemplo n.º 50
0
    def __init__(self, item):

        self.item = item

        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()

        self.userid = utils.window('emby_currUser')
        self.server = utils.window('emby_server%s' % self.userid)
Exemplo n.º 51
0
def doMainListing():

    xbmcplugin.setContent(int(sys.argv[1]), 'files')    
    # Get emby nodes from the window props
    embyprops = window('Emby.nodes.total')
    if embyprops:
        totalnodes = int(embyprops)
        for i in range(totalnodes):
            path = window('Emby.nodes.%s.index' % i)
            if not path:
                path = window('Emby.nodes.%s.content' % i)
            label = window('Emby.nodes.%s.title' % i)
            node = window('Emby.nodes.%s.type' % i)
            
            ''' because we do not use seperate entrypoints for each content type,
                we need to figure out which items to show in each listing.
                for now we just only show picture nodes in the picture library
                video nodes in the video library and all nodes in any other window 
            '''

            if path:
                if xbmc.getCondVisibility("Window.IsActive(Pictures)") and node == "photos":
                    addDirectoryItem(label, path)
                elif xbmc.getCondVisibility("Window.IsActive(Videos)") and node != "photos":
                    addDirectoryItem(label, path)
                elif not xbmc.getCondVisibility("Window.IsActive(Videos) | Window.IsActive(Pictures) | Window.IsActive(Music)"):
                    addDirectoryItem(label, path)

    # experimental live tv nodes
    if not xbmc.getCondVisibility("Window.IsActive(Pictures)"):
        addDirectoryItem(lang(33051),
            "plugin://emby.for.kodi/?mode=browsecontent&type=tvchannels&folderid=root")
        addDirectoryItem(lang(33052),
            "plugin://emby.for.kodi/?mode=browsecontent&type=recordings&folderid=root")

    '''
    TODO: Create plugin listing for servers
    servers = window('emby_servers.json')
    if servers:
        for server in servers:
            log.info(window('emby_server%s.name' % server))
            addDirectoryItem(window('emby_server%s.name' % server), "plugin://emby.for.kodi/?mode=%s" % server)'''

    addDirectoryItem(lang(30517), "plugin://emby.for.kodi/?mode=passwords")
    addDirectoryItem(lang(33053), "plugin://emby.for.kodi/?mode=settings")
    addDirectoryItem(lang(33054), "plugin://emby.for.kodi/?mode=adduser")
    addDirectoryItem(lang(33055), "plugin://emby.for.kodi/?mode=refreshplaylist")
    addDirectoryItem(lang(33056), "plugin://emby.for.kodi/?mode=manualsync")
    addDirectoryItem(lang(33057), "plugin://emby.for.kodi/?mode=repair")
    addDirectoryItem(lang(33058), "plugin://emby.for.kodi/?mode=reset")
    addDirectoryItem(lang(33059), "plugin://emby.for.kodi/?mode=texturecache")
    addDirectoryItem(lang(33060), "plugin://emby.for.kodi/?mode=thememedia")

    if settings('backupPath'):
        addDirectoryItem(lang(33092), "plugin://emby.for.kodi/?mode=backup")
    
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
Exemplo n.º 52
0
    def __init__(self, item):

        self.item = item
        self.clientInfo = clientinfo.ClientInfo()

        self.userid = window('emby_currUser')
        self.server = window('emby_server%s' % self.userid)

        self.doUtils = downloadutils.DownloadUtils().downloadUrl
Exemplo n.º 53
0
    def run(self):
        LOG.info("----===## Starting UserClient ##===----")
        stopped = self.stopped
        suspended = self.suspended
        while not stopped():
            while suspended():
                if stopped():
                    break
                sleep(1000)

            if state.PMS_STATUS == "Stop":
                sleep(500)
                continue

            # Verify the connection status to server
            elif state.PMS_STATUS == "restricted":
                # Parental control is restricting access
                self.HasAccess = False

            elif state.PMS_STATUS == "401":
                # Unauthorized access, revoke token
                state.PMS_STATUS = 'Auth'
                window('plex_serverStatus', value='Auth')
                self.resetClient()
                sleep(3000)

            if self.auth and (self.currUser is None):
                # Try to authenticate user
                if not state.PMS_STATUS or state.PMS_STATUS == "Auth":
                    # Set auth flag because we no longer need
                    # to authenticate the user
                    self.auth = False
                    if self.authenticate():
                        # Successfully authenticated and loaded a user
                        LOG.info("Successfully authenticated!")
                        LOG.info("Current user: %s", self.currUser)
                        LOG.info("Current userId: %s", state.PLEX_USER_ID)
                        self.retry = 0
                        state.SUSPEND_LIBRARY_THREAD = False
                        window('plex_serverStatus', clear=True)
                        state.PMS_STATUS = False

            if not self.auth and (self.currUser is None):
                # Loop if no server found
                server = self.getServer()

                # The status Stop is for when user cancelled password dialog.
                # Or retried too many times
                if server and state.PMS_STATUS != "Stop":
                    # Only if there's information found to login
                    LOG.debug("Server found: %s", server)
                    self.auth = True

            # Minimize CPU load
            sleep(100)

        LOG.info("##===---- UserClient Stopped ----===##")
Exemplo n.º 54
0
    def __init__(self):

        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()

        self.userid = utils.window('emby_currUser')
        self.server = utils.window('emby_server%s' % self.userid)

        self.emby = embyserver.Read_EmbyServer()
Exemplo n.º 55
0
    def __init__(self):

        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()

        self.userid = utils.window('emby_currUser')
        self.server = utils.window('emby_server%s' % self.userid)

        self.emby = embyserver.Read_EmbyServer()
Exemplo n.º 56
0
 def getUri(self):
     self.plex_client_Id = window('plex_client_Id')
     uri = ('wss://pubsub.plex.tv/sub/websockets/%s/%s?X-Plex-Token=%s'
            % (window('currUserId'),
               self.plex_client_Id,
               window('plex_token')))
     sslopt = {}
     log.debug("Uri: %s, sslopt: %s" % (uri, sslopt))
     return uri, sslopt
Exemplo n.º 57
0
def GetSubFolders(nodeindex):
    nodetypes = ["",".recent",".recentepisodes",".inprogress",".inprogressepisodes",".unwatched",".nextepisodes",".sets",".genres",".random",".recommended"]
    for node in nodetypes:
        title = utils.window('Emby.nodes.%s%s.title' %(nodeindex,node))
        if title:
            path = utils.window('Emby.nodes.%s%s.content' %(nodeindex,node))
            type = utils.window('Emby.nodes.%s%s.type' %(nodeindex,node))
            addDirectoryItem(title, path)
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
Exemplo n.º 58
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.clientInfo = clientinfo.ClientInfo()

        self.userid = utils.window('currUserId')
        self.server = utils.window('pms_server')
        self.machineIdentifier = utils.window('plex_machineIdentifier')