Add playlist title search and sorting (#782)

* Add title and sort arguments to server playlists method

* Raise NotFound when retrieving a playlist or collection

* Update tests for collection/playlist NotFound
This commit is contained in:
JonnyWong16 2021-07-26 18:45:58 -07:00 committed by GitHub
parent 3b1dce7a8d
commit 6cacc4a55a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 23 deletions

View file

@ -1405,10 +1405,14 @@ class LibrarySection(PlexObject):
Parameters:
title (str): Title of the item to return.
Raises:
:exc:`~plexapi.exceptions.NotFound`: Unable to find collection.
"""
results = self.collections(title__iexact=title)
if results:
return results[0]
try:
return self.collections(title=title, title__iexact=title)[0]
except IndexError:
raise NotFound('Unable to find collection with title "%s".' % title) from None
def collections(self, **kwargs):
""" Returns a list of collections from this library section.
@ -1430,15 +1434,19 @@ class LibrarySection(PlexObject):
Parameters:
title (str): Title of the item to return.
"""
results = self.playlists(title__iexact=title)
if results:
return results[0]
def playlists(self, **kwargs):
Raises:
:exc:`~plexapi.exceptions.NotFound`: Unable to find playlist.
"""
try:
return self.playlists(title=title, title__iexact=title)[0]
except IndexError:
raise NotFound('Unable to find playlist with title "%s".' % title) from None
def playlists(self, sort=None, **kwargs):
""" Returns a list of playlists from this library section. """
key = '/playlists?type=15&playlistType=%s&sectionID=%s' % (self.CONTENT_TYPE, self.key)
return self.fetchItems(key, **kwargs)
return self._server.playlists(
playlistType=self.CONTENT_TYPE, sectionId=self.key, sort=sort, **kwargs)
@deprecated('use "listFields" instead')
def filterFields(self, mediaType=None):

View file

@ -575,17 +575,29 @@ class PlexServer(PlexObject):
args['X-Plex-Container-Start'] += args['X-Plex-Container-Size']
return results
def playlists(self, playlistType=None):
def playlists(self, playlistType=None, sectionId=None, title=None, sort=None, **kwargs):
""" Returns a list of all :class:`~plexapi.playlist.Playlist` objects on the server.
Parameters:
playlistType (str, optional): The type of playlists to return (audio, video, photo).
Default returns all playlists.
sectionId (int, optional): The section ID (key) of the library to search within.
title (str, optional): General string query to search for. Partial string matches are allowed.
sort (str or list, optional): A string of comma separated sort fields in the format ``column:dir``.
"""
key = '/playlists'
if playlistType:
key = '%s?playlistType=%s' % (key, playlistType)
return self.fetchItems(key)
args = {}
if playlistType is not None:
args['playlistType'] = playlistType
if sectionId is not None:
args['sectionID'] = sectionId
if title is not None:
args['title'] = title
if sort is not None:
# TODO: Automatically retrieve and validate sort field similar to LibrarySection.search()
args['sort'] = sort
key = '/playlists%s' % utils.joinArgs(args)
return self.fetchItems(key, **kwargs)
def playlist(self, title):
""" Returns the :class:`~plexapi.client.Playlist` that matches the specified title.
@ -594,9 +606,12 @@ class PlexServer(PlexObject):
title (str): Title of the playlist to return.
Raises:
:exc:`~plexapi.exceptions.NotFound`: Invalid playlist title.
:exc:`~plexapi.exceptions.NotFound`: Unable to find playlist.
"""
return self.fetchItem('/playlists', title=title)
try:
return self.playlists(title=title, title__iexact=title)[0]
except IndexError:
raise NotFound('Unable to find playlist with title "%s".' % title) from None
def optimizedItems(self, removeAll=None):
""" Returns list of all :class:`~plexapi.media.Optimized` objects connected to server. """

View file

@ -276,9 +276,9 @@ def photo(photoalbum):
@pytest.fixture()
def collection(plex, movies, movie):
c = movies.collection("Test Collection")
if c: return c
else:
try:
return movies.collection("Test Collection")
except NotFound:
return plex.createCollection(
title="Test Collection",
section=movies,
@ -288,9 +288,9 @@ def collection(plex, movies, movie):
@pytest.fixture()
def playlist(plex, tvshows, season):
p = tvshows.playlist("Test Playlist")
if p: return p
else:
try:
return tvshows.playlist("Test Playlist")
except NotFound:
return plex.createPlaylist(
title="Test Playlist",
items=season.episodes()[:3]

View file

@ -207,6 +207,11 @@ def test_library_MovieSection_collections(movies, movie):
collection.delete()
def test_library_MovieSection_collection_exception(movies):
with pytest.raises(NotFound):
movies.collection("Does Not Exists")
def test_library_ShowSection_all(tvshows):
assert len(tvshows.all(title__iexact="The 100"))
@ -241,10 +246,17 @@ def test_library_ShowSection_playlists(tvshows, show):
assert playlist in playlists
p = tvshows.playlist(playlist.title)
assert playlist == p
playlists = tvshows.playlists(title="test_", sort="mediaCount:asc")
assert playlist in playlists
finally:
playlist.delete()
def test_library_ShowSection_playlist_exception(tvshows):
with pytest.raises(NotFound):
tvshows.playlist("Does Not Exists")
def test_library_MusicSection_albums(music):
assert len(music.albums())