|
12 | 12 | from music_assistant_models.media_items import UniqueList
|
13 | 13 |
|
14 | 14 | from music_assistant.providers.audiobookshelf.abs_schema import (
|
15 |
| - ABSAudioBook, |
16 | 15 | ABSDeviceInfo,
|
17 |
| - ABSLibrariesItemsResponse, |
| 16 | + ABSLibrariesItemsMinifiedBookResponse, |
| 17 | + ABSLibrariesItemsMinifiedPodcastResponse, |
18 | 18 | ABSLibrariesResponse,
|
19 | 19 | ABSLibrary,
|
20 |
| - ABSLibraryItem, |
| 20 | + ABSLibraryItemExpandedBook, |
| 21 | + ABSLibraryItemExpandedPodcast, |
| 22 | + ABSLibraryItemMinifiedBook, |
| 23 | + ABSLibraryItemMinifiedPodcast, |
21 | 24 | ABSLoginResponse,
|
22 | 25 | ABSMediaProgress,
|
23 | 26 | ABSPlaybackSession,
|
24 | 27 | ABSPlaybackSessionExpanded,
|
25 | 28 | ABSPlayRequest,
|
26 |
| - ABSPodcast, |
27 | 29 | ABSSessionsResponse,
|
28 | 30 | ABSSessionUpdate,
|
29 | 31 | ABSUser,
|
@@ -163,43 +165,54 @@ async def sync(self) -> None:
|
163 | 165 | self.podcast_libraries.append(library)
|
164 | 166 | self.user = await self.get_authenticated_user()
|
165 | 167 |
|
166 |
| - async def get_all_podcasts(self) -> AsyncGenerator[ABSPodcast]: |
| 168 | + async def get_all_podcasts(self) -> AsyncGenerator[ABSLibraryItemExpandedPodcast]: |
167 | 169 | """Get all available podcasts."""
|
168 | 170 | for library in self.podcast_libraries:
|
169 | 171 | async for podcast in self.get_all_podcasts_by_library(library):
|
170 | 172 | yield podcast
|
171 | 173 |
|
172 | 174 | async def _get_lib_items(self, lib: ABSLibrary) -> AsyncGenerator[bytes]:
|
173 |
| - """Get library items with pagination.""" |
| 175 | + """Get library items with pagination. |
| 176 | +
|
| 177 | + Note: |
| 178 | + - minified=1 -> minified items. However, there appears to be |
| 179 | + a bug in abs, so we always get minified items. Still there for |
| 180 | + consistency |
| 181 | + - collapseseries=0 -> even if books are part of a series, they will be single items |
| 182 | + """ |
174 | 183 | page_cnt = 0
|
175 | 184 | while True:
|
176 | 185 | data = await self._get(
|
177 |
| - f"/libraries/{lib.id_}/items", |
| 186 | + f"/libraries/{lib.id_}/items?minified=1&collapseseries=0", |
178 | 187 | params={"limit": LIMIT_ITEMS_PER_PAGE, "page": page_cnt},
|
179 | 188 | )
|
180 | 189 | page_cnt += 1
|
181 | 190 | yield data
|
182 | 191 |
|
183 |
| - async def get_all_podcasts_by_library(self, lib: ABSLibrary) -> AsyncGenerator[ABSPodcast]: |
| 192 | + async def get_all_podcasts_by_library( |
| 193 | + self, lib: ABSLibrary |
| 194 | + ) -> AsyncGenerator[ABSLibraryItemExpandedPodcast]: |
184 | 195 | """Get all podcasts in a library."""
|
185 | 196 | async for podcast_data in self._get_lib_items(lib):
|
186 |
| - podcast_list = ABSLibrariesItemsResponse.from_json(podcast_data).results |
| 197 | + podcast_list = ABSLibrariesItemsMinifiedPodcastResponse.from_json(podcast_data).results |
187 | 198 | if not podcast_list: # [] if page exceeds
|
188 | 199 | return
|
189 | 200 |
|
190 |
| - async def _get_id(plist: list[ABSLibraryItem] = podcast_list) -> AsyncGenerator[str]: |
| 201 | + async def _get_id( |
| 202 | + plist: list[ABSLibraryItemMinifiedPodcast] = podcast_list, |
| 203 | + ) -> AsyncGenerator[str]: |
191 | 204 | for entry in plist:
|
192 | 205 | yield entry.id_
|
193 | 206 |
|
194 | 207 | async for id_ in _get_id():
|
195 | 208 | podcast = await self.get_podcast(id_)
|
196 | 209 | yield podcast
|
197 | 210 |
|
198 |
| - async def get_podcast(self, id_: str) -> ABSPodcast: |
| 211 | + async def get_podcast(self, id_: str) -> ABSLibraryItemExpandedPodcast: |
199 | 212 | """Get a single Podcast by ID."""
|
200 | 213 | # this endpoint gives more podcast extra data
|
201 | 214 | data = await self._get(f"items/{id_}?expanded=1")
|
202 |
| - return ABSPodcast.from_json(data) |
| 215 | + return ABSLibraryItemExpandedPodcast.from_json(data) |
203 | 216 |
|
204 | 217 | async def _get_progress_ms(
|
205 | 218 | self,
|
@@ -288,32 +301,36 @@ async def update_audiobook_progress(
|
288 | 301 | endpoint = f"me/progress/{audiobook_id}"
|
289 | 302 | await self._update_progress(endpoint, progress_s, duration_s, is_finished)
|
290 | 303 |
|
291 |
| - async def get_all_audiobooks(self) -> AsyncGenerator[ABSAudioBook]: |
| 304 | + async def get_all_audiobooks(self) -> AsyncGenerator[ABSLibraryItemExpandedBook]: |
292 | 305 | """Get all audiobooks."""
|
293 | 306 | for library in self.audiobook_libraries:
|
294 | 307 | async for book in self.get_all_audiobooks_by_library(library):
|
295 | 308 | yield book
|
296 | 309 |
|
297 |
| - async def get_all_audiobooks_by_library(self, lib: ABSLibrary) -> AsyncGenerator[ABSAudioBook]: |
| 310 | + async def get_all_audiobooks_by_library( |
| 311 | + self, lib: ABSLibrary |
| 312 | + ) -> AsyncGenerator[ABSLibraryItemExpandedBook]: |
298 | 313 | """Get all Audiobooks in a library."""
|
299 | 314 | async for audiobook_data in self._get_lib_items(lib):
|
300 |
| - audiobook_list = ABSLibrariesItemsResponse.from_json(audiobook_data).results |
| 315 | + audiobook_list = ABSLibrariesItemsMinifiedBookResponse.from_json(audiobook_data).results |
301 | 316 | if not audiobook_list: # [] if page exceeds
|
302 | 317 | return
|
303 | 318 |
|
304 |
| - async def _get_id(alist: list[ABSLibraryItem] = audiobook_list) -> AsyncGenerator[str]: |
| 319 | + async def _get_id( |
| 320 | + alist: list[ABSLibraryItemMinifiedBook] = audiobook_list, |
| 321 | + ) -> AsyncGenerator[str]: |
305 | 322 | for entry in alist:
|
306 | 323 | yield entry.id_
|
307 | 324 |
|
308 | 325 | async for id_ in _get_id():
|
309 | 326 | audiobook = await self.get_audiobook(id_)
|
310 | 327 | yield audiobook
|
311 | 328 |
|
312 |
| - async def get_audiobook(self, id_: str) -> ABSAudioBook: |
| 329 | + async def get_audiobook(self, id_: str) -> ABSLibraryItemExpandedBook: |
313 | 330 | """Get a single Audiobook by ID."""
|
314 | 331 | # this endpoint gives more audiobook extra data
|
315 | 332 | audiobook = await self._get(f"items/{id_}?expanded=1")
|
316 |
| - return ABSAudioBook.from_json(audiobook) |
| 333 | + return ABSLibraryItemExpandedBook.from_json(audiobook) |
317 | 334 |
|
318 | 335 | async def get_playback_session_podcast(
|
319 | 336 | self, device_info: ABSDeviceInfo, podcast_id: str, episode_id: str
|
|
0 commit comments