Rockbox open source high quality audio player as a Music Player Daemon
mpris
rockbox
mpd
libadwaita
audio
rust
zig
deno
1"""Active playlist (queue) management."""
2
3from __future__ import annotations
4
5from ..transport import HttpTransport
6from ..types import InsertPosition, Playlist
7from ._fragments import TRACK_FIELDS
8
9
10class PlaylistApi:
11 def __init__(self, http: HttpTransport) -> None:
12 self._http = http
13
14 async def current(self) -> Playlist:
15 data = await self._http.execute(
16 f"{TRACK_FIELDS} query CurrentPlaylist {{ playlistGetCurrent {{ "
17 "amount index maxPlaylistSize firstIndex "
18 "lastInsertPos seed lastShuffledStart "
19 "tracks { ...TrackFields } } }}"
20 )
21 return Playlist.model_validate(data["playlistGetCurrent"])
22
23 async def amount(self) -> int:
24 data = await self._http.execute("query PlaylistAmount { playlistAmount }")
25 return int(data["playlistAmount"])
26
27 # --- queue mutations -----------------------------------------------
28
29 async def insert_tracks(
30 self,
31 paths: list[str],
32 position: InsertPosition = InsertPosition.NEXT,
33 playlist_id: str | None = None,
34 ) -> None:
35 """Insert track paths or IDs into the queue."""
36 await self._http.execute(
37 "mutation InsertTracks($playlistId: String, $position: Int!, $tracks: [String!]!) "
38 "{ insertTracks(playlistId: $playlistId, position: $position, tracks: $tracks) }",
39 {"playlistId": playlist_id, "position": int(position), "tracks": paths},
40 )
41
42 async def insert_directory(
43 self,
44 directory: str,
45 position: InsertPosition = InsertPosition.LAST,
46 playlist_id: str | None = None,
47 ) -> None:
48 await self._http.execute(
49 "mutation InsertDirectory($playlistId: String, $position: Int!, $directory: String!) "
50 "{ insertDirectory(playlistId: $playlistId, "
51 "position: $position, directory: $directory) }",
52 {"playlistId": playlist_id, "position": int(position), "directory": directory},
53 )
54
55 async def insert_album(
56 self, album_id: str, position: InsertPosition = InsertPosition.LAST
57 ) -> None:
58 await self._http.execute(
59 "mutation InsertAlbum($albumId: String!, $position: Int!) "
60 "{ insertAlbum(albumId: $albumId, position: $position) }",
61 {"albumId": album_id, "position": int(position)},
62 )
63
64 async def remove_track(self, index: int) -> None:
65 await self._http.execute(
66 "mutation RemoveTrack($index: Int!) { playlistRemoveTrack(index: $index) }",
67 {"index": index},
68 )
69
70 async def clear(self) -> None:
71 await self._http.execute("mutation ClearPlaylist { playlistRemoveAllTracks }")
72
73 async def shuffle(self) -> None:
74 await self._http.execute("mutation ShufflePlaylist { shufflePlaylist }")
75
76 async def create(self, name: str, tracks: list[str]) -> None:
77 """Create and start a new temporary playlist (replaces the current queue)."""
78 await self._http.execute(
79 "mutation CreatePlaylist($name: String!, $tracks: [String!]!) "
80 "{ playlistCreate(name: $name, tracks: $tracks) }",
81 {"name": name, "tracks": tracks},
82 )
83
84 async def start(
85 self,
86 *,
87 start_index: int | None = None,
88 elapsed: int | None = None,
89 offset: int | None = None,
90 ) -> None:
91 await self._http.execute(
92 "mutation PlaylistStart($startIndex: Int, $elapsed: Int, $offset: Int) "
93 "{ playlistStart(startIndex: $startIndex, elapsed: $elapsed, offset: $offset) }",
94 {"startIndex": start_index, "elapsed": elapsed, "offset": offset},
95 )
96
97 async def resume(self) -> None:
98 await self._http.execute("mutation PlaylistResume { playlistResume }")