mirror of
https://github.com/pkkid/python-plexapi
synced 2025-02-16 21:08:27 +00:00
Merge dev
This commit is contained in:
commit
44677e59a6
6 changed files with 79 additions and 28 deletions
|
@ -2,25 +2,25 @@
|
|||
import re
|
||||
from plexapi import log, utils
|
||||
from plexapi.compat import urlencode
|
||||
from plexapi.exceptions import NotFound, UnknownType, Unsupported
|
||||
from plexapi.exceptions import BadRequest, NotFound, UnknownType, Unsupported
|
||||
|
||||
OPERATORS = {
|
||||
'exact': lambda v,q: v == q,
|
||||
'iexact': lambda v,q: v.lower() == q.lower(),
|
||||
'contains': lambda v,q: q in v,
|
||||
'icontains': lambda v,q: q.lower() in v.lower(),
|
||||
'in': lambda v,q: v in q,
|
||||
'gt': lambda v,q: v > q,
|
||||
'gte': lambda v,q: v >= q,
|
||||
'lt': lambda v,q: v < q,
|
||||
'lte': lambda v,q: v <= q,
|
||||
'startswith': lambda v,q: v.startswith(q),
|
||||
'istartswith': lambda v,q: v.lower().startswith(q),
|
||||
'endswith': lambda v,q: v.endswith(q),
|
||||
'iendswith': lambda v,q: v.lower().endswith(q),
|
||||
'exists': lambda v,q: v is not None if q else v is None,
|
||||
'regex': lambda v,q: re.match(q, v),
|
||||
'iregex': lambda v,q: re.match(q, v, flags=re.IGNORECASE),
|
||||
'exact': lambda v, q: v == q,
|
||||
'iexact': lambda v, q: v.lower() == q.lower(),
|
||||
'contains': lambda v, q: q in v,
|
||||
'icontains': lambda v, q: q.lower() in v.lower(),
|
||||
'in': lambda v, q: v in q,
|
||||
'gt': lambda v, q: v > q,
|
||||
'gte': lambda v, q: v >= q,
|
||||
'lt': lambda v, q: v < q,
|
||||
'lte': lambda v, q: v <= q,
|
||||
'startswith': lambda v, q: v.startswith(q),
|
||||
'istartswith': lambda v, q: v.lower().startswith(q),
|
||||
'endswith': lambda v, q: v.endswith(q),
|
||||
'iendswith': lambda v, q: v.lower().endswith(q),
|
||||
'exists': lambda v, q: v is not None if q else v is None,
|
||||
'regex': lambda v, q: re.match(q, v),
|
||||
'iregex': lambda v, q: re.match(q, v, flags=re.IGNORECASE),
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@ class PlexObject(object):
|
|||
in, the key will be translated to /library/metadata/<key>. This allows
|
||||
fetching an item only knowing its key-id.
|
||||
cls (:class:`~plexapi.base.PlexObject`): If you know the class of the
|
||||
items to be fetched, passing this in will help the parser ensure
|
||||
items to be fetched, passing this in will help the parser ensure
|
||||
it only returns those items. By default we convert the xml elements
|
||||
with the best guess PlexObjects based on tag and type attrs.
|
||||
etag (str): Only fetch items with the specified tag.
|
||||
|
@ -166,7 +166,9 @@ class PlexObject(object):
|
|||
def reload(self, safe=False):
|
||||
""" Reload the data for this object from self.key. """
|
||||
if not self.key:
|
||||
if safe: return None
|
||||
if safe:
|
||||
return None
|
||||
|
||||
raise Unsupported('Cannot reload an object not built from a URL.')
|
||||
self._initpath = self.key
|
||||
data = self._server.query(self.key)
|
||||
|
@ -234,6 +236,14 @@ class PlexObject(object):
|
|||
def _loadData(self, data):
|
||||
raise NotImplementedError('Abstract method not implemented.')
|
||||
|
||||
def delete(self):
|
||||
try:
|
||||
return self._server.query(self.key, method=self._server._session.delete)
|
||||
except BadRequest:
|
||||
log.error('Failed to delete %s. This could be because you havnt allowed '
|
||||
'items to be deleted' % self.key)
|
||||
raise
|
||||
|
||||
|
||||
class PlexPartialObject(PlexObject):
|
||||
""" Not all objects in the Plex listings return the complete list of elements
|
||||
|
@ -319,6 +329,15 @@ class PlexPartialObject(PlexObject):
|
|||
""" Returns the :class:`~plexapi.library.LibrarySection` this item belongs to. """
|
||||
return self._server.library.sectionByID(self.librarySectionID)
|
||||
|
||||
def delete(self):
|
||||
"""Delete a media elemeent. This has to be enabled under settings > server > library in plex webui."""
|
||||
try:
|
||||
return self._server.query(self.key, method=self._server._session.delete)
|
||||
except BadRequest: # pragma: no cover
|
||||
log.error('Failed to delete %s. This could be because you havnt allowed '
|
||||
'items to be deleted' % self.key)
|
||||
raise
|
||||
|
||||
|
||||
class Playable(object):
|
||||
""" This is a general place to store functions specific to media that is Playable.
|
||||
|
@ -395,7 +414,7 @@ class Playable(object):
|
|||
def download(self, savepath=None, keep_orginal_name=False, **kwargs):
|
||||
""" Downloads this items media to the specified location. Returns a list of
|
||||
filepaths that have been saved to disk.
|
||||
|
||||
|
||||
Parameters:
|
||||
savepath (str): Title of the track to return.
|
||||
keep_orginal_name (bool): Set True to keep the original filename as stored in
|
||||
|
|
|
@ -180,6 +180,16 @@ class LibrarySection(PlexObject):
|
|||
self.updatedAt = utils.toDatetime(data.attrib.get('updatedAt'))
|
||||
self.uuid = data.attrib.get('uuid')
|
||||
|
||||
def delete(self):
|
||||
"""Delete a library section."""
|
||||
try:
|
||||
return self._server.query('/library/sections/%s' % self.key, method=self._server._session.delete)
|
||||
except BadRequest: # pragma: no cover
|
||||
msg = 'Failed to delete library %s' % self.key
|
||||
msg += 'You may need to allow this permission in your Plex settings.'
|
||||
log.error(msg)
|
||||
raise
|
||||
|
||||
def get(self, title):
|
||||
""" Returns the media item with the specified title.
|
||||
|
||||
|
|
|
@ -47,9 +47,20 @@ def test_library_section_get_movie(pms): # fix me
|
|||
assert m
|
||||
|
||||
|
||||
def test_library_section_delete(monkeypatch, pms):
|
||||
m = pms.library.section('Movies')
|
||||
monkeypatch.delattr("requests.sessions.Session.request")
|
||||
try:
|
||||
m.delete()
|
||||
except AttributeError:
|
||||
pass # this will always raise because there is no request anymore.
|
||||
|
||||
|
||||
def test_library_fetchItem(pms):
|
||||
m = pms.library.fetchItem('/library/metadata/1')
|
||||
f = pms.library.fetchItem(1)
|
||||
assert m.title == '16 Blocks'
|
||||
assert f == m
|
||||
|
||||
|
||||
def test_library_onDeck(pms):
|
||||
|
|
|
@ -19,7 +19,7 @@ def test_server_attr(pms):
|
|||
#assert pms.session == <requests.sessions.Session object at 0x029A5E10>
|
||||
assert pms._token == os.environ.get('PLEX_TEST_TOKEN') or CONFIG.get('authentication.server_token')
|
||||
assert pms.transcoderActiveVideoSessions == 0
|
||||
# assert str(pms.updatedAt.date()) == '2017-01-20'
|
||||
#assert str(pms.updatedAt.date()) == '2017-01-20'
|
||||
assert pms.version == '1.3.3.3148-b38628e'
|
||||
|
||||
|
||||
|
|
|
@ -89,13 +89,14 @@ def test_utils_cast():
|
|||
|
||||
|
||||
def test_utils_download(a_episode):
|
||||
# this files is really getting downloaded..
|
||||
without_session = utils.download(a_episode.getStreamURL(),
|
||||
filename=a_episode.location, mocked=True)
|
||||
filename=a_episode.location,
|
||||
mocked=True)
|
||||
assert without_session
|
||||
with_session = utils.download(a_episode.getStreamURL(),
|
||||
filename=a_episode.location, session=a_episode._server._session,
|
||||
mocked=True)
|
||||
filename=a_episode.location,
|
||||
session=a_episode._server._session,
|
||||
mocked=True)
|
||||
assert with_session
|
||||
img = utils.download(a_episode.thumbUrl, filename=a_episode.title, mocked=True)
|
||||
assert img
|
||||
|
|
|
@ -7,6 +7,16 @@ def test_video_Movie(a_movie_section):
|
|||
m = a_movie_section.get('Cars')
|
||||
assert m.title == 'Cars'
|
||||
|
||||
def test_video_Movie_delete(monkeypatch, pms):
|
||||
m = pms.library.section('Movies').get('16 blocks')
|
||||
monkeypatch.delattr("requests.sessions.Session.request")
|
||||
try:
|
||||
m.delete()
|
||||
except AttributeError:
|
||||
# Silence this because it will always raise beause of monkeypatch
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def test_video_Movie_getStreamURL(a_movie):
|
||||
assert a_movie.getStreamURL() == "http://138.68.157.5:32400/video/:/transcode/universal/start.m3u8?X-Plex-Platform=Chrome©ts=1&mediaIndex=0&offset=0&path=%2Flibrary%2Fmetadata%2F1&X-Plex-Token={0}".format(os.environ.get('PLEX_TEST_TOKEN'))
|
||||
|
@ -359,9 +369,9 @@ def test_video_Show_isWatched(a_show):
|
|||
assert not a_show.isWatched
|
||||
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_video_Show_section(a_show): # BROKEN!
|
||||
show = a_show.section()
|
||||
def test_video_Show_section(a_show):
|
||||
section = a_show.section()
|
||||
assert section.title == 'TV Shows'
|
||||
|
||||
|
||||
def test_video_Episode(a_show):
|
||||
|
|
Loading…
Add table
Reference in a new issue