mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-10 06:04:15 +00:00
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:
parent
3b1dce7a8d
commit
6cacc4a55a
4 changed files with 58 additions and 23 deletions
|
@ -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§ionID=%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):
|
||||
|
|
|
@ -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. """
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
Loading…
Reference in a new issue