mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-22 11:43:13 +00:00
Merge branch 'master' into better_cli
This commit is contained in:
commit
c9d1e222a6
7 changed files with 49 additions and 11 deletions
|
@ -10,7 +10,7 @@ Python-PlexAPI
|
|||
|
||||
Overview
|
||||
--------
|
||||
Python bindings for the Plex API. Our goal is to match all capabilities of the official
|
||||
Unofficial Python bindings for the Plex API. Our goal is to match all capabilities of the official
|
||||
Plex Web Client. A few of the many features we currently support are:
|
||||
|
||||
* Navigate local or remote shared libraries.
|
||||
|
|
|
@ -550,7 +550,7 @@ class MovieSection(LibrarySection):
|
|||
Attributes:
|
||||
ALLOWED_FILTERS (list<str>): List of allowed search filters. ('unwatched',
|
||||
'duplicate', 'year', 'decade', 'genre', 'contentRating', 'collection',
|
||||
'director', 'actor', 'country', 'studio', 'resolution')
|
||||
'director', 'actor', 'country', 'studio', 'resolution', 'guid')
|
||||
ALLOWED_SORT (list<str>): List of allowed sorting keys. ('addedAt',
|
||||
'originallyAvailableAt', 'lastViewedAt', 'titleSort', 'rating',
|
||||
'mediaHeight', 'duration')
|
||||
|
@ -558,7 +558,8 @@ class MovieSection(LibrarySection):
|
|||
TYPE (str): 'movie'
|
||||
"""
|
||||
ALLOWED_FILTERS = ('unwatched', 'duplicate', 'year', 'decade', 'genre', 'contentRating',
|
||||
'collection', 'director', 'actor', 'country', 'studio', 'resolution')
|
||||
'collection', 'director', 'actor', 'country', 'studio', 'resolution',
|
||||
'guid')
|
||||
ALLOWED_SORT = ('addedAt', 'originallyAvailableAt', 'lastViewedAt', 'titleSort', 'rating',
|
||||
'mediaHeight', 'duration')
|
||||
TAG = 'Directory'
|
||||
|
@ -570,13 +571,14 @@ class ShowSection(LibrarySection):
|
|||
|
||||
Attributes:
|
||||
ALLOWED_FILTERS (list<str>): List of allowed search filters. ('unwatched',
|
||||
'year', 'genre', 'contentRating', 'network', 'collection')
|
||||
'year', 'genre', 'contentRating', 'network', 'collection', 'guid')
|
||||
ALLOWED_SORT (list<str>): List of allowed sorting keys. ('addedAt', 'lastViewedAt',
|
||||
'originallyAvailableAt', 'titleSort', 'rating', 'unwatched')
|
||||
TAG (str): 'Directory'
|
||||
TYPE (str): 'show'
|
||||
"""
|
||||
ALLOWED_FILTERS = ('unwatched', 'year', 'genre', 'contentRating', 'network', 'collection')
|
||||
ALLOWED_FILTERS = ('unwatched', 'year', 'genre', 'contentRating', 'network', 'collection',
|
||||
'guid')
|
||||
ALLOWED_SORT = ('addedAt', 'lastViewedAt', 'originallyAvailableAt', 'titleSort',
|
||||
'rating', 'unwatched')
|
||||
TAG = 'Directory'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from plexapi import utils
|
||||
from plexapi import log, utils
|
||||
from plexapi.base import PlexObject
|
||||
from plexapi.exceptions import BadRequest
|
||||
from plexapi.utils import cast
|
||||
|
@ -52,6 +52,15 @@ class Media(PlexObject):
|
|||
self.width = cast(int, data.attrib.get('width'))
|
||||
self.parts = self.findItems(data, MediaPart)
|
||||
|
||||
def delete(self):
|
||||
part = self._initpath + '/media/%s' % self.id
|
||||
try:
|
||||
return self._server.query(part, method=self._server._session.delete)
|
||||
except BadRequest:
|
||||
log.error("Failed to delete %s. This could be because you havn't allowed "
|
||||
"items to be deleted" % part)
|
||||
raise
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class MediaPart(PlexObject):
|
||||
|
|
|
@ -300,7 +300,7 @@ class PlexServer(PlexObject):
|
|||
""" Install the newest version of Plex Media Server. """
|
||||
# We can add this but dunno how useful this is since it sometimes
|
||||
# requires user action using a gui.
|
||||
part = 'updater/apply'
|
||||
part = '/updater/apply'
|
||||
release = self.check_for_update(force=True, download=True)
|
||||
if release and release.version != self.version:
|
||||
# figure out what method this is..
|
||||
|
|
|
@ -242,7 +242,8 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
|
|||
chunksize (int): What chunksize read/write at the time.
|
||||
mocked (bool): Helper to do evertything except write the file.
|
||||
unpack (bool): Unpack the zip file.
|
||||
showstatus (bool): Display progressbar.
|
||||
showstatus(bool): Display a progressbar.
|
||||
|
||||
Example:
|
||||
>>> download(a_episode.getStreamURL(), a_episode.location)
|
||||
/path/to/file
|
||||
|
@ -255,10 +256,12 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
|
|||
# make sure the savepath directory exists
|
||||
savepath = savepath or os.getcwd()
|
||||
compat.makedirs(savepath, exist_ok=True)
|
||||
|
||||
# try getting filename from header if not specified in arguments (used for logs, db)
|
||||
if not filename and response.headers.get('Content-Disposition'):
|
||||
filename = re.findall(r'filename=\"(.+)\"', response.headers.get('Content-Disposition'))
|
||||
filename = filename[0] if filename[0] else None
|
||||
|
||||
filename = os.path.basename(filename)
|
||||
fullpath = os.path.join(savepath, filename)
|
||||
# append file.ext from content-type if not already there
|
||||
|
@ -267,15 +270,17 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
|
|||
contenttype = response.headers.get('content-type')
|
||||
if contenttype and 'image' in contenttype:
|
||||
fullpath += contenttype.split('/')[1]
|
||||
|
||||
# check this is a mocked download (testing)
|
||||
if mocked:
|
||||
log.debug('Mocked download %s', fullpath)
|
||||
return fullpath
|
||||
|
||||
# save the file to disk
|
||||
log.info('Downloading: %s', fullpath)
|
||||
if showstatus:
|
||||
bar = tqdm(desc=filename, unit='B', unit_scale=True,
|
||||
total=int(response.headers.get('content-length', 0)))
|
||||
total = int(response.headers.get('content-length', 0))
|
||||
bar = tqdm(unit='B', unit_scale=True, total=total, desc=filename)
|
||||
|
||||
with open(fullpath, 'wb') as handle:
|
||||
for chunk in response.iter_content(chunk_size=chunksize):
|
||||
|
|
|
@ -44,7 +44,7 @@ class Video(PlexPartialObject):
|
|||
@property
|
||||
def isWatched(self):
|
||||
""" Returns True if this video is watched. """
|
||||
return bool(self.viewCount > 0)
|
||||
return bool(self.viewCount > 0) if self.viewCount else False
|
||||
|
||||
@property
|
||||
def thumbUrl(self):
|
||||
|
|
22
tools/plex-alertlistener.py
Executable file
22
tools/plex-alertlistener.py
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Listen to plex alerts and print them to the console.
|
||||
Because we're using print as a function, example only works in Python3.
|
||||
"""
|
||||
import time
|
||||
from plexapi.server import PlexServer
|
||||
|
||||
|
||||
def _print(msg):
|
||||
print(msg)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
plex = PlexServer()
|
||||
listener = plex.startAlertListener(_print)
|
||||
while True:
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
listener.stop()
|
Loading…
Reference in a new issue