from datetime import datetime from typing import Optional, List, Dict, Any from pydantic import BaseModel, ConfigDict class AudiobookProjectCreate(BaseModel): title: str source_type: str source_text: Optional[str] = None class SynopsisGenerationRequest(BaseModel): title: str genre: str subgenre: str = "" protagonist_type: str = "" tone: str = "" conflict_scale: str = "" num_characters: int = 5 num_chapters: int = 8 violence_level: int = 0 eroticism_level: int = 0 class ScriptGenerationRequest(BaseModel): title: str genre: str subgenre: str = "" premise: str style: str = "" num_characters: int = 5 num_chapters: int = 8 violence_level: int = 0 eroticism_level: int = 0 class AudiobookProjectResponse(BaseModel): id: int user_id: int title: str source_type: str status: str llm_model: Optional[str] = None error_message: Optional[str] = None script_config: Optional[Dict[str, Any]] = None created_at: datetime updated_at: datetime segment_total: int = 0 segment_done: int = 0 model_config = ConfigDict(from_attributes=True) class AudiobookCharacterResponse(BaseModel): id: int project_id: int name: str gender: Optional[str] = None description: Optional[str] = None instruct: Optional[str] = None voice_design_id: Optional[int] = None use_indextts2: bool = False model_config = ConfigDict(from_attributes=True) class AudiobookChapterResponse(BaseModel): id: int project_id: int chapter_index: int title: Optional[str] = None status: str error_message: Optional[str] = None model_config = ConfigDict(from_attributes=True) class AudiobookProjectDetail(AudiobookProjectResponse): characters: List[AudiobookCharacterResponse] = [] chapters: List[AudiobookChapterResponse] = [] class ContinueScriptRequest(BaseModel): additional_chapters: int = 4 class AudiobookAnalyzeRequest(BaseModel): turbo: bool = False class AudiobookGenerateRequest(BaseModel): chapter_index: Optional[int] = None force: bool = False class AudiobookCharacterUpdate(BaseModel): voice_design_id: int class AudiobookCharacterEdit(BaseModel): name: Optional[str] = None gender: Optional[str] = None description: Optional[str] = None instruct: Optional[str] = None voice_design_id: Optional[int] = None use_indextts2: Optional[bool] = None class AudiobookSegmentResponse(BaseModel): id: int project_id: int chapter_index: int segment_index: int character_id: int character_name: Optional[str] = None text: str emo_text: Optional[str] = None emo_alpha: Optional[float] = None audio_path: Optional[str] = None status: str model_config = ConfigDict(from_attributes=True) class AudiobookSegmentUpdate(BaseModel): text: str emo_text: Optional[str] = None emo_alpha: Optional[float] = None class LLMConfigUpdate(BaseModel): base_url: str api_key: str model: str class LLMConfigResponse(BaseModel): base_url: Optional[str] = None model: Optional[str] = None has_key: bool class NsfwSynopsisGenerationRequest(BaseModel): title: str genre: str subgenre: str = "" protagonist_type: str = "" tone: str = "" conflict_scale: str = "" num_characters: int = 5 num_chapters: int = 8 violence_level: int = 0 eroticism_level: int = 0 class NsfwScriptGenerationRequest(BaseModel): title: str genre: str subgenre: str = "" premise: str style: str = "" num_characters: int = 5 num_chapters: int = 8 violence_level: int = 0 eroticism_level: int = 0