Merge branch 'master' into better_cli

This commit is contained in:
Hellowlol 2017-10-01 00:46:55 +02:00 committed by GitHub
commit c9d1e222a6
7 changed files with 49 additions and 11 deletions

View file

@ -10,7 +10,7 @@ Python-PlexAPI
Overview 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: Plex Web Client. A few of the many features we currently support are:
* Navigate local or remote shared libraries. * Navigate local or remote shared libraries.

View file

@ -550,7 +550,7 @@ class MovieSection(LibrarySection):
Attributes: Attributes:
ALLOWED_FILTERS (list<str>): List of allowed search filters. ('unwatched', ALLOWED_FILTERS (list<str>): List of allowed search filters. ('unwatched',
'duplicate', 'year', 'decade', 'genre', 'contentRating', 'collection', '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', ALLOWED_SORT (list<str>): List of allowed sorting keys. ('addedAt',
'originallyAvailableAt', 'lastViewedAt', 'titleSort', 'rating', 'originallyAvailableAt', 'lastViewedAt', 'titleSort', 'rating',
'mediaHeight', 'duration') 'mediaHeight', 'duration')
@ -558,7 +558,8 @@ class MovieSection(LibrarySection):
TYPE (str): 'movie' TYPE (str): 'movie'
""" """
ALLOWED_FILTERS = ('unwatched', 'duplicate', 'year', 'decade', 'genre', 'contentRating', 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', ALLOWED_SORT = ('addedAt', 'originallyAvailableAt', 'lastViewedAt', 'titleSort', 'rating',
'mediaHeight', 'duration') 'mediaHeight', 'duration')
TAG = 'Directory' TAG = 'Directory'
@ -570,13 +571,14 @@ class ShowSection(LibrarySection):
Attributes: Attributes:
ALLOWED_FILTERS (list<str>): List of allowed search filters. ('unwatched', 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', ALLOWED_SORT (list<str>): List of allowed sorting keys. ('addedAt', 'lastViewedAt',
'originallyAvailableAt', 'titleSort', 'rating', 'unwatched') 'originallyAvailableAt', 'titleSort', 'rating', 'unwatched')
TAG (str): 'Directory' TAG (str): 'Directory'
TYPE (str): 'show' 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', ALLOWED_SORT = ('addedAt', 'lastViewedAt', 'originallyAvailableAt', 'titleSort',
'rating', 'unwatched') 'rating', 'unwatched')
TAG = 'Directory' TAG = 'Directory'

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from plexapi import utils from plexapi import log, utils
from plexapi.base import PlexObject from plexapi.base import PlexObject
from plexapi.exceptions import BadRequest from plexapi.exceptions import BadRequest
from plexapi.utils import cast from plexapi.utils import cast
@ -52,6 +52,15 @@ class Media(PlexObject):
self.width = cast(int, data.attrib.get('width')) self.width = cast(int, data.attrib.get('width'))
self.parts = self.findItems(data, MediaPart) 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 @utils.registerPlexObject
class MediaPart(PlexObject): class MediaPart(PlexObject):

View file

@ -300,7 +300,7 @@ class PlexServer(PlexObject):
""" Install the newest version of Plex Media Server. """ """ Install the newest version of Plex Media Server. """
# We can add this but dunno how useful this is since it sometimes # We can add this but dunno how useful this is since it sometimes
# requires user action using a gui. # requires user action using a gui.
part = 'updater/apply' part = '/updater/apply'
release = self.check_for_update(force=True, download=True) release = self.check_for_update(force=True, download=True)
if release and release.version != self.version: if release and release.version != self.version:
# figure out what method this is.. # figure out what method this is..

View file

@ -242,7 +242,8 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
chunksize (int): What chunksize read/write at the time. chunksize (int): What chunksize read/write at the time.
mocked (bool): Helper to do evertything except write the file. mocked (bool): Helper to do evertything except write the file.
unpack (bool): Unpack the zip file. unpack (bool): Unpack the zip file.
showstatus (bool): Display progressbar. showstatus(bool): Display a progressbar.
Example: Example:
>>> download(a_episode.getStreamURL(), a_episode.location) >>> download(a_episode.getStreamURL(), a_episode.location)
/path/to/file /path/to/file
@ -255,10 +256,12 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
# make sure the savepath directory exists # make sure the savepath directory exists
savepath = savepath or os.getcwd() savepath = savepath or os.getcwd()
compat.makedirs(savepath, exist_ok=True) compat.makedirs(savepath, exist_ok=True)
# try getting filename from header if not specified in arguments (used for logs, db) # try getting filename from header if not specified in arguments (used for logs, db)
if not filename and response.headers.get('Content-Disposition'): if not filename and response.headers.get('Content-Disposition'):
filename = re.findall(r'filename=\"(.+)\"', response.headers.get('Content-Disposition')) filename = re.findall(r'filename=\"(.+)\"', response.headers.get('Content-Disposition'))
filename = filename[0] if filename[0] else None filename = filename[0] if filename[0] else None
filename = os.path.basename(filename) filename = os.path.basename(filename)
fullpath = os.path.join(savepath, filename) fullpath = os.path.join(savepath, filename)
# append file.ext from content-type if not already there # 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') contenttype = response.headers.get('content-type')
if contenttype and 'image' in contenttype: if contenttype and 'image' in contenttype:
fullpath += contenttype.split('/')[1] fullpath += contenttype.split('/')[1]
# check this is a mocked download (testing) # check this is a mocked download (testing)
if mocked: if mocked:
log.debug('Mocked download %s', fullpath) log.debug('Mocked download %s', fullpath)
return fullpath return fullpath
# save the file to disk # save the file to disk
log.info('Downloading: %s', fullpath) log.info('Downloading: %s', fullpath)
if showstatus: 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: with open(fullpath, 'wb') as handle:
for chunk in response.iter_content(chunk_size=chunksize): for chunk in response.iter_content(chunk_size=chunksize):

View file

@ -44,7 +44,7 @@ class Video(PlexPartialObject):
@property @property
def isWatched(self): def isWatched(self):
""" Returns True if this video is watched. """ """ Returns True if this video is watched. """
return bool(self.viewCount > 0) return bool(self.viewCount > 0) if self.viewCount else False
@property @property
def thumbUrl(self): def thumbUrl(self):

22
tools/plex-alertlistener.py Executable file
View 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()