from pydantic import BaseModel, ConfigDict from pydantic.alias_generators import to_camel from datetime import datetime from typing import Any class AudioFileMetadata(BaseModel): model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) filename: str ext: str path: str rel_path: str = "" size: int = 0 class AudioFileOut(BaseModel): model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) index: int ino: str = "" metadata: AudioFileMetadata added_at: int = 0 updated_at: int = 0 track_num_from_meta: int | None = None disc_num_from_meta: int | None = None format: str = "" duration: float = 0.0 bitrate: int = 0 language: str | None = None codec: str = "" time_base: str = "1/44100" channels: int = 2 channel_layout: str = "stereo" chapters: list = [] embedded_cover_art: str | None = None mime_type: str = "audio/mpeg" class ChapterOut(BaseModel): model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) id: int start: float end: float title: str class BookMetadata(BaseModel): model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) title: str | None = None subtitle: str | None = None authors: list[dict] = [] # [{"id": null, "name": "..."}] narrators: list[str] = [] series: list[dict] = [] # [{"id": null, "name": "...", "sequence": "..."}] genres: list[str] = [] published_year: str | None = None published_date: str | None = None publisher: str | None = None description: str | None = None isbn: str | None = None asin: str | None = None language: str | None = None explicit: bool = False abridged: bool = False class BookOut(BaseModel): model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) library_item_id: str metadata: BookMetadata cover_path: str | None = None tags: list[str] = [] audio_files: list[AudioFileOut] = [] chapters: list[ChapterOut] = [] missing_parts: list = [] ebookFile: Any = None duration: float = 0.0 size: int = 0 tracks: list[AudioFileOut] = [] num_tracks: int = 0 num_audio_files: int = 0 num_chapters: int = 0 num_missing_parts: int = 0 num_invalid_audio_files: int = 0 is_missing: bool = False is_invalid: bool = False class LibraryItemOut(BaseModel): model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) id: str ino: str = "" library_id: str folder_id: str = "" path: str rel_path: str = "" is_file: bool = False mtime_ms: int = 0 ctime_ms: int = 0 birth_time_ms: int = 0 added_at: int = 0 updated_at: int = 0 last_scan: int | None = None scan_version: str | None = None is_missing: bool = False is_invalid: bool = False media_type: str = "book" media: BookOut | None = None num_files: int = 0 size: int = 0 class LibraryItemUpdateRequest(BaseModel): metadata: dict | None = None tags: list[str] | None = None chapters: list[dict] | None = None cover_path: str | None = None