mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-10 06:04:15 +00:00
Make flake8 happy
This commit is contained in:
parent
1b549878ee
commit
cd1a05d770
15 changed files with 65 additions and 42 deletions
|
@ -21,6 +21,7 @@ install:
|
|||
|
||||
script:
|
||||
- py.test tests --tb=native --verbose --cov-config .coveragerc --cov=plexapi
|
||||
- flake8 plexapi --exclude=compat.py --max-line-length=120 --ignore=E128,E701,E702
|
||||
|
||||
after_success:
|
||||
- coveralls
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging, os
|
||||
import logging
|
||||
import os
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from platform import uname
|
||||
from plexapi.config import PlexConfig, reset_base_headers
|
||||
|
|
|
@ -111,7 +111,7 @@ class Artist(Audio):
|
|||
|
||||
def download(self, savepath=None, keep_orginal_name=False, **kwargs):
|
||||
""" Downloads all tracks for this artist to the specified location.
|
||||
|
||||
|
||||
Parameters:
|
||||
savepath (str): Title of the track to return.
|
||||
keep_orginal_name (bool): Set True to keep the original filename as stored in
|
||||
|
@ -188,7 +188,7 @@ class Album(Audio):
|
|||
|
||||
def download(self, savepath=None, keep_orginal_name=False, **kwargs):
|
||||
""" Downloads all tracks for this artist to the specified location.
|
||||
|
||||
|
||||
Parameters:
|
||||
savepath (str): Title of the track to return.
|
||||
keep_orginal_name (bool): Set True to keep the original filename as stored in
|
||||
|
|
|
@ -70,7 +70,7 @@ class PlexObject(object):
|
|||
etype = elem.attrib.get('type', elem.attrib.get('streamType'))
|
||||
ehash = '%s.%s' % (elem.tag, etype) if etype else elem.tag
|
||||
ecls = utils.PLEXOBJECTS.get(ehash, utils.PLEXOBJECTS.get(elem.tag))
|
||||
#log.debug('Building %s as %s', elem.tag, ecls.__name__)
|
||||
# log.debug('Building %s as %s', elem.tag, ecls.__name__)
|
||||
if ecls is not None:
|
||||
return ecls(self._server, elem, initpath)
|
||||
raise UnknownType("Unknown library type <%s type='%s'../>" % (elem.tag, etype))
|
||||
|
@ -201,7 +201,7 @@ class PlexObject(object):
|
|||
if operator(value, query):
|
||||
attrsFound[attr] = True
|
||||
break
|
||||
#log.debug('Checking %s for %s found: %s', elem.tag, kwargs, attrsFound)
|
||||
# log.debug('Checking %s for %s found: %s', elem.tag, kwargs, attrsFound)
|
||||
return all(attrsFound.values())
|
||||
|
||||
def _getAttrOperator(self, attr):
|
||||
|
@ -213,7 +213,7 @@ class PlexObject(object):
|
|||
return attr, 'exact', OPERATORS['exact']
|
||||
|
||||
def _getAttrValue(self, elem, attrstr, results=None):
|
||||
#log.debug('Fetching %s in %s', attrstr, elem.tag)
|
||||
# log.debug('Fetching %s in %s', attrstr, elem.tag)
|
||||
parts = attrstr.split('__', 1)
|
||||
attr = parts[0]
|
||||
attrstr = parts[1] if len(parts) == 2 else None
|
||||
|
|
|
@ -25,7 +25,7 @@ class PlexClient(PlexObject):
|
|||
baseurl (str): HTTP URL to connect dirrectly to this client.
|
||||
token (str): X-Plex-Token used for authenication (optional).
|
||||
session (:class:`~requests.Session`): requests.Session object if you want more control (optional).
|
||||
|
||||
|
||||
Attributes:
|
||||
TAG (str): 'Player'
|
||||
key (str): '/resources'
|
||||
|
@ -67,7 +67,7 @@ class PlexClient(PlexObject):
|
|||
|
||||
def connect(self):
|
||||
""" Alias of reload as any subsequent requests to this client will be
|
||||
made directly to the device even if the object attributes were initially
|
||||
made directly to the device even if the object attributes were initially
|
||||
populated from a PlexServer.
|
||||
"""
|
||||
if not self.key:
|
||||
|
@ -110,7 +110,7 @@ class PlexClient(PlexObject):
|
|||
|
||||
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.
|
||||
Useful if you do not wish to connect directly to the Client device itself.
|
||||
|
||||
Parameters:
|
||||
value (bool): Enable or disable proxying (optional, default True).
|
||||
|
@ -175,7 +175,7 @@ class PlexClient(PlexObject):
|
|||
return '%s%s%sX-Plex-Token=%s' % (self._baseurl, key, delim, self._token)
|
||||
return '%s%s' % (self._baseurl, key)
|
||||
|
||||
#---------------------
|
||||
# ---------------------
|
||||
# Navigation Commands
|
||||
# These commands navigate around the user-interface.
|
||||
def contextMenu(self):
|
||||
|
@ -254,7 +254,7 @@ class PlexClient(PlexObject):
|
|||
'key': media.key,
|
||||
}, **params))
|
||||
|
||||
#-------------------
|
||||
# -------------------
|
||||
# Playback Commands
|
||||
# Most of the playback commands take a mandatory mtype {'music','photo','video'} argument,
|
||||
# to specify which media type to apply the command to, (except for playMedia). This
|
||||
|
@ -400,7 +400,7 @@ class PlexClient(PlexObject):
|
|||
|
||||
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).
|
||||
|
@ -465,7 +465,7 @@ class PlexClient(PlexObject):
|
|||
params['type'] = mtype
|
||||
self.sendCommand('playback/setStreams', **params)
|
||||
|
||||
#-------------------
|
||||
# -------------------
|
||||
# Timeline Commands
|
||||
def timeline(self):
|
||||
""" Poll the current timeline and return the XML response. """
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
class PlexApiException(Exception):
|
||||
""" Base class for all PlexAPI exceptions. """
|
||||
pass
|
||||
|
||||
|
||||
class BadRequest(PlexApiException):
|
||||
""" An invalid request, generally a user error. """
|
||||
pass
|
||||
|
||||
|
||||
class NotFound(PlexApiException):
|
||||
""" Request media item or device is not found. """
|
||||
pass
|
||||
|
||||
|
||||
class UnknownType(PlexApiException):
|
||||
""" Unknown library type. """
|
||||
pass
|
||||
|
||||
|
||||
class Unsupported(PlexApiException):
|
||||
""" Unsupported client request. """
|
||||
pass
|
||||
|
||||
|
||||
class Unauthorized(PlexApiException):
|
||||
""" Invalid username or password. """
|
||||
pass
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from plexapi import X_PLEX_CONTAINER_SIZE, log, utils
|
||||
from plexapi.base import PlexObject
|
||||
from plexapi.compat import unquote
|
||||
from plexapi.media import MediaTag, Genre, Role, Director
|
||||
from plexapi.media import MediaTag
|
||||
from plexapi.exceptions import BadRequest, NotFound
|
||||
|
||||
|
||||
|
@ -303,7 +303,8 @@ class LibrarySection(PlexObject):
|
|||
sort (str): column:dir; column can be any of {addedAt, originallyAvailableAt, lastViewedAt,
|
||||
titleSort, rating, mediaHeight, duration}. dir can be asc or desc (optional).
|
||||
maxresults (int): Only return the specified number of results (optional).
|
||||
libtype (str): Filter results to a spcifiec libtype (movie, show, episode, artist, album, track; optional).
|
||||
libtype (str): Filter results to a spcifiec libtype (movie, show, episode, artist,
|
||||
album, track; optional).
|
||||
**kwargs (dict): Any of the available filters for the current library section. Partial string
|
||||
matches allowed. Multiple matches OR together. All inputs will be compared with the
|
||||
available options and a warning logged if the option does not appear valid.
|
||||
|
|
|
@ -143,7 +143,7 @@ class MediaPartStream(PlexObject):
|
|||
@staticmethod
|
||||
def parse(server, data, initpath):
|
||||
""" Factory method returns a new MediaPartStream from xml data. """
|
||||
STREAMCLS = {1:VideoStream, 2:AudioStream, 3:SubtitleStream}
|
||||
STREAMCLS = {1: VideoStream, 2: AudioStream, 3: SubtitleStream}
|
||||
stype = cast(int, data.attrib.get('streamType'))
|
||||
cls = STREAMCLS.get(stype, MediaPartStream)
|
||||
return cls(server, data, initpath)
|
||||
|
@ -340,6 +340,7 @@ class Collection(MediaTag):
|
|||
TAG = 'Collection'
|
||||
FILTER = 'collection'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Country(MediaTag):
|
||||
""" Represents a single Country media tag.
|
||||
|
@ -351,6 +352,7 @@ class Country(MediaTag):
|
|||
TAG = 'Country'
|
||||
FILTER = 'country'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Director(MediaTag):
|
||||
""" Represents a single Director media tag.
|
||||
|
@ -362,6 +364,7 @@ class Director(MediaTag):
|
|||
TAG = 'Director'
|
||||
FILTER = 'director'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Genre(MediaTag):
|
||||
""" Represents a single Genre media tag.
|
||||
|
@ -373,6 +376,7 @@ class Genre(MediaTag):
|
|||
TAG = 'Genre'
|
||||
FILTER = 'genre'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Mood(MediaTag):
|
||||
""" Represents a single Mood media tag.
|
||||
|
@ -384,6 +388,7 @@ class Mood(MediaTag):
|
|||
TAG = 'Mood'
|
||||
FILTER = 'mood'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Producer(MediaTag):
|
||||
""" Represents a single Producer media tag.
|
||||
|
@ -395,6 +400,7 @@ class Producer(MediaTag):
|
|||
TAG = 'Producer'
|
||||
FILTER = 'producer'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Role(MediaTag):
|
||||
""" Represents a single Role (actor/actress) media tag.
|
||||
|
@ -406,6 +412,7 @@ class Role(MediaTag):
|
|||
TAG = 'Role'
|
||||
FILTER = 'role'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Similar(MediaTag):
|
||||
""" Represents a single Similar media tag.
|
||||
|
@ -417,6 +424,7 @@ class Similar(MediaTag):
|
|||
TAG = 'Similar'
|
||||
FILTER = 'similar'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Writer(MediaTag):
|
||||
""" Represents a single Writer media tag.
|
||||
|
@ -428,6 +436,7 @@ class Writer(MediaTag):
|
|||
TAG = 'Writer'
|
||||
FILTER = 'writer'
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Field(PlexObject):
|
||||
""" Represents a single Field.
|
||||
|
|
|
@ -19,21 +19,21 @@ class MyPlexAccount(PlexObject):
|
|||
Attributes:
|
||||
SIGNIN (str): 'https://my.plexapp.com/users/sign_in.xml'
|
||||
key (str): 'https://plex.tv/users/account'
|
||||
authenticationToken (str): <Unknown>
|
||||
certificateVersion (str): <Unknown>
|
||||
cloudSyncDevice (str):
|
||||
authenticationToken (str): Unknown.
|
||||
certificateVersion (str): Unknown.
|
||||
cloudSyncDevice (str): Unknown.
|
||||
email (str): Your current Plex email address.
|
||||
entitlements (List<str>): List of devices your allowed to use with this account.
|
||||
guest (bool): <Unknown>
|
||||
home (bool): <Unknown>
|
||||
homeSize (int): <Unknown>
|
||||
guest (bool): Unknown.
|
||||
home (bool): Unknown.
|
||||
homeSize (int): Unknown.
|
||||
id (str): Your Plex account ID.
|
||||
locale (str): Your Plex locale
|
||||
mailing_list_status (str): Your current mailing list status.
|
||||
maxHomeSize (int): <Unknown>
|
||||
maxHomeSize (int): Unknown.
|
||||
queueEmail (str): Email address to add items to your `Watch Later` queue.
|
||||
queueUid (str): <Unknown>
|
||||
restricted (bool): <Unknown>
|
||||
queueUid (str): Unknown.
|
||||
restricted (bool): Unknown.
|
||||
roles: (List<str>) Lit of account roles. Plexpass membership listed here.
|
||||
scrobbleTypes (str): Description
|
||||
secure (bool): Description
|
||||
|
@ -42,9 +42,9 @@ class MyPlexAccount(PlexObject):
|
|||
subscriptionPlan (str): Name of subscription plan.
|
||||
subscriptionStatus (str): String representation of `subscriptionActive`.
|
||||
thumb (str): URL of your account thumbnail.
|
||||
title (str): <Unknown> - Looks like an alias for `username`.
|
||||
title (str): Unknown. - Looks like an alias for `username`.
|
||||
username (str): Your account username.
|
||||
uuid (str): <Unknown>
|
||||
uuid (str): Unknown.
|
||||
"""
|
||||
SIGNIN = 'https://my.plexapp.com/users/sign_in.xml'
|
||||
key = 'https://plex.tv/users/account'
|
||||
|
@ -271,10 +271,9 @@ class MyPlexResource(PlexObject):
|
|||
"""
|
||||
# Sort connections from (https, local) to (http, remote)
|
||||
# Only check non-local connections unless we own the resource
|
||||
forcelocal = lambda c: self.owned or c.local
|
||||
connections = sorted(self.connections, key=lambda c: c.local, reverse=True)
|
||||
https = [c.uri for c in self.connections if forcelocal(c)]
|
||||
http = [c.httpuri for c in self.connections if forcelocal(c)]
|
||||
https = [c.uri for c in self.connections if self.owned or c.local]
|
||||
http = [c.httpuri for c in self.connections if self.owned or c.local]
|
||||
# Force ssl, no ssl, or any (default)
|
||||
if ssl is True: connections = https
|
||||
elif ssl is False: connections = http
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import json, threading
|
||||
import json
|
||||
import threading
|
||||
from plexapi import log
|
||||
from plexapi.exceptions import Unsupported
|
||||
|
||||
|
@ -27,7 +28,7 @@ class PlexNotifier(threading.Thread):
|
|||
def run(self):
|
||||
""" Starts the PlexNotifier thread. This function should not be called
|
||||
directly, instead use :func:`~plexapi.server.PlexServer.startNotifier`.
|
||||
"""
|
||||
"""
|
||||
# try importing websocket-client package
|
||||
try:
|
||||
import websocket
|
||||
|
|
|
@ -8,7 +8,7 @@ from plexapi.utils import cast, toDatetime
|
|||
|
||||
@utils.registerPlexObject
|
||||
class Playlist(PlexPartialObject, Playable):
|
||||
""" Represents a single Playlist object.
|
||||
""" Represents a single Playlist object.
|
||||
# TODO: Document attributes
|
||||
"""
|
||||
TAG = 'Playlist'
|
||||
|
@ -45,7 +45,8 @@ class Playlist(PlexPartialObject, Playable):
|
|||
ratingKeys = []
|
||||
for item in items:
|
||||
if item.listType != self.playlistType:
|
||||
raise BadRequest('Can not mix media types when building a playlist: %s and %s' % (self.playlistType, item.listType))
|
||||
raise BadRequest('Can not mix media types when building a playlist: %s and %s' %
|
||||
(self.playlistType, item.listType))
|
||||
ratingKeys.append(str(item.ratingKey))
|
||||
uuid = items[0].section().uuid
|
||||
ratingKeys = ','.join(ratingKeys)
|
||||
|
@ -68,7 +69,7 @@ class Playlist(PlexPartialObject, Playable):
|
|||
|
||||
def edit(self, title=None, summary=None):
|
||||
""" Edit playlist. """
|
||||
key = '/library/metadata/%s%s' % (self.ratingKey, utils.joinArgs({'title':title, 'summary':summary}))
|
||||
key = '/library/metadata/%s%s' % (self.ratingKey, utils.joinArgs({'title': title, 'summary': summary}))
|
||||
return self._server.query(key, method=self._server._session.put)
|
||||
|
||||
def delete(self):
|
||||
|
|
|
@ -14,8 +14,8 @@ from plexapi.playqueue import PlayQueue
|
|||
from plexapi.utils import cast
|
||||
|
||||
# Need these imports to populate utils.PLEXOBJECTS
|
||||
from plexapi import (audio as _audio, video as _video,
|
||||
photo as _photo, media as _media, playlist as _playlist)
|
||||
from plexapi import (audio as _audio, video as _video, # noqa: F401
|
||||
photo as _photo, media as _media, playlist as _playlist) # noqa: F401
|
||||
|
||||
|
||||
class PlexServer(PlexObject):
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging, os, requests, time
|
||||
import logging
|
||||
import os
|
||||
import requests
|
||||
import time
|
||||
from datetime import datetime
|
||||
from plexapi.compat import quote, string_type
|
||||
from plexapi.exceptions import NotFound
|
||||
|
@ -266,9 +269,9 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024, mo
|
|||
for chunk in response.iter_content(chunk_size=chunksize):
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
#log.debug('Downloaded %s to %s from %s' % (filename, fullpath, url))
|
||||
# log.debug('Downloaded %s to %s from %s' % (filename, fullpath, url))
|
||||
return fullpath
|
||||
except Exception as err: # pragma: no cover
|
||||
log.error('Error downloading file: %s' % err)
|
||||
raise
|
||||
#log.exception('Failed to download %s to %s %s' % (url, fullpath, e))
|
||||
# log.exception('Failed to download %s to %s %s' % (url, fullpath, e))
|
||||
|
|
|
@ -344,7 +344,7 @@ class Season(Video):
|
|||
return '<%s>' % ':'.join([p for p in [
|
||||
self.__class__.__name__,
|
||||
self.key.replace('/library/metadata/', '').replace('/children', ''),
|
||||
'%s-s%s' % (self.parentTitle.replace(' ','-')[:20], self.seasonNumber),
|
||||
'%s-s%s' % (self.parentTitle.replace(' ', '-')[:20], self.seasonNumber),
|
||||
] if p])
|
||||
|
||||
@property
|
||||
|
@ -476,7 +476,7 @@ class Episode(Video, Playable):
|
|||
return '<%s>' % ':'.join([p for p in [
|
||||
self.__class__.__name__,
|
||||
self.key.replace('/library/metadata/', '').replace('/children', ''),
|
||||
'%s-s%se%s' % (self.grandparentTitle.replace(' ','-')[:20], self.seasonNumber, self.index),
|
||||
'%s-s%se%s' % (self.grandparentTitle.replace(' ', '-')[:20], self.seasonNumber, self.index),
|
||||
] if p])
|
||||
|
||||
def _prettyfilename(self):
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
betamax
|
||||
betamax_serializers
|
||||
coveralls
|
||||
flake8
|
||||
pillow
|
||||
pytest
|
||||
pytest-cov
|
||||
|
|
Loading…
Reference in a new issue