feat: add data models for search results
This commit is contained in:
@@ -5,6 +5,7 @@ from .track import Track
|
||||
from .album import Album
|
||||
from .playlist import Playlist, PlaylistItem, TrackStub, TracksPage, Owner, UserMini
|
||||
from .artist import Artist
|
||||
from .search import SearchResult, SearchTracksPage, SearchAlbumsPage, SearchArtistsPage, SearchPlaylistsPage
|
||||
|
||||
__all__ = [
|
||||
"Image",
|
||||
@@ -20,4 +21,9 @@ __all__ = [
|
||||
"Owner",
|
||||
"UserMini",
|
||||
"Artist",
|
||||
"SearchResult",
|
||||
"SearchTracksPage",
|
||||
"SearchAlbumsPage",
|
||||
"SearchArtistsPage",
|
||||
"SearchPlaylistsPage",
|
||||
]
|
||||
179
deezspot/models/librespot/search.py
Normal file
179
deezspot/models/librespot/search.py
Normal file
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional, Dict, Any, List
|
||||
|
||||
from .track import Track
|
||||
from .album import Album
|
||||
from .artist import Artist
|
||||
from .playlist import Playlist
|
||||
from .types import _int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SearchTracksPage:
|
||||
limit: int = 0
|
||||
offset: int = 0
|
||||
total: int = 0
|
||||
items: List[Track] = field(default_factory=list)
|
||||
|
||||
@staticmethod
|
||||
def from_dict(obj: Any) -> "SearchTracksPage":
|
||||
if not isinstance(obj, dict):
|
||||
return SearchTracksPage()
|
||||
items: List[Track] = []
|
||||
for it in obj.get("items", []) or []:
|
||||
if isinstance(it, dict):
|
||||
items.append(Track.from_dict(it))
|
||||
return SearchTracksPage(
|
||||
limit=_int(obj.get("limit")) or 0,
|
||||
offset=_int(obj.get("offset")) or 0,
|
||||
total=_int(obj.get("total")) or len(items),
|
||||
items=items,
|
||||
)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"limit": self.limit,
|
||||
"offset": self.offset,
|
||||
"total": self.total,
|
||||
"items": [it.to_dict() for it in (self.items or [])]
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class SearchAlbumsPage:
|
||||
limit: int = 0
|
||||
offset: int = 0
|
||||
total: int = 0
|
||||
items: List[Album] = field(default_factory=list)
|
||||
|
||||
@staticmethod
|
||||
def from_dict(obj: Any) -> "SearchAlbumsPage":
|
||||
if not isinstance(obj, dict):
|
||||
return SearchAlbumsPage()
|
||||
items: List[Album] = []
|
||||
for it in obj.get("items", []) or []:
|
||||
if isinstance(it, dict):
|
||||
items.append(Album.from_dict(it))
|
||||
return SearchAlbumsPage(
|
||||
limit=_int(obj.get("limit")) or 0,
|
||||
offset=_int(obj.get("offset")) or 0,
|
||||
total=_int(obj.get("total")) or len(items),
|
||||
items=items,
|
||||
)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"limit": self.limit,
|
||||
"offset": self.offset,
|
||||
"total": self.total,
|
||||
"items": [it.to_dict() for it in (self.items or [])]
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class SearchArtistsPage:
|
||||
limit: int = 0
|
||||
offset: int = 0
|
||||
total: int = 0
|
||||
items: List[Artist] = field(default_factory=list)
|
||||
|
||||
@staticmethod
|
||||
def from_dict(obj: Any) -> "SearchArtistsPage":
|
||||
if not isinstance(obj, dict):
|
||||
return SearchArtistsPage()
|
||||
items: List[Artist] = []
|
||||
for it in obj.get("items", []) or []:
|
||||
if isinstance(it, dict):
|
||||
items.append(Artist.from_dict(it))
|
||||
return SearchArtistsPage(
|
||||
limit=_int(obj.get("limit")) or 0,
|
||||
offset=_int(obj.get("offset")) or 0,
|
||||
total=_int(obj.get("total")) or len(items),
|
||||
items=items,
|
||||
)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"limit": self.limit,
|
||||
"offset": self.offset,
|
||||
"total": self.total,
|
||||
"items": [it.to_dict() for it in (self.items or [])]
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class SearchPlaylistsPage:
|
||||
limit: int = 0
|
||||
offset: int = 0
|
||||
total: int = 0
|
||||
items: List[Playlist] = field(default_factory=list)
|
||||
|
||||
@staticmethod
|
||||
def from_dict(obj: Any) -> "SearchPlaylistsPage":
|
||||
if not isinstance(obj, dict):
|
||||
return SearchPlaylistsPage()
|
||||
items: List[Playlist] = []
|
||||
for it in obj.get("items", []) or []:
|
||||
if isinstance(it, dict):
|
||||
items.append(Playlist.from_dict(it))
|
||||
return SearchPlaylistsPage(
|
||||
limit=_int(obj.get("limit")) or 0,
|
||||
offset=_int(obj.get("offset")) or 0,
|
||||
total=_int(obj.get("total")) or len(items),
|
||||
items=items,
|
||||
)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"limit": self.limit,
|
||||
"offset": self.offset,
|
||||
"total": self.total,
|
||||
"items": [it.to_dict() for it in (self.items or [])]
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class SearchResult:
|
||||
query: Optional[str] = None
|
||||
tracks: Optional[SearchTracksPage] = None
|
||||
albums: Optional[SearchAlbumsPage] = None
|
||||
artists: Optional[SearchArtistsPage] = None
|
||||
playlists: Optional[SearchPlaylistsPage] = None
|
||||
# raw passthrough for unsupported sections (e.g., shows, episodes)
|
||||
other: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@staticmethod
|
||||
def from_dict(obj: Any) -> "SearchResult":
|
||||
if not isinstance(obj, dict):
|
||||
return SearchResult()
|
||||
tracks = SearchTracksPage.from_dict(obj.get("tracks", {})) if isinstance(obj.get("tracks"), dict) else None
|
||||
albums = SearchAlbumsPage.from_dict(obj.get("albums", {})) if isinstance(obj.get("albums"), dict) else None
|
||||
artists = SearchArtistsPage.from_dict(obj.get("artists", {})) if isinstance(obj.get("artists"), dict) else None
|
||||
playlists = SearchPlaylistsPage.from_dict(obj.get("playlists", {})) if isinstance(obj.get("playlists"), dict) else None
|
||||
known = {k for k in ("query", "tracks", "albums", "artists", "playlists")}
|
||||
other = {k: v for k, v in obj.items() if k not in known}
|
||||
return SearchResult(
|
||||
query=obj.get("query"),
|
||||
tracks=tracks,
|
||||
albums=albums,
|
||||
artists=artists,
|
||||
playlists=playlists,
|
||||
other=other,
|
||||
)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
out: Dict[str, Any] = {}
|
||||
if self.query is not None:
|
||||
out["query"] = self.query
|
||||
if self.tracks is not None:
|
||||
out["tracks"] = self.tracks.to_dict()
|
||||
if self.albums is not None:
|
||||
out["albums"] = self.albums.to_dict()
|
||||
if self.artists is not None:
|
||||
out["artists"] = self.artists.to_dict()
|
||||
if self.playlists is not None:
|
||||
out["playlists"] = self.playlists.to_dict()
|
||||
out.update(self.other or {})
|
||||
return out
|
||||
Reference in New Issue
Block a user