Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 123 lines 4.8 kB view raw
1"""Library: albums, artists, tracks, search, likes, scan.""" 2 3from __future__ import annotations 4 5from ..transport import HttpTransport 6from ..types import Album, Artist, SearchResults, Track 7from ._fragments import ALBUM_FIELDS, ARTIST_FIELDS, TRACK_FIELDS 8 9 10class LibraryApi: 11 def __init__(self, http: HttpTransport) -> None: 12 self._http = http 13 14 # --- albums --------------------------------------------------------- 15 16 async def albums(self) -> list[Album]: 17 data = await self._http.execute( 18 f"{ALBUM_FIELDS} query Albums " 19 "{ albums { ...AlbumFields tracks { id title path length albumArt } } }" 20 ) 21 return [Album.model_validate(a) for a in data.get("albums", [])] 22 23 async def album(self, id: str) -> Album | None: 24 data = await self._http.execute( 25 f"{TRACK_FIELDS} {ALBUM_FIELDS} " 26 "query Album($id: String!) " 27 "{ album(id: $id) { ...AlbumFields tracks { ...TrackFields } } }", 28 {"id": id}, 29 ) 30 raw = data.get("album") 31 return Album.model_validate(raw) if raw is not None else None 32 33 async def liked_albums(self) -> list[Album]: 34 data = await self._http.execute( 35 f"{ALBUM_FIELDS} query LikedAlbums {{ likedAlbums {{ ...AlbumFields }} }}" 36 ) 37 return [Album.model_validate(a) for a in data.get("likedAlbums", [])] 38 39 async def like_album(self, id: str) -> None: 40 await self._http.execute( 41 "mutation LikeAlbum($id: String!) { likeAlbum(id: $id) }", {"id": id} 42 ) 43 44 async def unlike_album(self, id: str) -> None: 45 await self._http.execute( 46 "mutation UnlikeAlbum($id: String!) { unlikeAlbum(id: $id) }", {"id": id} 47 ) 48 49 # --- artists -------------------------------------------------------- 50 51 async def artists(self) -> list[Artist]: 52 data = await self._http.execute( 53 f"{ARTIST_FIELDS} query Artists " 54 "{ artists { ...ArtistFields albums { id title albumArt year } } }" 55 ) 56 return [Artist.model_validate(a) for a in data.get("artists", [])] 57 58 async def artist(self, id: str) -> Artist | None: 59 data = await self._http.execute( 60 f"{ARTIST_FIELDS} {TRACK_FIELDS} " 61 "query Artist($id: String!) { artist(id: $id) { " 62 "...ArtistFields " 63 "albums { id title albumArt year yearString md5 artistId " 64 "tracks { id title path length } } " 65 "tracks { ...TrackFields } } }", 66 {"id": id}, 67 ) 68 raw = data.get("artist") 69 return Artist.model_validate(raw) if raw is not None else None 70 71 # --- tracks --------------------------------------------------------- 72 73 async def tracks(self) -> list[Track]: 74 data = await self._http.execute( 75 f"{TRACK_FIELDS} query Tracks {{ tracks {{ ...TrackFields }} }}" 76 ) 77 return [Track.model_validate(t) for t in data.get("tracks", [])] 78 79 async def track(self, id: str) -> Track | None: 80 data = await self._http.execute( 81 f"{TRACK_FIELDS} query Track($id: String!) " 82 "{ track(id: $id) { ...TrackFields } }", 83 {"id": id}, 84 ) 85 raw = data.get("track") 86 return Track.model_validate(raw) if raw is not None else None 87 88 async def liked_tracks(self) -> list[Track]: 89 data = await self._http.execute( 90 f"{TRACK_FIELDS} query LikedTracks {{ likedTracks {{ ...TrackFields }} }}" 91 ) 92 return [Track.model_validate(t) for t in data.get("likedTracks", [])] 93 94 async def like_track(self, id: str) -> None: 95 await self._http.execute( 96 "mutation LikeTrack($id: String!) { likeTrack(id: $id) }", {"id": id} 97 ) 98 99 async def unlike_track(self, id: str) -> None: 100 await self._http.execute( 101 "mutation UnlikeTrack($id: String!) { unlikeTrack(id: $id) }", {"id": id} 102 ) 103 104 # --- search --------------------------------------------------------- 105 106 async def search(self, term: str) -> SearchResults: 107 data = await self._http.execute( 108 f"{TRACK_FIELDS} {ALBUM_FIELDS} {ARTIST_FIELDS} " 109 "query Search($term: String!) { search(term: $term) { " 110 "artists { ...ArtistFields } " 111 "albums { ...AlbumFields } " 112 "tracks { ...TrackFields } " 113 "likedTracks { ...TrackFields } " 114 "likedAlbums { ...AlbumFields } } }", 115 {"term": term}, 116 ) 117 return SearchResults.model_validate(data.get("search") or {}) 118 119 # --- maintenance ---------------------------------------------------- 120 121 async def scan(self) -> None: 122 """Trigger a library rescan.""" 123 await self._http.execute("mutation ScanLibrary { scanLibrary }")