Spaces:
Runtime error
Runtime error
| """ | |
| 任务数据模型 | |
| 定义转换任务的数据结构 | |
| """ | |
| from enum import Enum | |
| from dataclasses import dataclass, field | |
| from typing import Optional, Dict, List, Any | |
| from datetime import datetime | |
| import uuid | |
| class TaskStatus(Enum): | |
| """任务状态枚举""" | |
| PENDING = "pending" # 任务已创建,等待处理 | |
| QUEUED = "queued" # 任务在队列中等待 | |
| PROCESSING = "processing" # 正在处理中 | |
| CONVERTING = "converting" # 正在转换音频 | |
| UPLOADING = "uploading" # 正在上传结果 | |
| COMPLETED = "completed" # 转换完成 | |
| FAILED = "failed" # 转换失败 | |
| CANCELLED = "cancelled" # 任务已取消 | |
| class VoiceSettings: | |
| """语音设置""" | |
| language: str = "zh-CN" | |
| voice_name: str = "xiaoxiao" | |
| speed: float = 1.0 | |
| pitch: int = 0 | |
| volume: float = 0.8 | |
| class ProcessingDetails: | |
| """处理详情""" | |
| total_segments: int = 0 | |
| completed_segments: int = 0 | |
| current_segment: str = "" | |
| audio_duration: str = "0分0秒" | |
| error_message: Optional[str] = None | |
| class AudioFile: | |
| """音频文件信息""" | |
| title: str | |
| url: str | |
| duration: str | |
| file_size: int = 0 | |
| chapter_id: str = "" | |
| class ConversionTask: | |
| """转换任务模型""" | |
| task_id: str = field(default_factory=lambda: f"audio_{uuid.uuid4()}") | |
| status: TaskStatus = TaskStatus.PENDING | |
| # 输入信息 | |
| file_url: str = "" | |
| original_filename: str = "" | |
| user_id: Optional[str] = None # 从文件URL解析的用户ID | |
| original_task_id: Optional[str] = None # 从文件URL解析的原始任务ID | |
| r2_file_path: Optional[str] = None # R2存储路径(新增) | |
| # 转换配置 | |
| voice_settings: VoiceSettings = field(default_factory=VoiceSettings) | |
| output_formats: List[str] = field(default_factory=lambda: ["mp3"]) | |
| audio_quality: str = "high" | |
| split_by_chapter: bool = True | |
| max_segment_length: int = 300 | |
| # 进度信息 | |
| progress: int = 0 | |
| current_stage: str = "" | |
| queue_position: int = 0 | |
| # 时间信息 | |
| created_at: datetime = field(default_factory=datetime.now) | |
| started_at: Optional[datetime] = None | |
| completed_at: Optional[datetime] = None | |
| estimated_completion: Optional[datetime] = None | |
| # 处理详情 | |
| processing_details: ProcessingDetails = field(default_factory=ProcessingDetails) | |
| # 结果信息 | |
| audio_files: Dict[str, Any] = field(default_factory=dict) | |
| metadata: Dict[str, Any] = field(default_factory=dict) | |
| # 错误信息 | |
| error_message: Optional[str] = None | |
| retry_count: int = 0 | |
| max_retries: int = 3 | |
| def to_dict(self) -> Dict[str, Any]: | |
| """转换为字典格式""" | |
| return { | |
| "task_id": self.task_id, | |
| "status": self.status.value, | |
| "progress": self.progress, | |
| "current_stage": self.current_stage, | |
| "created_at": self.created_at.isoformat(), | |
| "started_at": self.started_at.isoformat() if self.started_at else None, | |
| "completed_at": ( | |
| self.completed_at.isoformat() if self.completed_at else None | |
| ), | |
| "estimated_completion": ( | |
| self.estimated_completion.isoformat() | |
| if self.estimated_completion | |
| else None | |
| ), | |
| "queue_position": self.queue_position, | |
| "processing_details": { | |
| "total_segments": self.processing_details.total_segments, | |
| "completed_segments": self.processing_details.completed_segments, | |
| "current_segment": self.processing_details.current_segment, | |
| "audio_duration": self.processing_details.audio_duration, | |
| }, | |
| "original_filename": self.original_filename, | |
| "user_id": self.user_id, | |
| "original_task_id": self.original_task_id, | |
| "r2_file_path": self.r2_file_path, | |
| "audio_files": self.audio_files, | |
| "metadata": self.metadata, | |
| "error_message": self.error_message, | |
| } | |
| def update_progress(self, progress: int, stage: str, segment: str = ""): | |
| """更新任务进度""" | |
| self.progress = progress | |
| self.current_stage = stage | |
| if segment: | |
| self.processing_details.current_segment = segment | |
| def mark_failed(self, error_message: str): | |
| """标记任务失败""" | |
| self.status = TaskStatus.FAILED | |
| self.error_message = error_message | |
| self.completed_at = datetime.now() | |
| def mark_completed(self): | |
| """标记任务完成""" | |
| self.status = TaskStatus.COMPLETED | |
| self.progress = 100 | |
| self.current_stage = "转换完成" | |
| self.completed_at = datetime.now() | |
| def can_retry(self) -> bool: | |
| """检查是否可以重试""" | |
| return self.retry_count < self.max_retries and self.status == TaskStatus.FAILED | |
| def increment_retry(self): | |
| """增加重试次数""" | |
| self.retry_count += 1 | |
| self.status = TaskStatus.PENDING | |
| self.error_message = None | |