コード例 #1
0
    def sendCommand(self, command, proxy=None, **params):
        """Send a command to the client

        Args:
            command (str): See the commands listed below
            proxy (None, optional): Description
            **params (dict): Description

        Returns:
            Element

        Raises:
            Unsupported: Unsupported clients
        """
        command = command.strip('/')
        controller = command.split('/')[0]
        if controller not in self.protocolCapabilities:
            raise Unsupported('Client %s does not support the %s controller.' %
                              (self.title, controller))
        path = '/player/%s%s' % (command, utils.joinArgs(params))
        headers = {'X-Plex-Target-Client-Identifier': self.machineIdentifier}
        self._commandId += 1
        params['commandID'] = self._commandId
        proxy = self._proxyThroughServer if proxy is None else proxy
        if proxy:
            return self.server.query(path, headers=headers)
        path = '/player/%s%s' % (command, utils.joinArgs(params))
        return self.query(path, headers=headers)
コード例 #2
0
    def getStreamURL(self, **params):
        """ Returns a stream url that may be used by external applications such as VLC.

            Parameters:
                **params (dict): optional parameters to manipulate the playback when accessing
                    the stream. A few known parameters include: maxVideoBitrate, videoResolution
                    offset, copyts, protocol, mediaIndex, platform.

            Raises:
                :class:`plexapi.exceptions.Unsupported`: When the item doesn't support fetching a stream URL.
        """
        if self.TYPE not in ('movie', 'episode', 'track'):
            raise Unsupported('Fetching stream URL for %s is unsupported.' % self.TYPE)
        mvb = params.get('maxVideoBitrate')
        vr = params.get('videoResolution', '')
        params = {
            'path': self.key,
            'offset': params.get('offset', 0),
            'copyts': params.get('copyts', 1),
            'protocol': params.get('protocol'),
            'mediaIndex': params.get('mediaIndex', 0),
            'X-Plex-Platform': params.get('platform', 'Chrome'),
            'maxVideoBitrate': max(mvb, 64) if mvb else None,
            'videoResolution': vr if re.match('^\d+x\d+$', vr) else None
        }
        # remove None values
        params = {k: v for k, v in params.items() if v is not None}
        streamtype = 'audio' if self.TYPE in ('track', 'album') else 'video'
        # sort the keys since the randomness f***s with my tests..
        sorted_params = sorted(params.items(), key=lambda val: val[0])
        return self._server.url('/%s/:/transcode/universal/start.m3u8?%s' %
            (streamtype, urlencode(sorted_params)), includeToken=True)
コード例 #3
0
    def getStreamURL(self, **params):
        """Make a stream url that can be used by vlc.

        Args:
            **params (dict): Description

        Returns:
            string: ''

        Raises:
            Unsupported: Raises a error is the type is wrong.
        """
        if self.TYPE not in ('movie', 'episode', 'track'):
            raise Unsupported(
                'Fetching stream URL for %s is unsupported.' % self.TYPE)
        mvb = params.get('maxVideoBitrate')
        vr = params.get('videoResolution', '')
        params = {
            'path': self.key,
            'offset': params.get('offset', 0),
            'copyts': params.get('copyts', 1),
            'protocol': params.get('protocol'),
            'mediaIndex': params.get('mediaIndex', 0),
            'X-Plex-Platform': params.get('platform', 'Chrome'),
            'maxVideoBitrate': max(mvb, 64) if mvb else None,
            'videoResolution': vr if re.match('^\d+x\d+$', vr) else None
        }
        # remove None values
        params = {k: v for k, v in params.items() if v is not None}
        streamtype = 'audio' if self.TYPE in ('track', 'album') else 'video'
        return self.server.url('/%s/:/transcode/universal/start.m3u8?%s' % (streamtype, urlencode(params)))
コード例 #4
0
 def connect(self, timeout=None):
     """ Alias of reload as any subsequent requests to this client will be
         made directly to the device even if the object attributes were initially
         populated from a PlexServer.
     """
     if not self.key:
         raise Unsupported('Cannot reload an object not built from a URL.')
     self._initpath = self.key
     data = self.query(self.key, timeout=timeout)
     if not data:
         raise NotFound("Client not found at %s" % self._baseurl)
     if self._clientIdentifier:
         client = next(
             (x for x in data
              if x.attrib.get("machineIdentifier") == self._clientIdentifier
              ),
             None,
         )
         if client is None:
             raise NotFound("Client with identifier %s not found at %s" %
                            (self._clientIdentifier, self._baseurl))
     else:
         client = data[0]
     self._loadData(client)
     return self
コード例 #5
0
 def getStreamUrl(self,
                  offset=0,
                  maxVideoBitrate=None,
                  videoResolution=None,
                  **kwargs):
     """ Fetch URL to stream video directly.
         offset: Start time (in seconds) video will initiate from (ex: 300).
         maxVideoBitrate: Max bitrate video and audio stream (ex: 64).
         videoResolution: Max resolution of a video stream (ex: 1280x720).
         params: Dict of additional parameters to include in URL.
     """
     if self.TYPE not in [Movie.TYPE, Episode.TYPE]:
         raise Unsupported('Cannot get stream URL for %s.' % self.TYPE)
     params = {}
     params['path'] = self.key
     params['offset'] = offset
     params['copyts'] = kwargs.get('copyts', 1)
     params['mediaIndex'] = kwargs.get('mediaIndex', 0)
     params['X-Plex-Platform'] = kwargs.get('platform', 'Chrome')
     if maxVideoBitrate:
         params['maxVideoBitrate'] = max(maxVideoBitrate, 64)
     if videoResolution and re.match('^\d+x\d+$', videoResolution):
         params['videoResolution'] = videoResolution
     return self.server.url('/video/:/transcode/universal/start?%s' %
                            urllib.urlencode(params))
コード例 #6
0
ファイル: client.py プロジェクト: dgoren/python-plexapi
    def playMedia(self, media, offset=0, **params):
        """ Start playback of the specified media item. See also:
            
            Parameters:
                media (:class:`~plexapi.media.Media`): Media item to be played back (movie, music, photo).
                offset (int): Number of milliseconds at which to start playing with zero representing
                    the beginning (default 0).
                **params (dict): Optional additional parameters to include in the playback request. See
                    also: https://github.com/plexinc/plex-media-player/wiki/Remote-control-API#modified-commands

            Raises:
                :class:`~plexapi.exceptions.Unsupported`: When no PlexServer specified in this object.
        """
        if not self.server:
            raise Unsupported('A server must be specified before using this command.')
        server_url = media.server.baseurl.split(':')
        playqueue = self.server.createPlayQueue(media)
        self.sendCommand('playback/playMedia', **dict({
            'machineIdentifier': self.server.machineIdentifier,
            'address': server_url[1].strip('/'),
            'port': server_url[-1],
            'offset': offset,
            'key': media.key,
            'containerKey': '/playQueues/%s?window=100&own=1' % playqueue.playQueueID,
        }, **params))
コード例 #7
0
    def playMedia(self, media, offset=0, **params):
        """ Start playback of the specified media item. See also:

            Parameters:
                media (:class:`~plexapi.media.Media`): Media item to be played back
                    (movie, music, photo, playlist, playqueue).
                offset (int): Number of milliseconds at which to start playing with zero
                    representing the beginning (default 0).
                **params (dict): Optional additional parameters to include in the playback request. See
                    also: https://github.com/plexinc/plex-media-player/wiki/Remote-control-API#modified-commands

            Raises:
                :class:`~plexapi.exceptions.Unsupported`: When no PlexServer specified in this object.
        """
        if not self._server:
            raise Unsupported('A server must be specified before using this command.')
        server_url = media._server._baseurl.split(':')
        try:
            self.sendCommand('timeline/subscribe', port=server_url[1].strip('/'), protocol='http')
        except:
            # some clients dont need or like this and raises http 400.
            # We want to include the exception in the log, but it might still work
            # so we swallow it.
            log.exception('%s failed to subscribe ' % self.title)
        playqueue = media if isinstance(media, PlayQueue) else self._server.createPlayQueue(media)
        self.sendCommand('playback/playMedia', **dict({
            'machineIdentifier': self._server.machineIdentifier,
            'address': server_url[1].strip('/'),
            'port': server_url[-1],
            'offset': offset,
            'key': media.key,
            'token': media._server._token,
            'containerKey': '/playQueues/%s?window=100&own=1' % playqueue.playQueueID,
        }, **params))
コード例 #8
0
    def playMedia(self, media, **params):
        """Start playback on a media item.

        Args:
            media (str): movie, music, photo
            **params (TYPE): Description

        Raises:
            Unsupported: Description
        """
        if not self.server:
            raise Unsupported(
                'A server must be specified before using this command.')
        server_url = media.server.baseurl.split(':')
        playqueue = self.server.createPlayQueue(media)
        self.sendCommand(
            'playback/playMedia',
            **dict(
                {
                    'machineIdentifier':
                    self.server.machineIdentifier,
                    'address':
                    server_url[1].strip('/'),
                    'port':
                    server_url[-1],
                    'key':
                    media.key,
                    'containerKey':
                    '/playQueues/%s?window=100&own=1' % playqueue.playQueueID,
                }, **params))
コード例 #9
0
ファイル: playlist.py プロジェクト: Tautulli/Tautulli
    def section(self):
        """ Returns the :class:`~plexapi.library.LibrarySection` this smart playlist belongs to.

            Raises:
                :class:`plexapi.exceptions.BadRequest`: When trying to get the section for a regular playlist.
                :class:`plexapi.exceptions.Unsupported`: When unable to determine the library section.
        """
        if not self.smart:
            raise BadRequest(
                'Regular playlists are not associated with a library.')

        if self._section is None:
            # Try to parse the library section from the content URI string
            match = re.search(r'/library/sections/(\d+)/all',
                              unquote(self.content or ''))
            if match:
                sectionKey = int(match.group(1))
                self._section = self._server.library.sectionByID(sectionKey)
                return self._section

            # Try to get the library section from the first item in the playlist
            if self.items():
                self._section = self.items()[0].section()
                return self._section

            raise Unsupported('Unable to determine the library section')

        return self._section
コード例 #10
0
    def addItem(self, item, playNext=False, refresh=True):
        """
        Append the provided item to the "Up Next" section of the PlayQueue.
        Items can only be added to the section immediately following the current playing item.

        Parameters:
            item (:class:`~plexapi.media.Media` or :class:`~plexapi.playlist.Playlist`): Single media item or Playlist.
            playNext (bool, optional): If True, add this item to the front of the "Up Next" section.
                If False, the item will be appended to the end of the "Up Next" section.
                Only has an effect if an item has already been added to the "Up Next" section.
                See https://support.plex.tv/articles/202188298-play-queues/ for more details.
            refresh (bool, optional): Refresh the PlayQueue from the server before updating.
        """
        if refresh:
            self.refresh()

        args = {}
        if item.type == "playlist":
            args["playlistID"] = item.ratingKey
            itemType = item.playlistType
        else:
            uuid = item.section().uuid
            itemType = item.listType
            args["uri"] = f"library://{uuid}/item{item.key}"

        if itemType != self.playQueueType:
            raise Unsupported("Item type does not match PlayQueue type")

        if playNext:
            args["next"] = 1

        path = f"/playQueues/{self.playQueueID}{utils.joinArgs(args)}"
        data = self._server.query(path, method=self._server._session.put)
        self._loadData(data)
コード例 #11
0
ファイル: client.py プロジェクト: raleeper/python-plexapi
    def goToMedia(self, media, **params):
        """ Navigate directly to the specified media page.

            Parameters:
                media (:class:`~plexapi.media.Media`): Media object to navigate to.
                **params (dict): Additional GET parameters to include with the command.

            Raises:
                :exc:`plexapi.exceptions.Unsupported`: When no PlexServer specified in this object.
        """
        if not self._server:
            raise Unsupported(
                'A server must be specified before using this command.')
        server_url = media._server._baseurl.split(':')
        self.sendCommand(
            'mirror/details',
            **dict(
                {
                    'machineIdentifier': self._server.machineIdentifier,
                    'address': server_url[1].strip('/'),
                    'port': server_url[-1],
                    'key': media.key,
                    'protocol': server_url[0],
                    'token': media._server.createToken()
                }, **params))
コード例 #12
0
ファイル: client.py プロジェクト: dgoren/python-plexapi
    def sendCommand(self, command, proxy=None, **params):
        """ Convenience wrapper around :func:`~plexapi.client.PlexClient.query()` to more easily
            send simple commands to the client. Returns an ElementTree object containing
            the response.

            Parameters:
                command (str): Command to be sent in for format '<controller>/<command>'.
                proxy (bool): Set True to proxy this command through the PlexServer.
                **params (dict): Additional GET parameters to include with the command.

            Raises:
                :class:`~plexapi.exceptions.Unsupported`: When we detect the client doesn't support this capability.
        """
        command = command.strip('/')
        controller = command.split('/')[0]
        if controller not in self.protocolCapabilities:
            raise Unsupported('Client %s does not support the %s controller.' %
                (self.title, controller))
        path = '/player/%s%s' % (command, utils.joinArgs(params))
        headers = {'X-Plex-Target-Client-Identifier': self.machineIdentifier}
        self._commandId += 1
        params['commandID'] = self._commandId
        proxy = self._proxyThroughServer if proxy is None else proxy
        if proxy:
            return self.server.query(path, headers=headers)
        path = '/player/%s%s' % (command, utils.joinArgs(params))
        return self.query(path, headers=headers)
コード例 #13
0
 def metadataType(self):
     if self.isVideo:
         return 'movie'
     elif self.isAudio:
         return 'track'
     elif self.isPhoto:
         return 'photo'
     else:
         raise Unsupported('Unexpected playlist type')
コード例 #14
0
 def reload(self, key=None):
     """ Reload the data for this object from self.key. """
     key = key or self._details_key or self.key
     if not key:
         raise Unsupported('Cannot reload an object not built from a URL.')
     self._initpath = key
     data = self._server.query(key)
     self._loadData(data[0])
     return self
コード例 #15
0
ファイル: client.py プロジェクト: joax01/PlexAPI-4.2.0.1
    def playMedia(self, media, offset=0, **params):
        """ Start playback of the specified media item. See also:

            Parameters:
                media (:class:`~plexapi.media.Media`): Media item to be played back
                    (movie, music, photo, playlist, playqueue).
                offset (int): Number of milliseconds at which to start playing with zero
                    representing the beginning (default 0).
                **params (dict): Optional additional parameters to include in the playback request. See
                    also: https://github.com/plexinc/plex-media-player/wiki/Remote-control-API#modified-commands

            Raises:
                :class:`plexapi.exceptions.Unsupported`: When no PlexServer specified in this object.
        """
        if not self._server:
            raise Unsupported(
                'A server must be specified before using this command.')
        server_url = media._server._baseurl.split(':')
        server_port = server_url[-1].strip('/')

        if hasattr(media, "playlistType"):
            mediatype = media.playlistType
        else:
            if isinstance(media, PlayQueue):
                mediatype = media.items[0].listType
            else:
                mediatype = media.listType

        # mediatype must be in ["video", "music", "photo"]
        if mediatype == "audio":
            mediatype = "music"

        playqueue = media if isinstance(
            media, PlayQueue) else self._server.createPlayQueue(media)
        self.sendCommand(
            'playback/playMedia',
            **dict(
                {
                    'machineIdentifier':
                    self._server.machineIdentifier,
                    'address':
                    server_url[1].strip('/'),
                    'port':
                    server_port,
                    'offset':
                    offset,
                    'key':
                    media.key,
                    'token':
                    media._server.createToken(),
                    'type':
                    mediatype,
                    'containerKey':
                    '/playQueues/%s&&window=100&&own=1' %
                    playqueue.playQueueID,
                }, **params))
コード例 #16
0
ファイル: playlist.py プロジェクト: Tautulli/Tautulli
 def metadataType(self):
     """ Returns the type of metadata in the playlist (movie, track, or photo). """
     if self.isVideo:
         return 'movie'
     elif self.isAudio:
         return 'track'
     elif self.isPhoto:
         return 'photo'
     else:
         raise Unsupported('Unexpected playlist type')
コード例 #17
0
ファイル: collection.py プロジェクト: Tautulli/Tautulli
 def listType(self):
     """ Returns the listType for the collection. """
     if self.isVideo:
         return 'video'
     elif self.isAudio:
         return 'audio'
     elif self.isPhoto:
         return 'photo'
     else:
         raise Unsupported('Unexpected collection type')
コード例 #18
0
ファイル: collection.py プロジェクト: Tautulli/Tautulli
    def sync(self, videoQuality=None, photoResolution=None, audioBitrate=None, client=None, clientId=None, limit=None,
             unwatched=False, title=None):
        """ Add the collection as sync item for the specified device.
            See :func:`~plexapi.myplex.MyPlexAccount.sync` for possible exceptions.

            Parameters:
                videoQuality (int): idx of quality of the video, one of VIDEO_QUALITY_* values defined in
                                    :mod:`~plexapi.sync` module. Used only when collection contains video.
                photoResolution (str): maximum allowed resolution for synchronized photos, see PHOTO_QUALITY_* values in
                                       the module :mod:`~plexapi.sync`. Used only when collection contains photos.
                audioBitrate (int): maximum bitrate for synchronized music, better use one of MUSIC_BITRATE_* values
                                    from the module :mod:`~plexapi.sync`. Used only when collection contains audio.
                client (:class:`~plexapi.myplex.MyPlexDevice`): sync destination, see
                                                               :func:`~plexapi.myplex.MyPlexAccount.sync`.
                clientId (str): sync destination, see :func:`~plexapi.myplex.MyPlexAccount.sync`.
                limit (int): maximum count of items to sync, unlimited if `None`.
                unwatched (bool): if `True` watched videos wouldn't be synced.
                title (str): descriptive title for the new :class:`~plexapi.sync.SyncItem`, if empty the value would be
                             generated from metadata of current photo.

            Raises:
                :exc:`~plexapi.exceptions.BadRequest`: When collection is not allowed to sync.
                :exc:`~plexapi.exceptions.Unsupported`: When collection content is unsupported.

            Returns:
                :class:`~plexapi.sync.SyncItem`: A new instance of the created sync item.
        """
        if not self.section().allowSync:
            raise BadRequest('The collection is not allowed to sync')

        from plexapi.sync import SyncItem, Policy, MediaSettings

        myplex = self._server.myPlexAccount()
        sync_item = SyncItem(self._server, None)
        sync_item.title = title if title else self.title
        sync_item.rootTitle = self.title
        sync_item.contentType = self.listType
        sync_item.metadataType = self.metadataType
        sync_item.machineIdentifier = self._server.machineIdentifier

        sync_item.location = 'library:///directory/%s' % quote_plus(
            '%s/children?excludeAllLeaves=1' % (self.key)
        )
        sync_item.policy = Policy.create(limit, unwatched)

        if self.isVideo:
            sync_item.mediaSettings = MediaSettings.createVideo(videoQuality)
        elif self.isAudio:
            sync_item.mediaSettings = MediaSettings.createMusic(audioBitrate)
        elif self.isPhoto:
            sync_item.mediaSettings = MediaSettings.createPhoto(photoResolution)
        else:
            raise Unsupported('Unsupported collection content')

        return myplex.sync(sync_item, client=client, clientId=clientId)
コード例 #19
0
ファイル: client.py プロジェクト: raleeper/python-plexapi
 def connect(self, timeout=None):
     """ Alias of reload as any subsequent requests to this client will be
         made directly to the device even if the object attributes were initially
         populated from a PlexServer.
     """
     if not self.key:
         raise Unsupported('Cannot reload an object not built from a URL.')
     self._initpath = self.key
     data = self.query(self.key, timeout=timeout)
     self._loadData(data[0])
     return self
コード例 #20
0
    def proxyThroughServer(self, value=True):
        """Connect to the client via the server.

        Args:
            value (bool, optional): Description

        Raises:
            Unsupported: Cannot use client proxy with unknown server.
        """
        if value is True and not self.server:
            raise Unsupported('Cannot use client proxy with unknown server.')
        self._proxyThroughServer = value
コード例 #21
0
 def _reload(self, key=None, _overwriteNone=True, **kwargs):
     """ Perform the actual reload. """
     details_key = self._buildDetailsKey(
         **kwargs) if kwargs else self._details_key
     key = key or details_key or self.key
     if not key:
         raise Unsupported('Cannot reload an object not built from a URL.')
     self._initpath = key
     data = self._server.query(key)
     self._overwriteNone = _overwriteNone
     self._loadData(data[0])
     self._overwriteNone = True
     return self
コード例 #22
0
ファイル: client.py プロジェクト: dgoren/python-plexapi
    def proxyThroughServer(self, value=True):
        """ Tells this PlexClient instance to proxy all future commands through the PlexServer.
            Useful if you do not wish to connect directly to the Client device itself. 

            Parameters:
                value (bool): Enable or disable proxying (optional, default True).

            Raises:
                :class:`~plexapi.exceptions.Unsupported`: Cannot use client proxy with unknown server.
        """
        if value is True and not self.server:
            raise Unsupported('Cannot use client proxy with unknown server.')
        self._proxyThroughServer = value
コード例 #23
0
ファイル: client.py プロジェクト: suavp/python-plexapi
 def goToMedia(self, media, **params):
     if not self.server:
         raise Unsupported(
             'A server must be specified before using this command.')
     server_url = media.server.baseurl.split(':')
     self.sendCommand(
         'mirror/details',
         **dict(
             {
                 'machineIdentifier': self.server.machineIdentifier,
                 'address': server_url[1].strip('/'),
                 'port': server_url[-1],
                 'key': media.key,
             }, **params))
コード例 #24
0
ファイル: client.py プロジェクト: suavp/python-plexapi
 def sendCommand(self, command, proxy=None, **params):
     command = command.strip('/')
     controller = command.split('/')[0]
     if controller not in self.protocolCapabilities:
         raise Unsupported('Client %s does not support the %s controller.' %
                           (self.title, controller))
     path = '/player/%s%s' % (command, utils.joinArgs(params))
     headers = {'X-Plex-Target-Client-Identifier': self.machineIdentifier}
     self._commandId += 1
     params['commandID'] = self._commandId
     proxy = self._proxyThroughServer if proxy is None else proxy
     if proxy:
         return self.server.query(path, headers=headers)
     path = '/player/%s%s' % (command, utils.joinArgs(params))
     return self.query(path, headers=headers)
コード例 #25
0
ファイル: client.py プロジェクト: suavp/python-plexapi
 def playMedia(self, media, **params):
     if not self.server:
         raise Unsupported(
             'A server must be specified before using this command.')
     server_url = media.server.baseurl.split(':')
     playqueue = self.server.createPlayQueue(media)
     self.sendCommand(
         'playback/playMedia',
         **dict(
             {
                 'machineIdentifier':
                 self.server.machineIdentifier,
                 'address':
                 server_url[1].strip('/'),
                 'port':
                 server_url[-1],
                 'key':
                 media.key,
                 'containerKey':
                 '/playQueues/%s?window=100&own=1' % playqueue.playQueueID,
             }, **params))
コード例 #26
0
ファイル: base.py プロジェクト: rubicon/Tautulli
    def reload(self, key=None, **kwargs):
        """ Reload the data for this object from self.key.

            Parameters:
                key (string, optional): Override the key to reload.
                **kwargs (dict): A dictionary of XML include parameters to exclude or override.
                    All parameters are included by default with the option to override each parameter
                    or disable each parameter individually by setting it to False or 0.
                    See :class:`~plexapi.base.PlexPartialObject` for all the available include parameters.

            Example:

                .. code-block:: python

                    from plexapi.server import PlexServer
                    plex = PlexServer('http://localhost:32400', token='xxxxxxxxxxxxxxxxxxxx')
                    movie = plex.library.section('Movies').get('Cars')

                    # Partial reload of the movie without the `checkFiles` parameter.
                    # Excluding `checkFiles` will prevent the Plex server from reading the
                    # file to check if the file still exists and is accessible.
                    # The movie object will remain as a partial object.
                    movie.reload(checkFiles=False)
                    movie.isPartialObject()  # Returns True

                    # Full reload of the movie with all include parameters.
                    # The movie object will be a full object.
                    movie.reload()
                    movie.isFullObject()  # Returns True

        """
        details_key = self._buildDetailsKey(
            **kwargs) if kwargs else self._details_key
        key = key or details_key or self.key
        if not key:
            raise Unsupported('Cannot reload an object not built from a URL.')
        self._initpath = key
        data = self._server.query(key)
        self._loadData(data[0])
        return self
コード例 #27
0
    def goToMedia(self, media, **params):
        """Go to a media on the client.

        Args:
            media (str): movie, music, photo
            **params (TYPE): Description # todo

        Raises:
            Unsupported: Description
        """
        if not self.server:
            raise Unsupported(
                'A server must be specified before using this command.')
        server_url = media.server.baseurl.split(':')
        self.sendCommand(
            'mirror/details',
            **dict(
                {
                    'machineIdentifier': self.server.machineIdentifier,
                    'address': server_url[1].strip('/'),
                    'port': server_url[-1],
                    'key': media.key,
                }, **params))
コード例 #28
0
ファイル: client.py プロジェクト: suavp/python-plexapi
 def proxyThroughServer(self, value=True):
     if value is True and not self.server:
         raise Unsupported('Cannot use client proxy with unknown server.')
     self._proxyThroughServer = value