Skip to content

Commit c9d1e22

Browse files
authored
Merge branch 'master' into better_cli
2 parents 569e4d3 + 484461b commit c9d1e22

File tree

7 files changed

+49
-11
lines changed

7 files changed

+49
-11
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Python-PlexAPI
1010

1111
Overview
1212
--------
13-
Python bindings for the Plex API. Our goal is to match all capabilities of the official
13+
Unofficial Python bindings for the Plex API. Our goal is to match all capabilities of the official
1414
Plex Web Client. A few of the many features we currently support are:
1515

1616
* Navigate local or remote shared libraries.

plexapi/library.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,15 +550,16 @@ class MovieSection(LibrarySection):
550550
Attributes:
551551
ALLOWED_FILTERS (list<str>): List of allowed search filters. ('unwatched',
552552
'duplicate', 'year', 'decade', 'genre', 'contentRating', 'collection',
553-
'director', 'actor', 'country', 'studio', 'resolution')
553+
'director', 'actor', 'country', 'studio', 'resolution', 'guid')
554554
ALLOWED_SORT (list<str>): List of allowed sorting keys. ('addedAt',
555555
'originallyAvailableAt', 'lastViewedAt', 'titleSort', 'rating',
556556
'mediaHeight', 'duration')
557557
TAG (str): 'Directory'
558558
TYPE (str): 'movie'
559559
"""
560560
ALLOWED_FILTERS = ('unwatched', 'duplicate', 'year', 'decade', 'genre', 'contentRating',
561-
'collection', 'director', 'actor', 'country', 'studio', 'resolution')
561+
'collection', 'director', 'actor', 'country', 'studio', 'resolution',
562+
'guid')
562563
ALLOWED_SORT = ('addedAt', 'originallyAvailableAt', 'lastViewedAt', 'titleSort', 'rating',
563564
'mediaHeight', 'duration')
564565
TAG = 'Directory'
@@ -570,13 +571,14 @@ class ShowSection(LibrarySection):
570571
571572
Attributes:
572573
ALLOWED_FILTERS (list<str>): List of allowed search filters. ('unwatched',
573-
'year', 'genre', 'contentRating', 'network', 'collection')
574+
'year', 'genre', 'contentRating', 'network', 'collection', 'guid')
574575
ALLOWED_SORT (list<str>): List of allowed sorting keys. ('addedAt', 'lastViewedAt',
575576
'originallyAvailableAt', 'titleSort', 'rating', 'unwatched')
576577
TAG (str): 'Directory'
577578
TYPE (str): 'show'
578579
"""
579-
ALLOWED_FILTERS = ('unwatched', 'year', 'genre', 'contentRating', 'network', 'collection')
580+
ALLOWED_FILTERS = ('unwatched', 'year', 'genre', 'contentRating', 'network', 'collection',
581+
'guid')
580582
ALLOWED_SORT = ('addedAt', 'lastViewedAt', 'originallyAvailableAt', 'titleSort',
581583
'rating', 'unwatched')
582584
TAG = 'Directory'

plexapi/media.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -*- coding: utf-8 -*-
2-
from plexapi import utils
2+
from plexapi import log, utils
33
from plexapi.base import PlexObject
44
from plexapi.exceptions import BadRequest
55
from plexapi.utils import cast
@@ -52,6 +52,15 @@ def _loadData(self, data):
5252
self.width = cast(int, data.attrib.get('width'))
5353
self.parts = self.findItems(data, MediaPart)
5454

55+
def delete(self):
56+
part = self._initpath + '/media/%s' % self.id
57+
try:
58+
return self._server.query(part, method=self._server._session.delete)
59+
except BadRequest:
60+
log.error("Failed to delete %s. This could be because you havn't allowed "
61+
"items to be deleted" % part)
62+
raise
63+
5564

5665
@utils.registerPlexObject
5766
class MediaPart(PlexObject):

plexapi/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ def installUpdate(self):
300300
""" Install the newest version of Plex Media Server. """
301301
# We can add this but dunno how useful this is since it sometimes
302302
# requires user action using a gui.
303-
part = 'updater/apply'
303+
part = '/updater/apply'
304304
release = self.check_for_update(force=True, download=True)
305305
if release and release.version != self.version:
306306
# figure out what method this is..

plexapi/utils.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
242242
chunksize (int): What chunksize read/write at the time.
243243
mocked (bool): Helper to do evertything except write the file.
244244
unpack (bool): Unpack the zip file.
245-
showstatus (bool): Display progressbar.
245+
showstatus(bool): Display a progressbar.
246+
246247
Example:
247248
>>> download(a_episode.getStreamURL(), a_episode.location)
248249
/path/to/file
@@ -255,10 +256,12 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
255256
# make sure the savepath directory exists
256257
savepath = savepath or os.getcwd()
257258
compat.makedirs(savepath, exist_ok=True)
259+
258260
# try getting filename from header if not specified in arguments (used for logs, db)
259261
if not filename and response.headers.get('Content-Disposition'):
260262
filename = re.findall(r'filename=\"(.+)\"', response.headers.get('Content-Disposition'))
261263
filename = filename[0] if filename[0] else None
264+
262265
filename = os.path.basename(filename)
263266
fullpath = os.path.join(savepath, filename)
264267
# 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,
267270
contenttype = response.headers.get('content-type')
268271
if contenttype and 'image' in contenttype:
269272
fullpath += contenttype.split('/')[1]
273+
270274
# check this is a mocked download (testing)
271275
if mocked:
272276
log.debug('Mocked download %s', fullpath)
273277
return fullpath
278+
274279
# save the file to disk
275280
log.info('Downloading: %s', fullpath)
276281
if showstatus:
277-
bar = tqdm(desc=filename, unit='B', unit_scale=True,
278-
total=int(response.headers.get('content-length', 0)))
282+
total = int(response.headers.get('content-length', 0))
283+
bar = tqdm(unit='B', unit_scale=True, total=total, desc=filename)
279284

280285
with open(fullpath, 'wb') as handle:
281286
for chunk in response.iter_content(chunk_size=chunksize):

plexapi/video.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def _loadData(self, data):
4444
@property
4545
def isWatched(self):
4646
""" Returns True if this video is watched. """
47-
return bool(self.viewCount > 0)
47+
return bool(self.viewCount > 0) if self.viewCount else False
4848

4949
@property
5050
def thumbUrl(self):

tools/plex-alertlistener.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Listen to plex alerts and print them to the console.
5+
Because we're using print as a function, example only works in Python3.
6+
"""
7+
import time
8+
from plexapi.server import PlexServer
9+
10+
11+
def _print(msg):
12+
print(msg)
13+
14+
15+
if __name__ == '__main__':
16+
try:
17+
plex = PlexServer()
18+
listener = plex.startAlertListener(_print)
19+
while True:
20+
time.sleep(1)
21+
except KeyboardInterrupt:
22+
listener.stop()

0 commit comments

Comments
 (0)