mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-22 03:33:08 +00:00
Fix various typos (#880)
* Fix various typos * Fix various typos in tests * Fix typos in `tests` * Fix more typos * Fix hasScalingMatrix test Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>
This commit is contained in:
parent
9a5170c2fb
commit
3917b335ca
27 changed files with 97 additions and 97 deletions
|
@ -21,9 +21,9 @@ TIMEOUT = CONFIG.get('plexapi.timeout', 30, int)
|
||||||
X_PLEX_CONTAINER_SIZE = CONFIG.get('plexapi.container_size', 100, int)
|
X_PLEX_CONTAINER_SIZE = CONFIG.get('plexapi.container_size', 100, int)
|
||||||
X_PLEX_ENABLE_FAST_CONNECT = CONFIG.get('plexapi.enable_fast_connect', False, bool)
|
X_PLEX_ENABLE_FAST_CONNECT = CONFIG.get('plexapi.enable_fast_connect', False, bool)
|
||||||
|
|
||||||
# Plex Header Configuation
|
# Plex Header Configuration
|
||||||
X_PLEX_PROVIDES = CONFIG.get('header.provides', 'controller')
|
X_PLEX_PROVIDES = CONFIG.get('header.provides', 'controller')
|
||||||
X_PLEX_PLATFORM = CONFIG.get('header.platform', CONFIG.get('header.platorm', uname()[0]))
|
X_PLEX_PLATFORM = CONFIG.get('header.platform', CONFIG.get('header.platform', uname()[0]))
|
||||||
X_PLEX_PLATFORM_VERSION = CONFIG.get('header.platform_version', uname()[2])
|
X_PLEX_PLATFORM_VERSION = CONFIG.get('header.platform_version', uname()[2])
|
||||||
X_PLEX_PRODUCT = CONFIG.get('header.product', PROJECT)
|
X_PLEX_PRODUCT = CONFIG.get('header.product', PROJECT)
|
||||||
X_PLEX_VERSION = CONFIG.get('header.version', VERSION)
|
X_PLEX_VERSION = CONFIG.get('header.version', VERSION)
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Audio(PlexPartialObject):
|
||||||
title (str): Name of the artist, album, or track (Jason Mraz, We Sing, Lucky, etc.).
|
title (str): Name of the artist, album, or track (Jason Mraz, We Sing, Lucky, etc.).
|
||||||
titleSort (str): Title to use when sorting (defaults to title).
|
titleSort (str): Title to use when sorting (defaults to title).
|
||||||
type (str): 'artist', 'album', or 'track'.
|
type (str): 'artist', 'album', or 'track'.
|
||||||
updatedAt (datatime): Datetime the item was updated.
|
updatedAt (datetime): Datetime the item was updated.
|
||||||
userRating (float): Rating of the item (0.0 - 10.0) equaling (0 stars - 5 stars).
|
userRating (float): Rating of the item (0.0 - 10.0) equaling (0 stars - 5 stars).
|
||||||
viewCount (int): Count of times the item was played.
|
viewCount (int): Count of times the item was played.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -196,7 +196,7 @@ class PlexObject(object):
|
||||||
Any XML attribute can be filtered when fetching results. Filtering is done before
|
Any XML attribute can be filtered when fetching results. Filtering is done before
|
||||||
the Python objects are built to help keep things speedy. For example, passing in
|
the Python objects are built to help keep things speedy. For example, passing in
|
||||||
``viewCount=0`` will only return matching items where the view count is ``0``.
|
``viewCount=0`` will only return matching items where the view count is ``0``.
|
||||||
Note that case matters when specifying attributes. Attributes futher down in the XML
|
Note that case matters when specifying attributes. Attributes further down in the XML
|
||||||
tree can be filtered by *prepending* the attribute with each element tag ``Tag__``.
|
tree can be filtered by *prepending* the attribute with each element tag ``Tag__``.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
@ -228,12 +228,12 @@ class PlexObject(object):
|
||||||
* ``__exists`` (*bool*): Value is or is not present in the attrs.
|
* ``__exists`` (*bool*): Value is or is not present in the attrs.
|
||||||
* ``__gt``: Value is greater than specified arg.
|
* ``__gt``: Value is greater than specified arg.
|
||||||
* ``__gte``: Value is greater than or equal to specified arg.
|
* ``__gte``: Value is greater than or equal to specified arg.
|
||||||
* ``__icontains``: Case insensative value contains specified arg.
|
* ``__icontains``: Case insensitive value contains specified arg.
|
||||||
* ``__iendswith``: Case insensative value ends with specified arg.
|
* ``__iendswith``: Case insensitive value ends with specified arg.
|
||||||
* ``__iexact``: Case insensative value matches specified arg.
|
* ``__iexact``: Case insensitive value matches specified arg.
|
||||||
* ``__in``: Value is in a specified list or tuple.
|
* ``__in``: Value is in a specified list or tuple.
|
||||||
* ``__iregex``: Case insensative value matches the specified regular expression.
|
* ``__iregex``: Case insensitive value matches the specified regular expression.
|
||||||
* ``__istartswith``: Case insensative value starts with specified arg.
|
* ``__istartswith``: Case insensitive value starts with specified arg.
|
||||||
* ``__lt``: Value is less than specified arg.
|
* ``__lt``: Value is less than specified arg.
|
||||||
* ``__lte``: Value is less than or equal to specified arg.
|
* ``__lte``: Value is less than or equal to specified arg.
|
||||||
* ``__regex``: Value matches the specified regular expression.
|
* ``__regex``: Value matches the specified regular expression.
|
||||||
|
@ -392,7 +392,7 @@ class PlexObject(object):
|
||||||
# check were looking for the tag
|
# check were looking for the tag
|
||||||
if attr.lower() == 'etag':
|
if attr.lower() == 'etag':
|
||||||
return [elem.tag]
|
return [elem.tag]
|
||||||
# loop through attrs so we can perform case-insensative match
|
# loop through attrs so we can perform case-insensitive match
|
||||||
for _attr, value in elem.attrib.items():
|
for _attr, value in elem.attrib.items():
|
||||||
if attr.lower() == _attr.lower():
|
if attr.lower() == _attr.lower():
|
||||||
return [value]
|
return [value]
|
||||||
|
@ -455,7 +455,7 @@ class PlexPartialObject(PlexObject):
|
||||||
def __getattribute__(self, attr):
|
def __getattribute__(self, attr):
|
||||||
# Dragons inside.. :-/
|
# Dragons inside.. :-/
|
||||||
value = super(PlexPartialObject, self).__getattribute__(attr)
|
value = super(PlexPartialObject, self).__getattribute__(attr)
|
||||||
# Check a few cases where we dont want to reload
|
# Check a few cases where we don't want to reload
|
||||||
if attr in _DONT_RELOAD_FOR_KEYS: return value
|
if attr in _DONT_RELOAD_FOR_KEYS: return value
|
||||||
if attr in _DONT_OVERWRITE_SESSION_KEYS: return value
|
if attr in _DONT_OVERWRITE_SESSION_KEYS: return value
|
||||||
if attr in USER_DONT_RELOAD_FOR_KEYS: return value
|
if attr in USER_DONT_RELOAD_FOR_KEYS: return value
|
||||||
|
@ -709,7 +709,7 @@ class Playable(object):
|
||||||
filename = part.file
|
filename = part.file
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
# So this seems to be a alot slower but allows transcode.
|
# So this seems to be a a lot slower but allows transcode.
|
||||||
download_url = self.getStreamURL(**kwargs)
|
download_url = self.getStreamURL(**kwargs)
|
||||||
else:
|
else:
|
||||||
download_url = self._server.url('%s?download=1' % part.key)
|
download_url = self._server.url('%s?download=1' % part.key)
|
||||||
|
|
|
@ -23,10 +23,10 @@ class PlexClient(PlexObject):
|
||||||
server (:class:`~plexapi.server.PlexServer`): PlexServer this client is connected to (optional).
|
server (:class:`~plexapi.server.PlexServer`): PlexServer this client is connected to (optional).
|
||||||
data (ElementTree): Response from PlexServer used to build this object (optional).
|
data (ElementTree): Response from PlexServer used to build this object (optional).
|
||||||
initpath (str): Path used to generate data.
|
initpath (str): Path used to generate data.
|
||||||
baseurl (str): HTTP URL to connect dirrectly to this client.
|
baseurl (str): HTTP URL to connect directly to this client.
|
||||||
identifier (str): The resource/machine identifier for the desired client.
|
identifier (str): The resource/machine identifier for the desired client.
|
||||||
May be necessary when connecting to a specific proxied client (optional).
|
May be necessary when connecting to a specific proxied client (optional).
|
||||||
token (str): X-Plex-Token used for authenication (optional).
|
token (str): X-Plex-Token used for authentication (optional).
|
||||||
session (:class:`~requests.Session`): requests.Session object if you want more control (optional).
|
session (:class:`~requests.Session`): requests.Session object if you want more control (optional).
|
||||||
timeout (int): timeout in seconds on initial connect to client (default config.TIMEOUT).
|
timeout (int): timeout in seconds on initial connect to client (default config.TIMEOUT).
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class PlexClient(PlexObject):
|
||||||
session (:class:`~requests.Session`): Session object used for connection.
|
session (:class:`~requests.Session`): Session object used for connection.
|
||||||
state (str): Unknown
|
state (str): Unknown
|
||||||
title (str): Name of this client (Johns iPhone, etc).
|
title (str): Name of this client (Johns iPhone, etc).
|
||||||
token (str): X-Plex-Token used for authenication
|
token (str): X-Plex-Token used for authentication
|
||||||
vendor (str): Unknown
|
vendor (str): Unknown
|
||||||
version (str): Device version (4.6.1, etc).
|
version (str): Device version (4.6.1, etc).
|
||||||
_baseurl (str): HTTP address of the client.
|
_baseurl (str): HTTP address of the client.
|
||||||
|
@ -210,8 +210,8 @@ class PlexClient(PlexObject):
|
||||||
controller = command.split('/')[0]
|
controller = command.split('/')[0]
|
||||||
headers = {'X-Plex-Target-Client-Identifier': self.machineIdentifier}
|
headers = {'X-Plex-Target-Client-Identifier': self.machineIdentifier}
|
||||||
if controller not in self.protocolCapabilities:
|
if controller not in self.protocolCapabilities:
|
||||||
log.debug('Client %s doesnt support %s controller.'
|
log.debug("Client %s doesn't support %s controller."
|
||||||
'What your trying might not work' % (self.title, controller))
|
"What your trying might not work" % (self.title, controller))
|
||||||
|
|
||||||
proxy = self._proxyThroughServer if proxy is None else proxy
|
proxy = self._proxyThroughServer if proxy is None else proxy
|
||||||
query = self._server.query if proxy else self.query
|
query = self._server.query if proxy else self.query
|
||||||
|
|
|
@ -50,7 +50,7 @@ class Collection(PlexPartialObject, AdvancedSettingsMixin, ArtMixin, PosterMixin
|
||||||
title (str): Name of the collection.
|
title (str): Name of the collection.
|
||||||
titleSort (str): Title to use when sorting (defaults to title).
|
titleSort (str): Title to use when sorting (defaults to title).
|
||||||
type (str): 'collection'
|
type (str): 'collection'
|
||||||
updatedAt (datatime): Datetime the collection was updated.
|
updatedAt (datetime): Datetime the collection was updated.
|
||||||
userRating (float): Rating of the collection (0.0 - 10.0) equaling (0 stars - 5 stars).
|
userRating (float): Rating of the collection (0.0 - 10.0) equaling (0 stars - 5 stars).
|
||||||
"""
|
"""
|
||||||
TAG = 'Directory'
|
TAG = 'Directory'
|
||||||
|
@ -219,7 +219,7 @@ class Collection(PlexPartialObject, AdvancedSettingsMixin, ArtMixin, PosterMixin
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
sort (str): One of the following values:
|
sort (str): One of the following values:
|
||||||
"realease" (Order Collection by realease dates),
|
"release" (Order Collection by release dates),
|
||||||
"alpha" (Order Collection alphabetically),
|
"alpha" (Order Collection alphabetically),
|
||||||
"custom" (Custom collection order)
|
"custom" (Custom collection order)
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import struct
|
||||||
class GDM:
|
class GDM:
|
||||||
"""Base class to discover GDM services.
|
"""Base class to discover GDM services.
|
||||||
|
|
||||||
Atrributes:
|
Attributes:
|
||||||
entries (List<dict>): List of server and/or client data discovered.
|
entries (List<dict>): List of server and/or client data discovered.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ class Library(PlexObject):
|
||||||
def search(self, title=None, libtype=None, **kwargs):
|
def search(self, title=None, libtype=None, **kwargs):
|
||||||
""" Searching within a library section is much more powerful. It seems certain
|
""" Searching within a library section is much more powerful. It seems certain
|
||||||
attributes on the media objects can be targeted to filter this search down
|
attributes on the media objects can be targeted to filter this search down
|
||||||
a bit, but I havent found the documentation for it.
|
a bit, but I haven't found the documentation for it.
|
||||||
|
|
||||||
Example: "studio=Comedy%20Central" or "year=1999" "title=Kung Fu" all work. Other items
|
Example: "studio=Comedy%20Central" or "year=1999" "title=Kung Fu" all work. Other items
|
||||||
such as actor=<id> seem to work, but require you already know the id of the actor.
|
such as actor=<id> seem to work, but require you already know the id of the actor.
|
||||||
|
@ -396,7 +396,7 @@ class LibrarySection(PlexObject):
|
||||||
self.type = data.attrib.get('type')
|
self.type = data.attrib.get('type')
|
||||||
self.updatedAt = utils.toDatetime(data.attrib.get('updatedAt'))
|
self.updatedAt = utils.toDatetime(data.attrib.get('updatedAt'))
|
||||||
self.uuid = data.attrib.get('uuid')
|
self.uuid = data.attrib.get('uuid')
|
||||||
# Private attrs as we dont want a reload.
|
# Private attrs as we don't want a reload.
|
||||||
self._filterTypes = None
|
self._filterTypes = None
|
||||||
self._fieldTypes = None
|
self._fieldTypes = None
|
||||||
self._totalViewSize = None
|
self._totalViewSize = None
|
||||||
|
@ -1271,7 +1271,7 @@ class LibrarySection(PlexObject):
|
||||||
* See :func:`~plexapi.library.LibrarySection.listOperators` to get a list of all available operators.
|
* See :func:`~plexapi.library.LibrarySection.listOperators` to get a list of all available operators.
|
||||||
* See :func:`~plexapi.library.LibrarySection.listFilterChoices` to get a list of all available filter values.
|
* See :func:`~plexapi.library.LibrarySection.listFilterChoices` to get a list of all available filter values.
|
||||||
|
|
||||||
The following filter fields are just some examples of the possible filters. The list is not exaustive,
|
The following filter fields are just some examples of the possible filters. The list is not exhaustive,
|
||||||
and not all filters apply to all library types.
|
and not all filters apply to all library types.
|
||||||
|
|
||||||
* **actor** (:class:`~plexapi.media.MediaTag`): Search for the name of an actor.
|
* **actor** (:class:`~plexapi.media.MediaTag`): Search for the name of an actor.
|
||||||
|
@ -1334,7 +1334,7 @@ class LibrarySection(PlexObject):
|
||||||
Some filters may be prefixed by the ``libtype`` separated by a ``.`` (e.g. ``show.collection``,
|
Some filters may be prefixed by the ``libtype`` separated by a ``.`` (e.g. ``show.collection``,
|
||||||
``episode.title``, ``artist.style``, ``album.genre``, ``track.userRating``, etc.). This should not be
|
``episode.title``, ``artist.style``, ``album.genre``, ``track.userRating``, etc.). This should not be
|
||||||
confused with the ``libtype`` parameter. If no ``libtype`` prefix is provided, then the default library
|
confused with the ``libtype`` parameter. If no ``libtype`` prefix is provided, then the default library
|
||||||
type is assumed. For example, in a TV show library ``viewCout`` is assumed to be ``show.viewCount``.
|
type is assumed. For example, in a TV show library ``viewCount`` is assumed to be ``show.viewCount``.
|
||||||
If you want to filter using episode view count then you must specify ``episode.viewCount`` explicitly.
|
If you want to filter using episode view count then you must specify ``episode.viewCount`` explicitly.
|
||||||
In addition, if the filter does not exist for the default library type it will fallback to the most
|
In addition, if the filter does not exist for the default library type it will fallback to the most
|
||||||
specific ``libtype`` available. For example, ``show.unwatched`` does not exists so it will fallback to
|
specific ``libtype`` available. For example, ``show.unwatched`` does not exists so it will fallback to
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Media(PlexObject):
|
||||||
|
|
||||||
<Photo_only_attributes>: The following attributes are only available for photos.
|
<Photo_only_attributes>: The following attributes are only available for photos.
|
||||||
|
|
||||||
* aperture (str): The apeture used to take the photo.
|
* aperture (str): The aperture used to take the photo.
|
||||||
* exposure (str): The exposure used to take the photo.
|
* exposure (str): The exposure used to take the photo.
|
||||||
* iso (int): The iso used to take the photo.
|
* iso (int): The iso used to take the photo.
|
||||||
* lens (str): The lens used to take the photo.
|
* lens (str): The lens used to take the photo.
|
||||||
|
@ -93,7 +93,7 @@ class Media(PlexObject):
|
||||||
try:
|
try:
|
||||||
return self._server.query(part, method=self._server._session.delete)
|
return self._server.query(part, method=self._server._session.delete)
|
||||||
except BadRequest:
|
except BadRequest:
|
||||||
log.error("Failed to delete %s. This could be because you havn't allowed "
|
log.error("Failed to delete %s. This could be because you haven't allowed "
|
||||||
"items to be deleted" % part)
|
"items to be deleted" % part)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@ -283,8 +283,8 @@ class VideoStream(MediaPartStream):
|
||||||
duration (int): The duration of video stream in milliseconds.
|
duration (int): The duration of video stream in milliseconds.
|
||||||
frameRate (float): The frame rate of the video stream (ex: 23.976).
|
frameRate (float): The frame rate of the video stream (ex: 23.976).
|
||||||
frameRateMode (str): The frame rate mode of the video stream.
|
frameRateMode (str): The frame rate mode of the video stream.
|
||||||
hasScallingMatrix (bool): True if video stream has a scaling matrix.
|
hasScalingMatrix (bool): True if video stream has a scaling matrix.
|
||||||
height (int): The hight of the video stream in pixels (ex: 1080).
|
height (int): The height of the video stream in pixels (ex: 1080).
|
||||||
level (int): The codec encoding level of the video stream (ex: 41).
|
level (int): The codec encoding level of the video stream (ex: 41).
|
||||||
profile (str): The profile of the video stream (ex: asp).
|
profile (str): The profile of the video stream (ex: asp).
|
||||||
pixelAspectRatio (str): The pixel aspect ratio of the video stream.
|
pixelAspectRatio (str): The pixel aspect ratio of the video stream.
|
||||||
|
@ -323,7 +323,7 @@ class VideoStream(MediaPartStream):
|
||||||
self.duration = utils.cast(int, data.attrib.get('duration'))
|
self.duration = utils.cast(int, data.attrib.get('duration'))
|
||||||
self.frameRate = utils.cast(float, data.attrib.get('frameRate'))
|
self.frameRate = utils.cast(float, data.attrib.get('frameRate'))
|
||||||
self.frameRateMode = data.attrib.get('frameRateMode')
|
self.frameRateMode = data.attrib.get('frameRateMode')
|
||||||
self.hasScallingMatrix = utils.cast(bool, data.attrib.get('hasScallingMatrix'))
|
self.hasScalingMatrix = utils.cast(bool, data.attrib.get('hasScalingMatrix'))
|
||||||
self.height = utils.cast(int, data.attrib.get('height'))
|
self.height = utils.cast(int, data.attrib.get('height'))
|
||||||
self.level = utils.cast(int, data.attrib.get('level'))
|
self.level = utils.cast(int, data.attrib.get('level'))
|
||||||
self.profile = data.attrib.get('profile')
|
self.profile = data.attrib.get('profile')
|
||||||
|
@ -400,7 +400,7 @@ class SubtitleStream(MediaPartStream):
|
||||||
container (str): The container of the subtitle stream.
|
container (str): The container of the subtitle stream.
|
||||||
forced (bool): True if this is a forced subtitle.
|
forced (bool): True if this is a forced subtitle.
|
||||||
format (str): The format of the subtitle stream (ex: srt).
|
format (str): The format of the subtitle stream (ex: srt).
|
||||||
headerCommpression (str): The header compression of the subtitle stream.
|
headerCompression (str): The header compression of the subtitle stream.
|
||||||
transient (str): Unknown.
|
transient (str): Unknown.
|
||||||
"""
|
"""
|
||||||
TAG = 'Stream'
|
TAG = 'Stream'
|
||||||
|
@ -468,7 +468,7 @@ class TranscodeSession(PlexObject):
|
||||||
audioDecision (str): The transcode decision for the audio stream.
|
audioDecision (str): The transcode decision for the audio stream.
|
||||||
complete (bool): True if the transcode is complete.
|
complete (bool): True if the transcode is complete.
|
||||||
container (str): The container of the transcoded media.
|
container (str): The container of the transcoded media.
|
||||||
context (str): The context for the transcode sesson.
|
context (str): The context for the transcode session.
|
||||||
duration (int): The duration of the transcoded media in milliseconds.
|
duration (int): The duration of the transcoded media in milliseconds.
|
||||||
height (int): The height of the transcoded media in pixels.
|
height (int): The height of the transcoded media in pixels.
|
||||||
key (str): API URL (ex: /transcode/sessions/<id>).
|
key (str): API URL (ex: /transcode/sessions/<id>).
|
||||||
|
|
|
@ -52,7 +52,7 @@ class MyPlexAccount(PlexObject):
|
||||||
roles: (List<str>) Lit of account roles. Plexpass membership listed here.
|
roles: (List<str>) Lit of account roles. Plexpass membership listed here.
|
||||||
scrobbleTypes (str): Description
|
scrobbleTypes (str): Description
|
||||||
secure (bool): Description
|
secure (bool): Description
|
||||||
subscriptionActive (bool): True if your subsctiption is active.
|
subscriptionActive (bool): True if your subscription is active.
|
||||||
subscriptionFeatures: (List<str>) List of features allowed on your subscription.
|
subscriptionFeatures: (List<str>) List of features allowed on your subscription.
|
||||||
subscriptionPlan (str): Name of subscription plan.
|
subscriptionPlan (str): Name of subscription plan.
|
||||||
subscriptionStatus (str): String representation of `subscriptionActive`.
|
subscriptionStatus (str): String representation of `subscriptionActive`.
|
||||||
|
@ -614,7 +614,7 @@ class MyPlexAccount(PlexObject):
|
||||||
clientId (str): an identifier of a client to query SyncItems for.
|
clientId (str): an identifier of a client to query SyncItems for.
|
||||||
|
|
||||||
If both `client` and `clientId` provided the client would be preferred.
|
If both `client` and `clientId` provided the client would be preferred.
|
||||||
If neither `client` nor `clientId` provided the clientId would be set to current clients`s identifier.
|
If neither `client` nor `clientId` provided the clientId would be set to current clients's identifier.
|
||||||
"""
|
"""
|
||||||
if client:
|
if client:
|
||||||
clientId = client.clientIdentifier
|
clientId = client.clientIdentifier
|
||||||
|
@ -635,14 +635,14 @@ class MyPlexAccount(PlexObject):
|
||||||
sync_item (:class:`~plexapi.sync.SyncItem`): prepared SyncItem object with all fields set.
|
sync_item (:class:`~plexapi.sync.SyncItem`): prepared SyncItem object with all fields set.
|
||||||
|
|
||||||
If both `client` and `clientId` provided the client would be preferred.
|
If both `client` and `clientId` provided the client would be preferred.
|
||||||
If neither `client` nor `clientId` provided the clientId would be set to current clients`s identifier.
|
If neither `client` nor `clientId` provided the clientId would be set to current clients's identifier.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:class:`~plexapi.sync.SyncItem`: an instance of created syncItem.
|
:class:`~plexapi.sync.SyncItem`: an instance of created syncItem.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
:exc:`~plexapi.exceptions.BadRequest`: When client with provided clientId wasn`t found.
|
:exc:`~plexapi.exceptions.BadRequest`: When client with provided clientId wasn't found.
|
||||||
:exc:`~plexapi.exceptions.BadRequest`: Provided client doesn`t provides `sync-target`.
|
:exc:`~plexapi.exceptions.BadRequest`: Provided client doesn't provides `sync-target`.
|
||||||
"""
|
"""
|
||||||
if not client and not clientId:
|
if not client and not clientId:
|
||||||
clientId = X_PLEX_IDENTIFIER
|
clientId = X_PLEX_IDENTIFIER
|
||||||
|
@ -657,7 +657,7 @@ class MyPlexAccount(PlexObject):
|
||||||
raise BadRequest('Unable to find client by clientId=%s', clientId)
|
raise BadRequest('Unable to find client by clientId=%s', clientId)
|
||||||
|
|
||||||
if 'sync-target' not in client.provides:
|
if 'sync-target' not in client.provides:
|
||||||
raise BadRequest('Received client doesn`t provides sync-target')
|
raise BadRequest("Received client doesn't provides sync-target")
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
'SyncItem[title]': sync_item.title,
|
'SyncItem[title]': sync_item.title,
|
||||||
|
@ -790,7 +790,7 @@ class MyPlexUser(PlexObject):
|
||||||
restricted (str): Unknown.
|
restricted (str): Unknown.
|
||||||
servers (List<:class:`~plexapi.myplex.<MyPlexServerShare`>)): Servers shared with the user.
|
servers (List<:class:`~plexapi.myplex.<MyPlexServerShare`>)): Servers shared with the user.
|
||||||
thumb (str): Link to the users avatar.
|
thumb (str): Link to the users avatar.
|
||||||
title (str): Seems to be an aliad for username.
|
title (str): Seems to be an alias for username.
|
||||||
username (str): User's username.
|
username (str): User's username.
|
||||||
"""
|
"""
|
||||||
TAG = 'User'
|
TAG = 'User'
|
||||||
|
@ -1103,7 +1103,7 @@ class MyPlexResource(PlexObject):
|
||||||
:exc:`~plexapi.exceptions.NotFound`: When unable to connect to any addresses for this resource.
|
:exc:`~plexapi.exceptions.NotFound`: When unable to connect to any addresses for this resource.
|
||||||
"""
|
"""
|
||||||
connections = self.preferred_connections(ssl, timeout, locations, schemes)
|
connections = self.preferred_connections(ssl, timeout, locations, schemes)
|
||||||
# Try connecting to all known resource connections in parellel, but
|
# Try connecting to all known resource connections in parallel, but
|
||||||
# only return the first server (in order) that provides a response.
|
# only return the first server (in order) that provides a response.
|
||||||
cls = PlexServer if 'server' in self.provides else PlexClient
|
cls = PlexServer if 'server' in self.provides else PlexClient
|
||||||
listargs = [[cls, url, self.accessToken, timeout] for url in connections]
|
listargs = [[cls, url, self.accessToken, timeout] for url in connections]
|
||||||
|
@ -1215,7 +1215,7 @@ class MyPlexDevice(PlexObject):
|
||||||
""" Returns an instance of :class:`~plexapi.sync.SyncList` for current device.
|
""" Returns an instance of :class:`~plexapi.sync.SyncList` for current device.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
:exc:`~plexapi.exceptions.BadRequest`: when the device doesn`t provides `sync-target`.
|
:exc:`~plexapi.exceptions.BadRequest`: when the device doesn't provides `sync-target`.
|
||||||
"""
|
"""
|
||||||
if 'sync-target' not in self.provides:
|
if 'sync-target' not in self.provides:
|
||||||
raise BadRequest('Requested syncList for device which do not provides sync-target')
|
raise BadRequest('Requested syncList for device which do not provides sync-target')
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Photoalbum(PlexPartialObject, ArtMixin, PosterMixin, RatingMixin):
|
||||||
title (str): Name of the photo album. (Trip to Disney World)
|
title (str): Name of the photo album. (Trip to Disney World)
|
||||||
titleSort (str): Title to use when sorting (defaults to title).
|
titleSort (str): Title to use when sorting (defaults to title).
|
||||||
type (str): 'photo'
|
type (str): 'photo'
|
||||||
updatedAt (datatime): Datetime the photo album was updated.
|
updatedAt (datetime): Datetime the photo album was updated.
|
||||||
userRating (float): Rating of the photo album (0.0 - 10.0) equaling (0 stars - 5 stars).
|
userRating (float): Rating of the photo album (0.0 - 10.0) equaling (0 stars - 5 stars).
|
||||||
"""
|
"""
|
||||||
TAG = 'Directory'
|
TAG = 'Directory'
|
||||||
|
@ -109,7 +109,7 @@ class Photoalbum(PlexPartialObject, ArtMixin, PosterMixin, RatingMixin):
|
||||||
return self.episode(title)
|
return self.episode(title)
|
||||||
|
|
||||||
def download(self, savepath=None, keep_original_name=False, subfolders=False):
|
def download(self, savepath=None, keep_original_name=False, subfolders=False):
|
||||||
""" Download all photos and clips from the photo ablum. See :func:`~plexapi.base.Playable.download` for details.
|
""" Download all photos and clips from the photo album. See :func:`~plexapi.base.Playable.download` for details.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
savepath (str): Defaults to current working dir.
|
savepath (str): Defaults to current working dir.
|
||||||
|
@ -164,7 +164,7 @@ class Photo(PlexPartialObject, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixi
|
||||||
title (str): Name of the photo.
|
title (str): Name of the photo.
|
||||||
titleSort (str): Title to use when sorting (defaults to title).
|
titleSort (str): Title to use when sorting (defaults to title).
|
||||||
type (str): 'photo'
|
type (str): 'photo'
|
||||||
updatedAt (datatime): Datetime the photo was updated.
|
updatedAt (datetime): Datetime the photo was updated.
|
||||||
userRating (float): Rating of the photo (0.0 - 10.0) equaling (0 stars - 5 stars).
|
userRating (float): Rating of the photo (0.0 - 10.0) equaling (0 stars - 5 stars).
|
||||||
year (int): Year the photo was taken.
|
year (int): Year the photo was taken.
|
||||||
"""
|
"""
|
||||||
|
@ -223,7 +223,7 @@ class Photo(PlexPartialObject, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixi
|
||||||
elif self.parentKey:
|
elif self.parentKey:
|
||||||
return self._server.library.sectionByID(self.photoalbum().librarySectionID)
|
return self._server.library.sectionByID(self.photoalbum().librarySectionID)
|
||||||
else:
|
else:
|
||||||
raise BadRequest('Unable to get section for photo, can`t find librarySectionID')
|
raise BadRequest("Unable to get section for photo, can't find librarySectionID")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def locations(self):
|
def locations(self):
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Playlist(PlexPartialObject, Playable, ArtMixin, PosterMixin, SmartFilterMi
|
||||||
summary (str): Summary of the playlist.
|
summary (str): Summary of the playlist.
|
||||||
title (str): Name of the playlist.
|
title (str): Name of the playlist.
|
||||||
type (str): 'playlist'
|
type (str): 'playlist'
|
||||||
updatedAt (datatime): Datetime the playlist was updated.
|
updatedAt (datetime): Datetime the playlist was updated.
|
||||||
"""
|
"""
|
||||||
TAG = 'Playlist'
|
TAG = 'Playlist'
|
||||||
TYPE = 'playlist'
|
TYPE = 'playlist'
|
||||||
|
|
|
@ -314,7 +314,7 @@ class PlexServer(PlexObject):
|
||||||
def myPlexAccount(self):
|
def myPlexAccount(self):
|
||||||
""" Returns a :class:`~plexapi.myplex.MyPlexAccount` object using the same
|
""" Returns a :class:`~plexapi.myplex.MyPlexAccount` object using the same
|
||||||
token to access this server. If you are not the owner of this PlexServer
|
token to access this server. If you are not the owner of this PlexServer
|
||||||
you're likley to recieve an authentication error calling this.
|
you're likely to receive an authentication error calling this.
|
||||||
"""
|
"""
|
||||||
if self._myPlexAccount is None:
|
if self._myPlexAccount is None:
|
||||||
from plexapi.myplex import MyPlexAccount
|
from plexapi.myplex import MyPlexAccount
|
||||||
|
@ -323,7 +323,7 @@ class PlexServer(PlexObject):
|
||||||
|
|
||||||
def _myPlexClientPorts(self):
|
def _myPlexClientPorts(self):
|
||||||
""" Sometimes the PlexServer does not properly advertise port numbers required
|
""" Sometimes the PlexServer does not properly advertise port numbers required
|
||||||
to connect. This attemps to look up device port number from plex.tv.
|
to connect. This attempts to look up device port number from plex.tv.
|
||||||
See issue #126: Make PlexServer.clients() more user friendly.
|
See issue #126: Make PlexServer.clients() more user friendly.
|
||||||
https://github.com/pkkid/python-plexapi/issues/126
|
https://github.com/pkkid/python-plexapi/issues/126
|
||||||
"""
|
"""
|
||||||
|
@ -1078,7 +1078,7 @@ class SystemDevice(PlexObject):
|
||||||
Attributes:
|
Attributes:
|
||||||
TAG (str): 'Device'
|
TAG (str): 'Device'
|
||||||
clientIdentifier (str): The unique identifier for the device.
|
clientIdentifier (str): The unique identifier for the device.
|
||||||
createdAt (datatime): Datetime the device was created.
|
createdAt (datetime): Datetime the device was created.
|
||||||
id (int): The ID of the device (not the same as :class:`~plexapi.myplex.MyPlexDevice` ID).
|
id (int): The ID of the device (not the same as :class:`~plexapi.myplex.MyPlexDevice` ID).
|
||||||
key (str): API URL (/devices/<id>)
|
key (str): API URL (/devices/<id>)
|
||||||
name (str): The name of the device.
|
name (str): The name of the device.
|
||||||
|
@ -1102,11 +1102,11 @@ class StatisticsBandwidth(PlexObject):
|
||||||
Attributes:
|
Attributes:
|
||||||
TAG (str): 'StatisticsBandwidth'
|
TAG (str): 'StatisticsBandwidth'
|
||||||
accountID (int): The associated :class:`~plexapi.server.SystemAccount` ID.
|
accountID (int): The associated :class:`~plexapi.server.SystemAccount` ID.
|
||||||
at (datatime): Datetime of the bandwidth data.
|
at (datetime): Datetime of the bandwidth data.
|
||||||
bytes (int): The total number of bytes for the specified timespan.
|
bytes (int): The total number of bytes for the specified time span.
|
||||||
deviceID (int): The associated :class:`~plexapi.server.SystemDevice` ID.
|
deviceID (int): The associated :class:`~plexapi.server.SystemDevice` ID.
|
||||||
lan (bool): True or False wheter the bandwidth is local or remote.
|
lan (bool): True or False whether the bandwidth is local or remote.
|
||||||
timespan (int): The timespan for the bandwidth data.
|
timespan (int): The time span for the bandwidth data.
|
||||||
1: months, 2: weeks, 3: days, 4: hours, 6: seconds.
|
1: months, 2: weeks, 3: days, 4: hours, 6: seconds.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -1143,12 +1143,12 @@ class StatisticsResources(PlexObject):
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
TAG (str): 'StatisticsResources'
|
TAG (str): 'StatisticsResources'
|
||||||
at (datatime): Datetime of the resource data.
|
at (datetime): Datetime of the resource data.
|
||||||
hostCpuUtilization (float): The system CPU usage %.
|
hostCpuUtilization (float): The system CPU usage %.
|
||||||
hostMemoryUtilization (float): The Plex Media Server CPU usage %.
|
hostMemoryUtilization (float): The Plex Media Server CPU usage %.
|
||||||
processCpuUtilization (float): The system RAM usage %.
|
processCpuUtilization (float): The system RAM usage %.
|
||||||
processMemoryUtilization (float): The Plex Media Server RAM usage %.
|
processMemoryUtilization (float): The Plex Media Server RAM usage %.
|
||||||
timespan (int): The timespan for the resource data (6: seconds).
|
timespan (int): The time span for the resource data (6: seconds).
|
||||||
"""
|
"""
|
||||||
TAG = 'StatisticsResources'
|
TAG = 'StatisticsResources'
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Settings(PlexObject):
|
||||||
return self.groups().get(group, [])
|
return self.groups().get(group, [])
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
""" Save any outstanding settnig changes to the :class:`~plexapi.server.PlexServer`. This
|
""" Save any outstanding setting changes to the :class:`~plexapi.server.PlexServer`. This
|
||||||
performs a full reload() of Settings after complete.
|
performs a full reload() of Settings after complete.
|
||||||
"""
|
"""
|
||||||
params = {}
|
params = {}
|
||||||
|
@ -100,7 +100,7 @@ class Setting(PlexObject):
|
||||||
hidden (bool): True if this is a hidden setting.
|
hidden (bool): True if this is a hidden setting.
|
||||||
advanced (bool): True if this is an advanced setting.
|
advanced (bool): True if this is an advanced setting.
|
||||||
group (str): Group name this setting is categorized as.
|
group (str): Group name this setting is categorized as.
|
||||||
enumValues (list,dict): List or dictionary of valis values for this setting.
|
enumValues (list,dict): List or dictionary of valid values for this setting.
|
||||||
"""
|
"""
|
||||||
_bool_cast = lambda x: bool(x == 'true' or x == '1')
|
_bool_cast = lambda x: bool(x == 'true' or x == '1')
|
||||||
_bool_str = lambda x: str(x).lower()
|
_bool_str = lambda x: str(x).lower()
|
||||||
|
@ -143,7 +143,7 @@ class Setting(PlexObject):
|
||||||
return enumstr.split('|')
|
return enumstr.split('|')
|
||||||
|
|
||||||
def set(self, value):
|
def set(self, value):
|
||||||
""" Set a new value for this setitng. NOTE: You must call plex.settings.save() for before
|
""" Set a new value for this setting. NOTE: You must call plex.settings.save() for before
|
||||||
any changes to setting values are persisted to the :class:`~plexapi.server.PlexServer`.
|
any changes to setting values are persisted to the :class:`~plexapi.server.PlexServer`.
|
||||||
"""
|
"""
|
||||||
# check a few things up front
|
# check a few things up front
|
||||||
|
|
|
@ -14,7 +14,7 @@ class PlexSonosClient(PlexClient):
|
||||||
speakers linked to your Plex account. It also requires remote access to
|
speakers linked to your Plex account. It also requires remote access to
|
||||||
be working properly.
|
be working properly.
|
||||||
|
|
||||||
More details on the Sonos integration are avaialble here:
|
More details on the Sonos integration are available here:
|
||||||
https://support.plex.tv/articles/218237558-requirements-for-using-plex-for-sonos/
|
https://support.plex.tv/articles/218237558-requirements-for-using-plex-for-sonos/
|
||||||
|
|
||||||
The Sonos API emulates the Plex player control API closely:
|
The Sonos API emulates the Plex player control API closely:
|
||||||
|
@ -38,7 +38,7 @@ class PlexSonosClient(PlexClient):
|
||||||
server (:class:`~plexapi.server.PlexServer`): Server this client is connected to.
|
server (:class:`~plexapi.server.PlexServer`): Server this client is connected to.
|
||||||
session (:class:`~requests.Session`): Session object used for connection.
|
session (:class:`~requests.Session`): Session object used for connection.
|
||||||
title (str): Name of this Sonos speaker.
|
title (str): Name of this Sonos speaker.
|
||||||
token (str): X-Plex-Token used for authenication
|
token (str): X-Plex-Token used for authentication
|
||||||
_baseurl (str): Address of public Plex Sonos API endpoint.
|
_baseurl (str): Address of public Plex Sonos API endpoint.
|
||||||
_commandId (int): Counter for commands sent to Plex API.
|
_commandId (int): Counter for commands sent to Plex API.
|
||||||
_token (str): Token associated with linked Plex account.
|
_token (str): Token associated with linked Plex account.
|
||||||
|
|
|
@ -55,7 +55,7 @@ class SecretsFilter(logging.Filter):
|
||||||
|
|
||||||
def registerPlexObject(cls):
|
def registerPlexObject(cls):
|
||||||
""" Registry of library types we may come across when parsing XML. This allows us to
|
""" Registry of library types we may come across when parsing XML. This allows us to
|
||||||
define a few helper functions to dynamically convery the XML into objects. See
|
define a few helper functions to dynamically convert the XML into objects. See
|
||||||
buildItem() below for an example.
|
buildItem() below for an example.
|
||||||
"""
|
"""
|
||||||
etype = getattr(cls, 'STREAMTYPE', getattr(cls, 'TAGTYPE', cls.TYPE))
|
etype = getattr(cls, 'STREAMTYPE', getattr(cls, 'TAGTYPE', cls.TYPE))
|
||||||
|
@ -72,7 +72,7 @@ def cast(func, value):
|
||||||
only support str, int, float, bool. Should be extended if needed.
|
only support str, int, float, bool. Should be extended if needed.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
func (func): Calback function to used cast to type (int, bool, float).
|
func (func): Callback function to used cast to type (int, bool, float).
|
||||||
value (any): value to be cast and returned.
|
value (any): value to be cast and returned.
|
||||||
"""
|
"""
|
||||||
if value is not None:
|
if value is not None:
|
||||||
|
@ -114,7 +114,7 @@ def lowerFirst(s):
|
||||||
|
|
||||||
|
|
||||||
def rget(obj, attrstr, default=None, delim='.'): # pragma: no cover
|
def rget(obj, attrstr, default=None, delim='.'): # pragma: no cover
|
||||||
""" Returns the value at the specified attrstr location within a nexted tree of
|
""" Returns the value at the specified attrstr location within a nested tree of
|
||||||
dicts, lists, tuples, functions, classes, etc. The lookup is done recursively
|
dicts, lists, tuples, functions, classes, etc. The lookup is done recursively
|
||||||
for each key in attrstr (split by by the delimiter) This function is heavily
|
for each key in attrstr (split by by the delimiter) This function is heavily
|
||||||
influenced by the lookups used in Django templates.
|
influenced by the lookups used in Django templates.
|
||||||
|
@ -485,7 +485,7 @@ def getAgentIdentifier(section, agent):
|
||||||
if agent in identifiers:
|
if agent in identifiers:
|
||||||
return ag.identifier
|
return ag.identifier
|
||||||
agents += identifiers
|
agents += identifiers
|
||||||
raise NotFound('Couldnt find "%s" in agents list (%s)' %
|
raise NotFound('Could not find "%s" in agents list (%s)' %
|
||||||
(agent, ', '.join(agents)))
|
(agent, ', '.join(agents)))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class Video(PlexPartialObject):
|
||||||
title (str): Name of the movie, show, season, episode, or clip.
|
title (str): Name of the movie, show, season, episode, or clip.
|
||||||
titleSort (str): Title to use when sorting (defaults to title).
|
titleSort (str): Title to use when sorting (defaults to title).
|
||||||
type (str): 'movie', 'show', 'season', 'episode', or 'clip'.
|
type (str): 'movie', 'show', 'season', 'episode', or 'clip'.
|
||||||
updatedAt (datatime): Datetime the item was updated.
|
updatedAt (datetime): Datetime the item was updated.
|
||||||
userRating (float): Rating of the item (0.0 - 10.0) equaling (0 stars - 5 stars).
|
userRating (float): Rating of the item (0.0 - 10.0) equaling (0 stars - 5 stars).
|
||||||
viewCount (int): Count of times the item was played.
|
viewCount (int): Count of times the item was played.
|
||||||
"""
|
"""
|
||||||
|
@ -78,7 +78,7 @@ class Video(PlexPartialObject):
|
||||||
return self._server.url(part, includeToken=True) if part else None
|
return self._server.url(part, includeToken=True) if part else None
|
||||||
|
|
||||||
def markWatched(self):
|
def markWatched(self):
|
||||||
""" Mark the video as palyed. """
|
""" Mark the video as played. """
|
||||||
key = '/:/scrobble?key=%s&identifier=com.plexapp.plugins.library' % self.ratingKey
|
key = '/:/scrobble?key=%s&identifier=com.plexapp.plugins.library' % self.ratingKey
|
||||||
self._server.query(key)
|
self._server.query(key)
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ class Movie(Video, Playable, AdvancedSettingsMixin, ArtMixin, PosterMixin, Theme
|
||||||
genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
|
genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
|
||||||
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
|
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
|
||||||
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
||||||
languageOverride (str): Setting that indicates if a languge is used to override metadata
|
languageOverride (str): Setting that indicates if a language is used to override metadata
|
||||||
(eg. en-CA, None = Library default).
|
(eg. en-CA, None = Library default).
|
||||||
media (List<:class:`~plexapi.media.Media`>): List of media objects.
|
media (List<:class:`~plexapi.media.Media`>): List of media objects.
|
||||||
originallyAvailableAt (datetime): Datetime the movie was released.
|
originallyAvailableAt (datetime): Datetime the movie was released.
|
||||||
|
@ -412,7 +412,7 @@ class Show(Video, AdvancedSettingsMixin, ArtMixin, BannerMixin, PosterMixin, The
|
||||||
index (int): Plex index number for the show.
|
index (int): Plex index number for the show.
|
||||||
key (str): API URL (/library/metadata/<ratingkey>).
|
key (str): API URL (/library/metadata/<ratingkey>).
|
||||||
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
||||||
languageOverride (str): Setting that indicates if a languge is used to override metadata
|
languageOverride (str): Setting that indicates if a language is used to override metadata
|
||||||
(eg. en-CA, None = Library default).
|
(eg. en-CA, None = Library default).
|
||||||
leafCount (int): Number of items in the show view.
|
leafCount (int): Number of items in the show view.
|
||||||
locations (List<str>): List of folder paths where the show is found on disk.
|
locations (List<str>): List of folder paths where the show is found on disk.
|
||||||
|
|
|
@ -320,7 +320,7 @@ def shared_username(account):
|
||||||
in (user.username.lower(), user.email.lower(), str(user.id))
|
in (user.username.lower(), user.email.lower(), str(user.id))
|
||||||
):
|
):
|
||||||
return username
|
return username
|
||||||
pytest.skip("Shared user %s wasn`t found in your MyPlex account" % username)
|
pytest.skip("Shared user %s wasn't found in your MyPlex account" % username)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
@ -333,7 +333,7 @@ def monkeydownload(request, monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def callable_http_patch():
|
def callable_http_patch():
|
||||||
"""This intented to stop some http requests inside some tests."""
|
"""This is intended to stop some http requests inside some tests."""
|
||||||
return patch(
|
return patch(
|
||||||
"plexapi.server.requests.sessions.Session.send",
|
"plexapi.server.requests.sessions.Session.send",
|
||||||
return_value=MagicMock(status_code=200, text="<xml><child></child></xml>"),
|
return_value=MagicMock(status_code=200, text="<xml><child></child></xml>"),
|
||||||
|
|
|
@ -9,7 +9,7 @@ def _check_capabilities(client, capabilities):
|
||||||
for capability in capabilities:
|
for capability in capabilities:
|
||||||
if capability not in supported:
|
if capability not in supported:
|
||||||
pytest.skip(
|
pytest.skip(
|
||||||
"Client %s doesnt support %s capability support %s"
|
"Client %s doesn't support %s capability support %s"
|
||||||
% (client.title, capability, supported)
|
% (client.title, capability, supported)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ def _check_proxy(plex, client, proxy):
|
||||||
|
|
||||||
@pytest.mark.client
|
@pytest.mark.client
|
||||||
def test_list_clients(account, plex):
|
def test_list_clients(account, plex):
|
||||||
assert account.resources(), "MyPlex is not listing any devlices."
|
assert account.resources(), "MyPlex is not listing any devices."
|
||||||
assert account.devices(), "MyPlex is not listing any devlices."
|
assert account.devices(), "MyPlex is not listing any devices."
|
||||||
assert plex.clients(), "PlexServer is not listing any clients."
|
assert plex.clients(), "PlexServer is not listing any clients."
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,15 +22,15 @@ def test_library_Library_section(plex):
|
||||||
|
|
||||||
|
|
||||||
def test_library_Library_sectionByID_is_equal_section(plex, movies):
|
def test_library_Library_sectionByID_is_equal_section(plex, movies):
|
||||||
# test that sctionmyID refreshes the section if the key is missing
|
# test that sectionByID refreshes the section if the key is missing
|
||||||
# this is needed if there isnt any cached sections
|
# this is needed if there isn't any cached sections
|
||||||
assert plex.library.sectionByID(movies.key).uuid == movies.uuid
|
assert plex.library.sectionByID(movies.key).uuid == movies.uuid
|
||||||
|
|
||||||
|
|
||||||
def test_library_sectionByID_with_attrs(plex, movies):
|
def test_library_sectionByID_with_attrs(plex, movies):
|
||||||
assert movies.agent == "tv.plex.agents.movie"
|
assert movies.agent == "tv.plex.agents.movie"
|
||||||
# This seems to fail for some reason.
|
# This seems to fail for some reason.
|
||||||
# my account alloew of sync, didnt find any about settings about the library.
|
# my account allow of sync, didn't find any about settings about the library.
|
||||||
# assert movies.allowSync is ("sync" in plex.ownerFeatures)
|
# assert movies.allowSync is ("sync" in plex.ownerFeatures)
|
||||||
assert movies.art == "/:/resources/movie-fanart.jpg"
|
assert movies.art == "/:/resources/movie-fanart.jpg"
|
||||||
assert utils.is_metadata(
|
assert utils.is_metadata(
|
||||||
|
@ -246,7 +246,7 @@ def test_library_MovieSection_cancelUpdate(movies):
|
||||||
movies.cancelUpdate()
|
movies.cancelUpdate()
|
||||||
|
|
||||||
|
|
||||||
def test_librarty_deleteMediaPreviews(movies):
|
def test_library_deleteMediaPreviews(movies):
|
||||||
movies.deleteMediaPreviews()
|
movies.deleteMediaPreviews()
|
||||||
|
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ def test_library_MovieSection_search_sort(movies):
|
||||||
|
|
||||||
|
|
||||||
def test_library_ShowSection_search_sort(tvshows):
|
def test_library_ShowSection_search_sort(tvshows):
|
||||||
# Test predefined Plex mult-sort
|
# Test predefined Plex multi-sort
|
||||||
seasonAsc = "season.index,season.titleSort"
|
seasonAsc = "season.index,season.titleSort"
|
||||||
results = tvshows.search(sort=seasonAsc, libtype="season")
|
results = tvshows.search(sort=seasonAsc, libtype="season")
|
||||||
sortedResults = sorted(results, key=lambda s: (s.index, s.titleSort))
|
sortedResults = sorted(results, key=lambda s: (s.index, s.titleSort))
|
||||||
|
@ -678,7 +678,7 @@ def test_library_ShowSection_search_sort(tvshows):
|
||||||
|
|
||||||
|
|
||||||
def test_library_MusicSection_search_sort(music):
|
def test_library_MusicSection_search_sort(music):
|
||||||
# Test predefined Plex mult-sort
|
# Test predefined Plex multi-sort
|
||||||
albumArtistAsc = "artist.titleSort,album.titleSort,album.index,album.id,album.originallyAvailableAt"
|
albumArtistAsc = "artist.titleSort,album.titleSort,album.index,album.id,album.originallyAvailableAt"
|
||||||
results = music.search(sort=albumArtistAsc, libtype="album")
|
results = music.search(sort=albumArtistAsc, libtype="album")
|
||||||
sortedResults = sorted(
|
sortedResults = sorted(
|
||||||
|
|
|
@ -13,9 +13,9 @@ def test_navigate_around_show(account, plex):
|
||||||
assert show.season(1) == season
|
assert show.season(1) == season
|
||||||
assert show.episode("Pilot") == episode, "Unable to get show episode:"
|
assert show.episode("Pilot") == episode, "Unable to get show episode:"
|
||||||
assert season.episode("Pilot") == episode, "Unable to get season episode:"
|
assert season.episode("Pilot") == episode, "Unable to get season episode:"
|
||||||
assert season.show() == show, "season.show() doesnt match expected show."
|
assert season.show() == show, "season.show() doesn't match expected show."
|
||||||
assert episode.show() == show, "episode.show() doesnt match expected show."
|
assert episode.show() == show, "episode.show() doesn't match expected show."
|
||||||
assert episode.season() == season, "episode.season() doesnt match expected season."
|
assert episode.season() == season, "episode.season() doesn't match expected season."
|
||||||
|
|
||||||
|
|
||||||
def test_navigate_around_artist(account, plex):
|
def test_navigate_around_artist(account, plex):
|
||||||
|
@ -30,6 +30,6 @@ def test_navigate_around_artist(account, plex):
|
||||||
print("Track: %s" % track)
|
print("Track: %s" % track)
|
||||||
assert artist.track("As Colourful as Ever") == track, "Unable to get artist track."
|
assert artist.track("As Colourful as Ever") == track, "Unable to get artist track."
|
||||||
assert album.track("As Colourful as Ever") == track, "Unable to get album track."
|
assert album.track("As Colourful as Ever") == track, "Unable to get album track."
|
||||||
assert album.artist() == artist, "album.artist() doesnt match expected artist."
|
assert album.artist() == artist, "album.artist() doesn't match expected artist."
|
||||||
assert track.artist() == artist, "track.artist() doesnt match expected artist."
|
assert track.artist() == artist, "track.artist() doesn't match expected artist."
|
||||||
assert track.album() == album, "track.album() doesnt match expected album."
|
assert track.album() == album, "track.album() doesn't match expected album."
|
||||||
|
|
|
@ -116,7 +116,7 @@ def test_modify_playqueue_with_library_media(plex, show):
|
||||||
assert pq.items[0].ratingKey == episodes[0].ratingKey, "Items not in proper order."
|
assert pq.items[0].ratingKey == episodes[0].ratingKey, "Items not in proper order."
|
||||||
assert pq.items[2].ratingKey == episodes[1].ratingKey, "Items not in proper order."
|
assert pq.items[2].ratingKey == episodes[1].ratingKey, "Items not in proper order."
|
||||||
assert pq.items[1].ratingKey == episodes[2].ratingKey, "Items not in proper order."
|
assert pq.items[1].ratingKey == episodes[2].ratingKey, "Items not in proper order."
|
||||||
# Test too many mathcing library items
|
# Test too many matching library items
|
||||||
pq.addItem(episodes[0])
|
pq.addItem(episodes[0])
|
||||||
pq.addItem(episodes[0])
|
pq.addItem(episodes[0])
|
||||||
with pytest.raises(BadRequest):
|
with pytest.raises(BadRequest):
|
||||||
|
|
|
@ -221,7 +221,7 @@ def test_server_Server_query(plex):
|
||||||
|
|
||||||
|
|
||||||
def test_server_Server_session(account):
|
def test_server_Server_session(account):
|
||||||
# Mock Sesstion
|
# Mock Session
|
||||||
class MySession(Session):
|
class MySession(Session):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(self.__class__, self).__init__()
|
super(self.__class__, self).__init__()
|
||||||
|
|
|
@ -374,7 +374,7 @@ def test_sync_entire_library_photos(clear_sync_device, photos):
|
||||||
sync_device=clear_sync_device,
|
sync_device=clear_sync_device,
|
||||||
sync_item=new_item,
|
sync_item=new_item,
|
||||||
)
|
)
|
||||||
# It's not that easy, to just get all the photos within the library, so let`s query for photos with device!=0x0
|
# It's not that easy, to just get all the photos within the library, so let's query for photos with device!=0x0
|
||||||
section_content = photos.search(libtype="photo", **{"addedAt>>": "2000-01-01"})
|
section_content = photos.search(libtype="photo", **{"addedAt>>": "2000-01-01"})
|
||||||
media_list = utils.wait_until(
|
media_list = utils.wait_until(
|
||||||
get_media, delay=0.25, timeout=3, item=item, server=photos._server
|
get_media, delay=0.25, timeout=3, item=item, server=photos._server
|
||||||
|
|
|
@ -338,7 +338,7 @@ def test_video_Movie_attrs(movies):
|
||||||
assert video.extendedDisplayTitle == "1080p (H.264)"
|
assert video.extendedDisplayTitle == "1080p (H.264)"
|
||||||
assert utils.is_float(video.frameRate, gte=20.0)
|
assert utils.is_float(video.frameRate, gte=20.0)
|
||||||
assert video.frameRateMode is None
|
assert video.frameRateMode is None
|
||||||
assert video.hasScallingMatrix is None
|
assert video.hasScalingMatrix is False
|
||||||
assert utils.is_int(video.height, gte=250)
|
assert utils.is_int(video.height, gte=250)
|
||||||
assert utils.is_int(video.id)
|
assert utils.is_int(video.id)
|
||||||
assert utils.is_int(video.index, gte=0)
|
assert utils.is_int(video.index, gte=0)
|
||||||
|
@ -396,7 +396,7 @@ def test_video_Movie_attrs(movies):
|
||||||
assert stream1.duration is None
|
assert stream1.duration is None
|
||||||
assert utils.is_float(stream1.frameRate, gte=20.0)
|
assert utils.is_float(stream1.frameRate, gte=20.0)
|
||||||
assert stream1.frameRateMode is None
|
assert stream1.frameRateMode is None
|
||||||
assert stream1.hasScallingMatrix is None
|
assert stream1.hasScalingMatrix is False
|
||||||
assert utils.is_int(stream1.height, gte=250)
|
assert utils.is_int(stream1.height, gte=250)
|
||||||
assert utils.is_int(stream1.id)
|
assert utils.is_int(stream1.id)
|
||||||
assert utils.is_int(stream1.index, gte=0)
|
assert utils.is_int(stream1.index, gte=0)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
The script is used to bootstrap a the test enviroment for plexapi
|
The script is used to bootstrap a the test environment for plexapi
|
||||||
with all the libraries required for testing.
|
with all the libraries required for testing.
|
||||||
|
|
||||||
By default this uses a docker.
|
By default this uses a docker.
|
||||||
|
@ -231,7 +231,7 @@ def get_default_ip():
|
||||||
|
|
||||||
|
|
||||||
def get_plex_account(opts):
|
def get_plex_account(opts):
|
||||||
""" Authenitcate with Plex using the command line options. """
|
""" Authenticate with Plex using the command line options. """
|
||||||
if not opts.unclaimed:
|
if not opts.unclaimed:
|
||||||
if opts.token:
|
if opts.token:
|
||||||
return MyPlexAccount(token=opts.token)
|
return MyPlexAccount(token=opts.token)
|
||||||
|
@ -381,7 +381,7 @@ if __name__ == "__main__":
|
||||||
default="plex-test-docker-%s" % str(uuid4()),
|
default="plex-test-docker-%s" % str(uuid4()),
|
||||||
) # noqa
|
) # noqa
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--accept-eula", help="Accept Plex`s EULA", default=False, action="store_true"
|
"--accept-eula", help="Accept Plex's EULA", default=False, action="store_true"
|
||||||
) # noqa
|
) # noqa
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--without-movies",
|
"--without-movies",
|
||||||
|
@ -479,7 +479,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
if not server:
|
if not server:
|
||||||
raise SystemExit(
|
raise SystemExit(
|
||||||
"Server didnt appear in your account after %ss" % opts.bootstrap_timeout
|
"Server didn't appear in your account after %ss" % opts.bootstrap_timeout
|
||||||
)
|
)
|
||||||
|
|
||||||
print("Plex container started after %ss" % int(runtime))
|
print("Plex container started after %ss" % int(runtime))
|
||||||
|
@ -498,7 +498,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
sections = []
|
sections = []
|
||||||
|
|
||||||
# Lets add a check here do somebody dont mess up
|
# Lets add a check here do somebody don't mess up
|
||||||
# there normal server if they run manual tests.
|
# there normal server if they run manual tests.
|
||||||
# Like i did....
|
# Like i did....
|
||||||
if len(server.library.sections()) and opts.no_docker is True:
|
if len(server.library.sections()) and opts.no_docker is True:
|
||||||
|
|
|
@ -79,7 +79,7 @@ if __name__ == '__main__':
|
||||||
items = search_for_item(opts.url)
|
items = search_for_item(opts.url)
|
||||||
for item in items:
|
for item in items:
|
||||||
for part in item.iterParts():
|
for part in item.iterParts():
|
||||||
# We do this manually since we dont want to add a progress to Episode etc
|
# We do this manually since we don't want to add a progress to Episode etc
|
||||||
filename = '%s.%s' % (item._prettyfilename(), part.container)
|
filename = '%s.%s' % (item._prettyfilename(), part.container)
|
||||||
url = item._server.url('%s?download=1' % part.key)
|
url = item._server.url('%s?download=1' % part.key)
|
||||||
filepath = utils.download(url, token=account.authenticationToken, filename=filename, savepath=os.getcwd(),
|
filepath = utils.download(url, token=account.authenticationToken, filename=filename, savepath=os.getcwd(),
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Plex-ListAttrs is used during development of PlexAPI and loops through all media
|
Plex-ListAttrs is used during development of PlexAPI and loops through all media
|
||||||
items to build a collection of attributes on each media type. The resulting list
|
items to build a collection of attributes on each media type. The resulting list
|
||||||
can be compared with the current object implementation in python-plexapi to track
|
can be compared with the current object implementation in python-plexapi to track
|
||||||
new attributes and depricate old ones.
|
new attributes and deprecate old ones.
|
||||||
"""
|
"""
|
||||||
import argparse, copy, pickle, plexapi, os, re, sys, time
|
import argparse, copy, pickle, plexapi, os, re, sys, time
|
||||||
from os.path import abspath, dirname, join
|
from os.path import abspath, dirname, join
|
||||||
|
@ -49,7 +49,7 @@ DONT_RELOAD = (
|
||||||
'myplex.MyPlexDevice',
|
'myplex.MyPlexDevice',
|
||||||
'photo.Photoalbum',
|
'photo.Photoalbum',
|
||||||
'server.Account',
|
'server.Account',
|
||||||
'client.PlexClient', # we dont have the token to reload.
|
'client.PlexClient', # we don't have the token to reload.
|
||||||
)
|
)
|
||||||
TAGATTRS = {
|
TAGATTRS = {
|
||||||
'Media': 'media',
|
'Media': 'media',
|
||||||
|
|
Loading…
Reference in a new issue