61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
"""
|
|
Utility methods for the Spotify query API
|
|
"""
|
|
from functools import partial
|
|
from typing import Iterable, Optional, Union
|
|
|
|
from spotify_model import Paging, SearchAlbum, SimplifiedTrack
|
|
from spotipy import Spotify
|
|
|
|
from .util import exhaust
|
|
|
|
|
|
class Query:
|
|
"Query builder for Spotify search API"
|
|
|
|
def __init__(self, query: Optional[str] = None, artist: Optional[str] = None, label: Optional[str] = None) -> None:
|
|
self.query = query
|
|
self.artist = artist
|
|
self.label = label
|
|
|
|
def __str__(self) -> str:
|
|
query_items = [
|
|
self.query,
|
|
f'artist:"{self.artist}"' if self.artist is not None else None,
|
|
f'label:"{self.label}"' if self.label is not None else None,
|
|
]
|
|
return " ".join([i for i in query_items if i is not None])
|
|
|
|
|
|
# pylint: disable=too-many-arguments
|
|
def _search(client: Spotify, query_str: str, query_type: str, item_key: str, limit: int, offset: int) -> Paging:
|
|
return Paging(**client.search(query_str, type=query_type, limit=limit, offset=offset)[item_key])
|
|
|
|
|
|
def search_albums(client: Spotify, query: Union[str, Query]) -> Iterable[SearchAlbum]:
|
|
"Retrieve albums from a search string"
|
|
|
|
query = query if isinstance(query, Query) else Query(query)
|
|
query_str = str(query)
|
|
|
|
if not query_str:
|
|
return
|
|
|
|
search_function = partial(_search, client, query_str, "album", "albums")
|
|
for item in exhaust(search_function):
|
|
yield SearchAlbum(**item)
|
|
|
|
|
|
def search_tracks(client: Spotify, query: Union[str, Query]) -> Iterable[SimplifiedTrack]:
|
|
"Retrieve tracks from a search string"
|
|
|
|
query = query if isinstance(query, Query) else Query(query)
|
|
query_str = str(query)
|
|
|
|
if not query_str:
|
|
return
|
|
|
|
search_function = partial(_search, client, query_str, "track", "tracks")
|
|
for item in exhaust(search_function):
|
|
yield SimplifiedTrack(**item)
|