aioaudiobookshelf 0.1.0__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.

Files changed (45) hide show
  1. aioaudiobookshelf/__init__.py +72 -0
  2. aioaudiobookshelf/client/__init__.py +189 -0
  3. aioaudiobookshelf/client/_base.py +110 -0
  4. aioaudiobookshelf/client/authors.py +34 -0
  5. aioaudiobookshelf/client/collections_.py +28 -0
  6. aioaudiobookshelf/client/items.py +108 -0
  7. aioaudiobookshelf/client/libraries.py +173 -0
  8. aioaudiobookshelf/client/me.py +103 -0
  9. aioaudiobookshelf/client/playlists.py +29 -0
  10. aioaudiobookshelf/client/podcasts.py +22 -0
  11. aioaudiobookshelf/client/series.py +27 -0
  12. aioaudiobookshelf/client/session.py +35 -0
  13. aioaudiobookshelf/exceptions.py +13 -0
  14. aioaudiobookshelf/helpers.py +56 -0
  15. aioaudiobookshelf/schema/__init__.py +14 -0
  16. aioaudiobookshelf/schema/audio.py +71 -0
  17. aioaudiobookshelf/schema/author.py +46 -0
  18. aioaudiobookshelf/schema/book.py +125 -0
  19. aioaudiobookshelf/schema/calls_authors.py +33 -0
  20. aioaudiobookshelf/schema/calls_collections.py +14 -0
  21. aioaudiobookshelf/schema/calls_items.py +53 -0
  22. aioaudiobookshelf/schema/calls_library.py +103 -0
  23. aioaudiobookshelf/schema/calls_login.py +28 -0
  24. aioaudiobookshelf/schema/calls_me.py +28 -0
  25. aioaudiobookshelf/schema/calls_playlists.py +14 -0
  26. aioaudiobookshelf/schema/calls_series.py +25 -0
  27. aioaudiobookshelf/schema/calls_session.py +17 -0
  28. aioaudiobookshelf/schema/collection.py +36 -0
  29. aioaudiobookshelf/schema/events_socket.py +46 -0
  30. aioaudiobookshelf/schema/file.py +22 -0
  31. aioaudiobookshelf/schema/folder.py +18 -0
  32. aioaudiobookshelf/schema/library.py +221 -0
  33. aioaudiobookshelf/schema/media_progress.py +42 -0
  34. aioaudiobookshelf/schema/playlist.py +74 -0
  35. aioaudiobookshelf/schema/podcast.py +129 -0
  36. aioaudiobookshelf/schema/series.py +45 -0
  37. aioaudiobookshelf/schema/series_books.py +34 -0
  38. aioaudiobookshelf/schema/server.py +76 -0
  39. aioaudiobookshelf/schema/session.py +78 -0
  40. aioaudiobookshelf/schema/user.py +81 -0
  41. aioaudiobookshelf-0.1.0.dist-info/LICENSE +201 -0
  42. aioaudiobookshelf-0.1.0.dist-info/METADATA +32 -0
  43. aioaudiobookshelf-0.1.0.dist-info/RECORD +45 -0
  44. aioaudiobookshelf-0.1.0.dist-info/WHEEL +5 -0
  45. aioaudiobookshelf-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,221 @@
1
+ """Library Schema."""
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 AuthorMinified
13
+ from aioaudiobookshelf.schema.series import SeriesFilterData
14
+
15
+ from . import _BaseModel
16
+ from .book import Book, BookExpanded, BookMinified
17
+ from .file import FileMetadata
18
+ from .folder import Folder
19
+ from .podcast import Podcast, PodcastExpanded, PodcastMinified
20
+
21
+
22
+ class LibraryIcons(StrEnum):
23
+ """LibraryIcons."""
24
+
25
+ DATABASE = "database"
26
+ AUDIOBOOKSHELF = "audiobookshelf"
27
+ BOOKS1 = "books-1"
28
+ BOOKS2 = "books-2"
29
+ BOOK1 = "book-1"
30
+ MICROPHONE1 = "microphone-1"
31
+ MICROPHONE3 = "microphone-3"
32
+ RADIO = "radio"
33
+ PODCAST = "podcast"
34
+ RSS = "rss"
35
+ HEADPHONES = "headphones"
36
+ MUSIC = "music"
37
+ FILEPICTURE = "file-picture"
38
+ ROCKET = "rocket"
39
+ POWER = "power"
40
+ START = "star"
41
+ HEART = "heart"
42
+
43
+
44
+ class LibraryMediaType(StrEnum):
45
+ """LibraryMediaType."""
46
+
47
+ BOOK = "book"
48
+ PODCAST = "podcast"
49
+
50
+
51
+ @dataclass(kw_only=True)
52
+ class LibraryFile(_BaseModel):
53
+ """LibraryFile."""
54
+
55
+ ino: str
56
+ metadata: FileMetadata
57
+ added_at: Annotated[int, Alias("addedAt")] # ms epoch
58
+ updated_at: Annotated[int, Alias("updatedAt")] # ms epoch
59
+ file_type: Annotated[str, Alias("fileType")]
60
+
61
+
62
+ @dataclass(kw_only=True)
63
+ class LibrarySettings(_BaseModel):
64
+ """LibrarySettings."""
65
+
66
+ cover_aspect_ratio: Annotated[int, Alias("coverAspectRatio")]
67
+ disable_watcher: Annotated[bool, Alias("disableWatcher")]
68
+ skip_matching_media_with_asin: Annotated[bool, Alias("skipMatchingMediaWithAsin")]
69
+ skip_matching_media_with_isbn: Annotated[bool, Alias("skipMatchingMediaWithIsbn")]
70
+ auto_scan_cron_expression: Annotated[str | None, Alias("autoScanCronExpression")] = None
71
+
72
+
73
+ @dataclass(kw_only=True)
74
+ class Library(_BaseModel):
75
+ """Library."""
76
+
77
+ id_: Annotated[str, Alias("id")]
78
+ name: str
79
+ folders: list[Folder]
80
+ display_order: Annotated[int, Alias("displayOrder")]
81
+ icon: LibraryIcons
82
+ media_type: Annotated[LibraryMediaType, Alias("mediaType")]
83
+ # TODO: add enum
84
+ provider: str
85
+ settings: LibrarySettings
86
+ created_at: Annotated[int, Alias("createdAt")] # ms epoch
87
+ last_update: Annotated[int, Alias("lastUpdate")] # ms epoch
88
+
89
+
90
+ @dataclass(kw_only=True)
91
+ class _LibraryItemBase(_BaseModel):
92
+ id_: Annotated[str, Alias("id")]
93
+ ino: str
94
+ library_id: Annotated[str, Alias("libraryId")]
95
+ folder_id: Annotated[str, Alias("folderId")]
96
+ path: str
97
+ relative_path: Annotated[str, Alias("relPath")]
98
+ is_file: Annotated[bool, Alias("isFile")]
99
+ modified_time_ms: Annotated[int, Alias("mtimeMs")]
100
+ changed_time_ms: Annotated[int, Alias("ctimeMs")]
101
+ created_time_ms: Annotated[int, Alias("birthtimeMs")] # epoch
102
+ added_at: Annotated[int, Alias("addedAt")]
103
+ updated_at: Annotated[int, Alias("updatedAt")] # ms epoch
104
+ is_missing: Annotated[bool, Alias("isMissing")]
105
+ is_invalid: Annotated[bool, Alias("isInvalid")]
106
+
107
+
108
+ @dataclass(kw_only=True)
109
+ class LibraryItem(_LibraryItemBase):
110
+ """LibraryItem."""
111
+
112
+ class Config(_LibraryItemBase.Config):
113
+ """Config."""
114
+
115
+ discriminator = Discriminator(
116
+ field="mediaType",
117
+ include_subtypes=True,
118
+ )
119
+
120
+ last_scan: Annotated[int | None, Alias("lastScan")] = None # ms epoch
121
+ scan_version: Annotated[str | None, Alias("scanVersion")] = None
122
+ library_files: Annotated[list[LibraryFile], Alias("libraryFiles")]
123
+
124
+
125
+ @dataclass(kw_only=True)
126
+ class LibraryItemBook(LibraryItem):
127
+ """LibraryItemBook."""
128
+
129
+ media: Book
130
+ mediaType: LibraryMediaType = LibraryMediaType.BOOK
131
+
132
+
133
+ @dataclass(kw_only=True)
134
+ class LibraryItemPodcast(LibraryItem):
135
+ """LibraryItemPodcast."""
136
+
137
+ media: Podcast
138
+ mediaType: LibraryMediaType = LibraryMediaType.PODCAST
139
+
140
+
141
+ @dataclass(kw_only=True)
142
+ class LibraryItemMinified(_LibraryItemBase):
143
+ """LibraryItemMinified."""
144
+
145
+ class Config(_LibraryItemBase.Config):
146
+ """Config."""
147
+
148
+ discriminator = Discriminator(
149
+ field="mediaType",
150
+ include_subtypes=True,
151
+ )
152
+
153
+ num_files: Annotated[int, Alias("numFiles")]
154
+ size: int
155
+
156
+
157
+ @dataclass(kw_only=True)
158
+ class LibraryItemMinifiedBook(LibraryItemMinified):
159
+ """LibraryItemMinifiedBook."""
160
+
161
+ media: BookMinified
162
+ mediaType: LibraryMediaType = LibraryMediaType.BOOK
163
+ # media_type: Annotated[LibraryMediaType, Alias("mediaType")] = LibraryMediaType.BOOK
164
+ # media_type: LibraryMediaType = field(
165
+ # metadata=field_options(alias="mediaType"), default=LibraryMediaType.BOOK
166
+ # )
167
+
168
+
169
+ @dataclass(kw_only=True)
170
+ class LibraryItemMinifiedPodcast(LibraryItemMinified):
171
+ """LibraryItemMinifiedPodcast."""
172
+
173
+ media: PodcastMinified
174
+ mediaType: LibraryMediaType = LibraryMediaType.PODCAST
175
+ # media_type: Annotated[LibraryMediaType, Alias("mediaType")] = LibraryMediaType.PODCAST
176
+ # media_type: LibraryMediaType = field(
177
+ # metadata=field_options(alias="mediaType"), default=LibraryMediaType.PODCAST
178
+ # )
179
+
180
+
181
+ @dataclass(kw_only=True)
182
+ class LibraryItemExpanded(LibraryItem):
183
+ """LibraryItemExpanded."""
184
+
185
+ class Config(LibraryItem.Config):
186
+ """Config."""
187
+
188
+ discriminator = Discriminator(
189
+ field="mediaType",
190
+ include_subtypes=True,
191
+ )
192
+
193
+ size: int
194
+
195
+
196
+ @dataclass(kw_only=True)
197
+ class LibraryItemExpandedBook(LibraryItemExpanded):
198
+ """LibraryItemExpandedBook."""
199
+
200
+ media: BookExpanded
201
+ mediaType: LibraryMediaType = LibraryMediaType.BOOK
202
+
203
+
204
+ @dataclass(kw_only=True)
205
+ class LibraryItemExpandedPodcast(LibraryItemExpanded):
206
+ """LibraryItemExpandedPodcast."""
207
+
208
+ media: PodcastExpanded
209
+ mediaType: LibraryMediaType = LibraryMediaType.PODCAST
210
+
211
+
212
+ @dataclass(kw_only=True)
213
+ class LibraryFilterData(_BaseModel):
214
+ """LibraryFilterData."""
215
+
216
+ authors: list[AuthorMinified]
217
+ genres: list[str]
218
+ tags: list[str]
219
+ series: list[SeriesFilterData]
220
+ narrators: list[str]
221
+ languages: list[str]
@@ -0,0 +1,42 @@
1
+ """Schema for media progress."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Annotated
5
+
6
+ from mashumaro.types import Alias
7
+
8
+ from . import _BaseModel
9
+ from .book import BookExpanded
10
+ from .podcast import PodcastEpisode, PodcastExpanded
11
+
12
+
13
+ @dataclass(kw_only=True)
14
+ class MediaProgress(_BaseModel):
15
+ """MediaProgress."""
16
+
17
+ id_: Annotated[str, Alias("id")]
18
+ library_item_id: Annotated[str, Alias("libraryItemId")]
19
+ episode_id: Annotated[str | None, Alias("episodeId")] = None
20
+ duration: float # seconds
21
+ progress: float # percent 0->1
22
+ current_time: Annotated[float, Alias("currentTime")] # seconds
23
+ is_finished: Annotated[bool, Alias("isFinished")]
24
+ hide_from_continue_listening: Annotated[bool, Alias("hideFromContinueListening")]
25
+ last_update: Annotated[int, Alias("lastUpdate")] # ms epoch
26
+ started_at: Annotated[int, Alias("startedAt")] # ms epoch
27
+ finished_at: Annotated[int | None, Alias("finishedAt")] = None # ms epoch
28
+
29
+
30
+ @dataclass(kw_only=True)
31
+ class MediaProgressWithMediaBook(MediaProgress):
32
+ """MediaProgressWithMediaBook."""
33
+
34
+ media: BookExpanded
35
+
36
+
37
+ @dataclass(kw_only=True)
38
+ class MediaProgressWithMediaPodcast(MediaProgress):
39
+ """MediaProgressWithMediaPodcast."""
40
+
41
+ media: PodcastExpanded
42
+ episode: PodcastEpisode
@@ -0,0 +1,74 @@
1
+ """Schema for playlist."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Annotated
5
+
6
+ from mashumaro.types import Alias, Discriminator
7
+
8
+ from aioaudiobookshelf.schema.podcast import PodcastEpisodeExpanded
9
+
10
+ from . import _BaseModel
11
+ from .library import LibraryItemExpandedBook, LibraryItemMinifiedPodcast
12
+
13
+
14
+ @dataclass(kw_only=True)
15
+ class PlaylistItem(_BaseModel):
16
+ """PlaylistItem."""
17
+
18
+ library_item_id: Annotated[str, Alias("libraryItemId")]
19
+ episode_id: Annotated[str | None, Alias("episodeId")] = None
20
+
21
+
22
+ @dataclass(kw_only=True)
23
+ class PlaylistItemExpanded(_BaseModel):
24
+ """PlaylistExpanded."""
25
+
26
+ class Config(PlaylistItem.Config):
27
+ """Config."""
28
+
29
+ # can't use field as episode_id is either existing or not.
30
+ discriminator = Discriminator(
31
+ include_subtypes=True,
32
+ )
33
+
34
+
35
+ @dataclass(kw_only=True)
36
+ class PlaylistItemExpandedBook(PlaylistItemExpanded):
37
+ """PlaylistExpanded."""
38
+
39
+ library_item: Annotated[LibraryItemExpandedBook, Alias("libraryItem")]
40
+
41
+
42
+ @dataclass(kw_only=True)
43
+ class PlaylistItemExpandedPodcast(PlaylistItemExpanded):
44
+ """PlaylistItemExpandedPodcast."""
45
+
46
+ library_item: Annotated[LibraryItemMinifiedPodcast, Alias("libraryItem")]
47
+ episode_id: Annotated[str, Alias("episodeId")]
48
+ episode: PodcastEpisodeExpanded
49
+
50
+
51
+ @dataclass(kw_only=True)
52
+ class _PlaylistBase(_BaseModel):
53
+ id_: Annotated[str, Alias("id")]
54
+ library_id: Annotated[str, Alias("libraryId")]
55
+ user_id: Annotated[str | None, Alias("userId")] = None
56
+ name: str
57
+ description: str | None = None
58
+ cover_path: Annotated[str | None, Alias("coverPath")] = None
59
+ last_update: Annotated[int, Alias("lastUpdate")] # ms epoch
60
+ created_at: Annotated[int, Alias("createdAt")] # ms epoch
61
+
62
+
63
+ @dataclass(kw_only=True)
64
+ class Playlist(_PlaylistBase):
65
+ """Playlist."""
66
+
67
+ items: list[PlaylistItem]
68
+
69
+
70
+ @dataclass(kw_only=True)
71
+ class PlaylistExpanded(_PlaylistBase):
72
+ """Playlist."""
73
+
74
+ items: list[PlaylistItemExpanded]
@@ -0,0 +1,129 @@
1
+ """Schema for podcasts."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Annotated
5
+
6
+ from mashumaro.types import Alias
7
+
8
+ from . import _BaseModel
9
+ from .audio import AudioFile, AudioTrack
10
+
11
+
12
+ @dataclass(kw_only=True)
13
+ class PodcastMetadata(_BaseModel):
14
+ """PodcastMetadata."""
15
+
16
+ title: str | None = None
17
+ author: str | None = None
18
+ description: str | None = None
19
+ release_date: Annotated[str | None, Alias("releaseDate")] = None
20
+ genres: list[str]
21
+ feed_url: Annotated[str | None, Alias("feedUrl")] = None
22
+ image_url: Annotated[str | None, Alias("imageUrl")] = None
23
+ itunes_page_url: Annotated[str | None, Alias("itunesPageUrl")] = None
24
+ itunes_id: Annotated[int | str | None, Alias("itunesId")] = None
25
+ # str: is not documented
26
+ itunes_artist_id: Annotated[int | str | None, Alias("itunesArtistId")] = None
27
+ explicit: bool
28
+ language: str | None = None
29
+ type_: Annotated[str | None, Alias("type")] = None
30
+
31
+
32
+ @dataclass(kw_only=True)
33
+ class PodcastMetadataMinified(PodcastMetadata):
34
+ """PodcastMetadataMinified."""
35
+
36
+ title_ignore_prefix: Annotated[str | None, Alias("titleIgnorePrefix")] = None
37
+
38
+
39
+ PodcastMetaDataExpanded = PodcastMetadataMinified
40
+
41
+
42
+ @dataclass(kw_only=True)
43
+ class PodcastEpisodeEnclosure(_BaseModel):
44
+ """PodcastEpisodeEnclosure."""
45
+
46
+ url: str
47
+ type_: Annotated[str, Alias("type")]
48
+ length: str
49
+
50
+
51
+ @dataclass(kw_only=True)
52
+ class _PodcastEpisodeBase(_BaseModel):
53
+ """PodcastEpisode."""
54
+
55
+ library_item_id: Annotated[str, Alias("libraryItemId")]
56
+ id_: Annotated[str, Alias("id")]
57
+ index: int | None = None
58
+ season: str
59
+ episode: str
60
+ episode_type: Annotated[str, Alias("episodeType")]
61
+ title: str
62
+ subtitle: str
63
+ description: str
64
+ pub_date: Annotated[str, Alias("pubDate")]
65
+ published_at: Annotated[int | None, Alias("publishedAt")] = None # ms posix epoch
66
+ added_at: Annotated[int, Alias("addedAt")] # ms posix epoch
67
+ updated_at: Annotated[int, Alias("updatedAt")] # ms posix epoch
68
+
69
+
70
+ @dataclass(kw_only=True)
71
+ class PodcastEpisode(_PodcastEpisodeBase):
72
+ """PodcastEpisode."""
73
+
74
+ audio_file: AudioFile | None = None
75
+ enclosure: PodcastEpisodeEnclosure | None = None
76
+
77
+
78
+ @dataclass(kw_only=True)
79
+ class PodcastEpisodeExpanded(_PodcastEpisodeBase):
80
+ """PodcastEpisodeExpanded."""
81
+
82
+ audio_track: Annotated[AudioTrack, Alias("audioTrack")]
83
+ duration: float
84
+ size: int
85
+ audio_file: AudioFile | None = None
86
+ enclosure: PodcastEpisodeEnclosure | None = None
87
+
88
+
89
+ @dataclass(kw_only=True)
90
+ class _PodcastBase(_BaseModel):
91
+ """_PodcastBase."""
92
+
93
+ cover_path: Annotated[str | None, Alias("coverPath")] = None
94
+ auto_download_episodes: Annotated[bool, Alias("autoDownloadEpisodes")]
95
+ auto_download_schedule: Annotated[str, Alias("autoDownloadSchedule")]
96
+ # None is not documented
97
+ last_episode_check_ms: Annotated[int | None, Alias("lastEpisodeCheck")] = None
98
+ max_episodes_to_keep: Annotated[int, Alias("maxEpisodesToKeep")] # 0 = all
99
+ max_new_episodes_to_download: Annotated[int, Alias("maxNewEpisodesToDownload")]
100
+
101
+
102
+ @dataclass(kw_only=True)
103
+ class Podcast(_PodcastBase):
104
+ """ABSPodcast."""
105
+
106
+ library_item_id: Annotated[str, Alias("libraryItemId")]
107
+ metadata: PodcastMetadata
108
+ tags: list[str]
109
+ episodes: list[PodcastEpisode]
110
+
111
+
112
+ @dataclass(kw_only=True)
113
+ class PodcastMinified(_PodcastBase):
114
+ """ABSPodcastMinified."""
115
+
116
+ metadata: PodcastMetadataMinified
117
+ size: int # bytes
118
+ num_episodes: Annotated[int, Alias("numEpisodes")]
119
+
120
+
121
+ @dataclass(kw_only=True)
122
+ class PodcastExpanded(_PodcastBase):
123
+ """PodcastEpisodeExpanded."""
124
+
125
+ library_item_id: Annotated[str, Alias("libraryItemId")]
126
+ tags: list[str]
127
+ size: int # bytes
128
+ metadata: PodcastMetaDataExpanded
129
+ episodes: list[PodcastEpisodeExpanded]
@@ -0,0 +1,45 @@
1
+ """Schema for series."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Annotated
5
+
6
+ from mashumaro.types import Alias
7
+
8
+ from . import _BaseModel
9
+
10
+
11
+ @dataclass(kw_only=True)
12
+ class _SeriesBase(_BaseModel):
13
+ """_SeriesBase."""
14
+
15
+ id_: Annotated[str, Alias("id")]
16
+ name: str
17
+
18
+
19
+ # in get_library call including filterdata we get only id and name of series
20
+ SeriesFilterData = _SeriesBase
21
+
22
+
23
+ @dataclass(kw_only=True)
24
+ class Series(_SeriesBase):
25
+ """Series."""
26
+
27
+ description: str | None = None
28
+ added_at: Annotated[int, Alias("addedAt")] # ms epoch
29
+ updated_at: Annotated[int, Alias("updatedAt")] # ms epoch
30
+
31
+
32
+ @dataclass(kw_only=True)
33
+ class SeriesNumBooks(_SeriesBase):
34
+ """SeriesNumBooks."""
35
+
36
+ name_ignore_prefix: Annotated[str, Alias("nameIgnorePrefix")]
37
+ library_item_ids: Annotated[list[str], Alias("libraryItemIds")]
38
+ num_books: Annotated[int, Alias("numBooks")]
39
+
40
+
41
+ @dataclass(kw_only=True)
42
+ class SeriesSequence(_SeriesBase):
43
+ """Series Sequence."""
44
+
45
+ sequence: str | None = None
@@ -0,0 +1,34 @@
1
+ """SeriesBase classes."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Annotated
5
+
6
+ from mashumaro.types import Alias
7
+
8
+ from .library import LibraryItemBook, LibraryItemMinifiedBook
9
+ from .series import _SeriesBase
10
+
11
+
12
+ @dataclass(kw_only=True)
13
+ class _SeriesBooksBase(_SeriesBase):
14
+ """SeriesBooks."""
15
+
16
+ added_at: Annotated[int, Alias("addedAt")] # ms epoch
17
+ name_ignore_prefix: Annotated[str, Alias("nameIgnorePrefix")]
18
+ name_ignore_prefix_sort: Annotated[str, Alias("nameIgnorePrefixSort")]
19
+ type_: Annotated[str, Alias("type")]
20
+ total_duration: Annotated[float, Alias("totalDuration")] # s
21
+
22
+
23
+ @dataclass(kw_only=True)
24
+ class SeriesBooks(_SeriesBooksBase):
25
+ """SeriesBooks."""
26
+
27
+ books: list[LibraryItemBook]
28
+
29
+
30
+ @dataclass(kw_only=True)
31
+ class SeriesBooksMinified(_SeriesBase):
32
+ """SeriesBooks."""
33
+
34
+ books: list[LibraryItemMinifiedBook]
@@ -0,0 +1,76 @@
1
+ """Server Schema."""
2
+
3
+ from dataclasses import dataclass
4
+ from enum import Enum, StrEnum
5
+ from typing import Annotated
6
+
7
+ from mashumaro.types import Alias
8
+
9
+ from . import _BaseModel
10
+
11
+
12
+ class ServerSettingsMetadataFileFormat(StrEnum):
13
+ """ServerSettingsMetadataFileFormat."""
14
+
15
+ ABS = "abs"
16
+ JSON = "json"
17
+
18
+
19
+ class ServerSettingsDateFormat(StrEnum):
20
+ """ServerSettingsDateFormat."""
21
+
22
+ MM_DD_YYYY = "MM/dd/yyyy"
23
+ DD_MM_YYYY = "dd/MM/yyyy"
24
+ DDpMMpYYYY = "dd.MM.yyyy"
25
+ YYYY_MM_DD = "yyyy-MM-dd"
26
+ MMM_DO_YYYY = "MMM do, yyyy"
27
+ MMMM_DO_YYYY = "MMMM do, yyyy"
28
+ DD_MMM_YYYY = "dd MMM yyyy"
29
+ DD_MMMM_YYYY = "dd MMMM yyyy"
30
+
31
+
32
+ class ServerSettingsTimeFormat(StrEnum):
33
+ """ServerSettingsTimeFormat."""
34
+
35
+ TWENTY_FOUR_HOOUR = "HH:mm"
36
+ TWELVE_HOUR = "h:mma"
37
+
38
+
39
+ class ServerLogLevel(Enum):
40
+ """ServerLogLevel."""
41
+
42
+ DEBUG = 1
43
+ INFO = 2
44
+ WARNING = 3
45
+
46
+
47
+ @dataclass(kw_only=True)
48
+ class ServerSettings(_BaseModel):
49
+ """ServerSettings."""
50
+
51
+ id: Annotated[str, Alias("id")]
52
+ scanner_find_covers: Annotated[bool, Alias("scannerFindCovers")]
53
+ scanner_cover_provider: Annotated[str, Alias("scannerCoverProvider")]
54
+ scanner_parse_subtitle: Annotated[bool, Alias("scannerParseSubtitle")]
55
+ scanner_prefer_matched_metadata: Annotated[bool, Alias("scannerPreferMatchedMetadata")]
56
+ scanner_disable_watcher: Annotated[bool, Alias("scannerDisableWatcher")]
57
+ store_cover_with_item: Annotated[bool, Alias("storeCoverWithItem")]
58
+ store_metadata_with_item: Annotated[bool, Alias("storeMetadataWithItem")]
59
+ metadata_file_format: Annotated[ServerSettingsMetadataFileFormat, Alias("metadataFileFormat")]
60
+ rate_limit_login_requests: Annotated[int, Alias("rateLimitLoginRequests")]
61
+ rate_limit_login_window: Annotated[int, Alias("rateLimitLoginWindow")] # ms
62
+ backup_schedule: Annotated[str, Alias("backupSchedule")]
63
+ backups_to_keep: Annotated[int, Alias("backupsToKeep")]
64
+ max_backup_size: Annotated[int, Alias("maxBackupSize")] # GB
65
+ logger_daily_logs_to_keep: Annotated[int, Alias("loggerDailyLogsToKeep")]
66
+ logger_scanner_logs_to_keep: Annotated[int, Alias("loggerScannerLogsToKeep")]
67
+ home_bookshelf_view: Annotated[int, Alias("homeBookshelfView")]
68
+ bookshelf_view: Annotated[int, Alias("bookshelfView")]
69
+ sorting_ignore_prefix: Annotated[bool, Alias("sortingIgnorePrefix")]
70
+ sorting_prefixes: Annotated[list[str], Alias("sortingPrefixes")]
71
+ chromecast_enabled: Annotated[bool, Alias("chromecastEnabled")]
72
+ date_format: Annotated[ServerSettingsDateFormat, Alias("dateFormat")]
73
+ time_format: Annotated[ServerSettingsTimeFormat, Alias("timeFormat")]
74
+ language: str
75
+ log_level: Annotated[ServerLogLevel, Alias("logLevel")]
76
+ version: str