| from dataclasses import asdict, dataclass, field |
| from pathlib import Path |
| from typing import Any, Dict, List, Optional |
|
|
|
|
| JsonDict = Dict[str, Any] |
|
|
|
|
| @dataclass |
| class Chapter: |
| id: str |
| label: str |
| title: str |
| text: str |
| chars: int |
| est_minutes: int |
| included: bool = True |
| start_seconds: int = 0 |
|
|
| def to_dict(self) -> JsonDict: |
| data = asdict(self) |
| data["n"] = data["label"] |
| return data |
|
|
|
|
| @dataclass |
| class SessionRecord: |
| session_id: str |
| root: Path |
| created_at: float |
| touched_at: float |
|
|
|
|
| @dataclass |
| class VoiceConfig: |
| mode: str |
| narrator_id: Optional[str] = None |
| sample_path: Optional[str] = None |
| reference_text: Optional[str] = None |
| design_prompt: Optional[str] = None |
|
|
| @classmethod |
| def from_dict(cls, data: JsonDict) -> "VoiceConfig": |
| return cls( |
| mode=data.get("mode", "auto"), |
| narrator_id=data.get("narratorId") or data.get("narrator_id"), |
| sample_path=data.get("samplePath") or data.get("sample_path"), |
| reference_text=data.get("referenceText") or data.get("reference_text"), |
| design_prompt=data.get("designPrompt") or data.get("design_prompt"), |
| ) |
|
|
|
|
| @dataclass |
| class RenderArtifact: |
| path: Path |
| duration_seconds: int |
| chapter_id: str |
|
|
|
|
| @dataclass |
| class RenderJob: |
| session_id: str |
| status: str = "idle" |
| current_chapter_id: Optional[str] = None |
| outputs: List[RenderArtifact] = field(default_factory=list) |
|
|
|
|