aioaudiobookshelf 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of aioaudiobookshelf might be problematic. Click here for more details.

@@ -6,7 +6,7 @@ from aioaudiobookshelf.client import AdminClient, SessionConfiguration, SocketCl
6
6
  from aioaudiobookshelf.exceptions import LoginError, TokenIsMissingError
7
7
  from aioaudiobookshelf.schema.calls_login import AuthorizeResponse, LoginParameters, LoginResponse
8
8
 
9
- __version__ = "0.1.4"
9
+ __version__ = "0.1.6"
10
10
 
11
11
 
12
12
  async def _get_login_response(
@@ -32,9 +32,8 @@ class BaseClient:
32
32
  self.logger = self.session_config.logger
33
33
 
34
34
  self.logger.debug(
35
- "Initialized client %s, token: %s",
35
+ "Initialized client %s",
36
36
  self.__class__.__name__,
37
- self._token,
38
37
  )
39
38
 
40
39
  self._verify_user()
@@ -3,6 +3,7 @@
3
3
  from collections.abc import AsyncGenerator
4
4
  from typing import TypeVar
5
5
 
6
+ from mashumaro.codecs.json import json_decode
6
7
  from mashumaro.mixins.json import DataClassJSONMixin
7
8
 
8
9
  from aioaudiobookshelf.client._base import BaseClient
@@ -18,6 +19,14 @@ from aioaudiobookshelf.schema.calls_library import (
18
19
  LibraryWithFilterDataResponse,
19
20
  )
20
21
  from aioaudiobookshelf.schema.library import Library, LibraryFilterData
22
+ from aioaudiobookshelf.schema.shelf import (
23
+ Shelf,
24
+ ShelfAuthors,
25
+ ShelfBook,
26
+ ShelfEpisode,
27
+ ShelfPodcast,
28
+ ShelfSeries,
29
+ )
21
30
 
22
31
  ResponseMinified = TypeVar("ResponseMinified", bound=DataClassJSONMixin)
23
32
  ResponseNormal = TypeVar("ResponseNormal", bound=DataClassJSONMixin)
@@ -147,7 +156,17 @@ class LibrariesClient(BaseClient):
147
156
  ):
148
157
  yield result
149
158
 
150
- # get library's personalized view
159
+ async def get_library_personalized_view(
160
+ self, *, library_id: str, limit: int = 10
161
+ ) -> list[ShelfBook | ShelfPodcast | ShelfAuthors | ShelfEpisode | ShelfSeries]:
162
+ """Get personalized view of library.
163
+
164
+ TODO: Add rssfeed
165
+ """
166
+ response = await self._get(
167
+ endpoint=f"/api/libraries/{library_id}/personalized", params={"limit": limit}
168
+ )
169
+ return json_decode(response, list[Shelf])
151
170
 
152
171
  async def get_library_filterdata(self, *, library_id: str) -> LibraryFilterData:
153
172
  """Get filterdata of library."""
@@ -0,0 +1,188 @@
1
+ """Schema for shelf, the response object to library's personalized view."""
2
+ # Discriminators don't work together with aliases.
3
+ # https://github.com/Fatal1ty/mashumaro/issues/254
4
+ # ruff: noqa: N815
5
+
6
+ from dataclasses import dataclass
7
+ from enum import StrEnum
8
+ from typing import Annotated
9
+
10
+ from mashumaro.types import Alias, Discriminator
11
+
12
+ from aioaudiobookshelf.schema.author import AuthorExpanded
13
+ from aioaudiobookshelf.schema.book import BookMinified
14
+
15
+ from . import _BaseModel
16
+ from .library import LibraryMediaType, _LibraryItemBase
17
+ from .podcast import PodcastEpisode, PodcastMinified
18
+ from .series import Series
19
+
20
+
21
+ class ShelfId(StrEnum):
22
+ """ShelfId."""
23
+
24
+ LISTEN_AGAIN = "listen-again"
25
+ CONTINUE_LISTENING = "continue-listening"
26
+ CONTINUE_SERIES = "continue-series"
27
+ RECOMMENDED = "recommended"
28
+ RECENTLY_ADDED = "recently-added"
29
+ EPISODES_RECENTLY_ADDED = "episodes-recently-added"
30
+ RECENT_SERIES = "recent-series"
31
+ NEWEST_AUTHORS = "newest-authors"
32
+ NEWEST_EPISODES = "newest-episodes"
33
+ DISCOVER = "discover"
34
+
35
+
36
+ @dataclass(kw_only=True)
37
+ class ShelfLibraryItemMinified(_LibraryItemBase):
38
+ """ShelfLibraryItemMinified.
39
+
40
+ Beside using type, there is another distinction on which attributes
41
+ are available based on the id. We allow ourselves the easy route
42
+ here, and just make all of them optional.
43
+ """
44
+
45
+ # episode (type) and
46
+ # id: continue-listening, listen-again, episodes-recently-added
47
+ recent_episode: Annotated[PodcastEpisode | None, Alias("recentEpisode")] = None
48
+
49
+ # id: continue-listening
50
+ progress_last_update_ms: Annotated[int | None, Alias("progressLastUpdate")] = None
51
+
52
+ # id: continue-series
53
+ previous_book_in_progress_last_update_ms: Annotated[
54
+ int | None, Alias("prevBookInProgressLastUpdate")
55
+ ] = None
56
+ # TODO: minified item has seriesSequence, which we currently ignore
57
+
58
+ # id: recommended
59
+ weight: float | None = None
60
+
61
+ # id: listen-again
62
+ finished_at_ms: Annotated[int | None, Alias("finishedAt")] = None
63
+
64
+ # This and the two subclasses are copied over from libraries, as we otherwise
65
+ # face issues with the discriminator
66
+ class Config(_LibraryItemBase.Config):
67
+ """Config."""
68
+
69
+ discriminator = Discriminator(
70
+ field="mediaType",
71
+ include_subtypes=True,
72
+ )
73
+
74
+ num_files: Annotated[int, Alias("numFiles")]
75
+ size: int
76
+
77
+
78
+ @dataclass(kw_only=True)
79
+ class LibraryItemMinifiedBook(ShelfLibraryItemMinified):
80
+ """LibraryItemMinifiedBook."""
81
+
82
+ media: BookMinified
83
+ mediaType: LibraryMediaType = LibraryMediaType.BOOK
84
+
85
+
86
+ @dataclass(kw_only=True)
87
+ class LibraryItemMinifiedPodcast(ShelfLibraryItemMinified):
88
+ """LibraryItemMinifiedPodcast."""
89
+
90
+ media: PodcastMinified
91
+ mediaType: LibraryMediaType = LibraryMediaType.PODCAST
92
+
93
+
94
+ @dataclass(kw_only=True)
95
+ class LibraryItemMinifiedBookSeriesShelf(ShelfLibraryItemMinified):
96
+ """LibraryItemMinifiedBookSeriesShelf."""
97
+
98
+ # this appears not to be around?
99
+ series_sequence: Annotated[str | int | None, Alias("seriesSequence")] = None
100
+
101
+
102
+ @dataclass(kw_only=True)
103
+ class SeriesShelf(Series):
104
+ """SeriesShelf."""
105
+
106
+ books: list[LibraryItemMinifiedBookSeriesShelf]
107
+ in_progress: Annotated[bool | None, Alias("inProgress")] = None
108
+ has_active_book: Annotated[bool | None, Alias("hasActiveBook")] = None
109
+ hide_from_continue_listening: Annotated[bool | None, Alias("hideFromContinueListening")] = None
110
+ book_in_progress_last_update_ms: Annotated[int | None, Alias("bookInProgressLastUpdate")] = None
111
+ first_book_unread: Annotated[
112
+ LibraryItemMinifiedBookSeriesShelf | None, Alias("firstBookUnread")
113
+ ] = None
114
+
115
+
116
+ class ShelfType(StrEnum):
117
+ """ShelfType."""
118
+
119
+ BOOK = "book"
120
+ SERIES = "series"
121
+ AUTHORS = "authors"
122
+ EPISODE = "episode"
123
+ PODCAST = "podcast"
124
+
125
+
126
+ @dataclass(kw_only=True)
127
+ class _ShelfBase(_BaseModel):
128
+ """Shelf."""
129
+
130
+ id_: Annotated[ShelfId | str, Alias("id")]
131
+ label: str
132
+ label_string_key: Annotated[str, Alias("labelStringKey")]
133
+ type_: Annotated[ShelfType, Alias("type")]
134
+ category: str | None = None
135
+
136
+
137
+ @dataclass(kw_only=True)
138
+ class Shelf(_ShelfBase):
139
+ """Shelf."""
140
+
141
+ class Config(_ShelfBase.Config):
142
+ """Config."""
143
+
144
+ discriminator = Discriminator(
145
+ field="type",
146
+ include_subtypes=True,
147
+ )
148
+
149
+
150
+ @dataclass(kw_only=True)
151
+ class ShelfBook(Shelf):
152
+ """ShelfBook."""
153
+
154
+ type = ShelfType.BOOK
155
+ entities: list[ShelfLibraryItemMinified]
156
+
157
+
158
+ @dataclass(kw_only=True)
159
+ class ShelfPodcast(Shelf):
160
+ """ShelfBook."""
161
+
162
+ type = ShelfType.PODCAST
163
+ entities: list[ShelfLibraryItemMinified]
164
+
165
+
166
+ @dataclass(kw_only=True)
167
+ class ShelfEpisode(Shelf):
168
+ """ShelfBook."""
169
+
170
+ type = ShelfType.EPISODE
171
+ entities: list[ShelfLibraryItemMinified]
172
+
173
+
174
+ @dataclass(kw_only=True)
175
+ class ShelfAuthors(Shelf):
176
+ """ShelfAuthor."""
177
+
178
+ type = ShelfType.AUTHORS
179
+
180
+ entities: list[AuthorExpanded]
181
+
182
+
183
+ @dataclass(kw_only=True)
184
+ class ShelfSeries(Shelf):
185
+ """ShelfSeries."""
186
+
187
+ type = ShelfType.SERIES
188
+ entities: list[SeriesShelf]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: aioaudiobookshelf
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: Async library for Audiobookshelf
5
5
  Author-email: Fabian Munkes <105975993+fmunkes@users.noreply.github.com>
6
6
  License: Apache-2.0
@@ -109,7 +109,7 @@ async def abs_basics():
109
109
 
110
110
  # get a single podcast
111
111
  podcast_id = "dda96167-eaad-4012-83e1-149c6700d3e8"
112
- podcast_expanded = client.get_library_item_podcast(podcast_id=podcast_id, expanded=True)
112
+ podcast_expanded = await client.get_library_item_podcast(podcast_id=podcast_id, expanded=True)
113
113
 
114
114
 
115
115
  asyncio.run(abs_basics())
@@ -1,12 +1,12 @@
1
- aioaudiobookshelf/__init__.py,sha256=zihAWwXc_wjsyXfWPt8TJ4r3Ichm5so7484NsDXThP0,4138
1
+ aioaudiobookshelf/__init__.py,sha256=V20kFZaBlByTjA2mNdWR20JPpzjC-YY_CKremymscRI,4138
2
2
  aioaudiobookshelf/exceptions.py,sha256=JQNdqBaR5AhuCUBg5DH5-orkfJrx_CJpe53ignWD6vE,377
3
3
  aioaudiobookshelf/helpers.py,sha256=ImZntca2l39P285TVVrFah82MjrP4wXLnVd7LMoD5Ck,1581
4
4
  aioaudiobookshelf/client/__init__.py,sha256=YnrNm2ZmQeVqGQ8EfAKIPRI4p2cLFqCzv4uKgL6HJPM,6931
5
- aioaudiobookshelf/client/_base.py,sha256=1S0ACN-fiXKy0uVVLb422LGFB4bOvVFnSvyEDM47-v0,3815
5
+ aioaudiobookshelf/client/_base.py,sha256=cxzivvqAitDkpyjqr0o_GjtaoWn6-kQ4GXCrkhZ3ufI,3779
6
6
  aioaudiobookshelf/client/authors.py,sha256=8bXN0NsPvH1rvF166xUu7rVC-0P0Sp4N7oxZrO666nc,1129
7
7
  aioaudiobookshelf/client/collections_.py,sha256=Z3r7dxHhzMm_cGCMRJkVzN5-Eesftib3d0bs4iXmmzY,879
8
8
  aioaudiobookshelf/client/items.py,sha256=4yWy7Shd6sbKj4MSGYJXklXs-yZH2q95qGIm4L-PS5o,3624
9
- aioaudiobookshelf/client/libraries.py,sha256=ejzxUCFgCfWtJQMCjAlo7LHWLk82Kl2BdkjpRVKtBck,6250
9
+ aioaudiobookshelf/client/libraries.py,sha256=VK1VqX9V6_8PAhPVx-eIPOgsS8t_U1a6iFML2nOyi14,6852
10
10
  aioaudiobookshelf/client/me.py,sha256=cYmXNoFJHZgEI6Ds19Pf6gNQMBVOqrtcKmiyXHFFIL0,3586
11
11
  aioaudiobookshelf/client/playlists.py,sha256=sTsmuBqjSlKyTo31mc9Ha-WtzX7bh0hH7n1BcnlO7YY,875
12
12
  aioaudiobookshelf/client/podcasts.py,sha256=f1ECD43cn4EIwWpRvwM_RosfzDr8popFDFbRYgCZQxs,684
@@ -37,9 +37,10 @@ aioaudiobookshelf/schema/series.py,sha256=XmwDvMchb-W2y-Tm-eKiE-3rPjs4kXC3Ib2dZO
37
37
  aioaudiobookshelf/schema/series_books.py,sha256=rs8a4JmSHqJR6WPA2XKXmC6XDq8D9wmzxftLlPhvub8,868
38
38
  aioaudiobookshelf/schema/server.py,sha256=yWBRxtwtX1USs43yGFuDIM3jfWbmduW3GRahisOUCqw,2726
39
39
  aioaudiobookshelf/schema/session.py,sha256=jqCHNUthuzE6jhgG3UwFgagl1HA_rfDwn6Te38jaqC8,2684
40
+ aioaudiobookshelf/schema/shelf.py,sha256=npPr5iacm6b5FfJYF9_lFZaitJNJ3SVvBOScbxlF5MQ,5064
40
41
  aioaudiobookshelf/schema/user.py,sha256=Zcnl6gqfc97dmHrNOHVsX_OOqwcJq-eFMhc9zVMLIs4,2057
41
- aioaudiobookshelf-0.1.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
42
- aioaudiobookshelf-0.1.4.dist-info/METADATA,sha256=OmHbBKE2vAJ8-wU1v1NKsrnTEfwjz5-MTqRnQNKJt6o,4377
43
- aioaudiobookshelf-0.1.4.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
44
- aioaudiobookshelf-0.1.4.dist-info/top_level.txt,sha256=2_I2_xz98xmVIT84pcF3tlq3NdZNKskfs7BqUmYZylk,18
45
- aioaudiobookshelf-0.1.4.dist-info/RECORD,,
42
+ aioaudiobookshelf-0.1.6.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
43
+ aioaudiobookshelf-0.1.6.dist-info/METADATA,sha256=VuR5OVJBBkIXh0omjtvIpv3Be9k0ov7BzXL6-SA4AVo,4383
44
+ aioaudiobookshelf-0.1.6.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
45
+ aioaudiobookshelf-0.1.6.dist-info/top_level.txt,sha256=2_I2_xz98xmVIT84pcF3tlq3NdZNKskfs7BqUmYZylk,18
46
+ aioaudiobookshelf-0.1.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5