项目文件夹

文件
wehub-resource-sync 41b710f9c7
CI / Backend tests (push) Failing after 1s
CI / Frontend checks (push) Failing after 0s
I18n Documentation Sync / sync-docs (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:28:40 +08:00

168 行
4.2 KiB
Python

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
"""
切片模型
定义视频切片的基本信息和状态
"""
import enum
from typing import Optional
from sqlalchemy import Column, String, Integer, Float, ForeignKey, Enum, JSON, DateTime, Text
from sqlalchemy.orm import relationship
from .base import BaseModel
class ClipStatus(str, enum.Enum):
"""切片状态枚举"""
PENDING = "pending" # 待处理
PROCESSING = "processing" # 处理中
COMPLETED = "completed" # 已完成
FAILED = "failed" # 失败
class Clip(BaseModel):
"""切片模型"""
__tablename__ = "clips"
# 基本信息
title = Column(
String(255),
nullable=False,
comment="切片标题"
)
description = Column(
Text,
nullable=True,
comment="切片描述"
)
# 状态信息
status = Column(
Enum(ClipStatus),
default=ClipStatus.PENDING,
nullable=False,
comment="切片状态"
)
# 时间信息
start_time = Column(
Integer,
nullable=False,
comment="开始时间(秒)"
)
end_time = Column(
Integer,
nullable=False,
comment="结束时间(秒)"
)
duration = Column(
Integer,
nullable=False,
comment="切片时长(秒)"
)
# 评分信息
score = Column(
Float,
nullable=True,
comment="切片评分"
)
recommendation_reason = Column(
Text,
nullable=True,
comment="推荐理由"
)
# 文件信息
video_path = Column(
String(500),
nullable=True,
comment="切片视频文件路径"
)
thumbnail_path = Column(
String(500),
nullable=True,
comment="缩略图文件路径"
)
# 处理信息
processing_step = Column(
Integer,
nullable=True,
comment="处理步骤(1-6"
)
# 标签和元数据
tags = Column(
JSON,
nullable=True,
comment="切片标签"
)
clip_metadata = Column(
JSON,
nullable=True,
comment="切片元数据(精简版,完整数据存储在文件系统)"
)
# 添加计算属性
@property
def metadata_file_path(self) -> Optional[str]:
"""获取完整元数据文件路径"""
if self.clip_metadata and 'metadata_file' in self.clip_metadata:
return self.clip_metadata['metadata_file']
return None
@property
def has_full_content(self) -> bool:
"""是否有完整内容文件"""
return self.metadata_file_path is not None
# 外键关联
project_id = Column(
String(36),
ForeignKey("projects.id", ondelete="CASCADE"),
nullable=False,
comment="所属项目ID"
)
# 关联关系
project = relationship(
"Project",
back_populates="clips"
)
collections = relationship(
"Collection",
secondary="clip_collection",
back_populates="clips"
)
def __repr__(self):
return f"<Clip(id={self.id}, title='{self.title}', duration={self.duration}s)>"
@property
def is_processing(self):
"""是否正在处理"""
return self.status == ClipStatus.PROCESSING
@property
def is_completed(self):
"""是否已完成"""
return self.status == ClipStatus.COMPLETED
@property
def has_error(self):
"""是否有错误"""
return self.status == ClipStatus.FAILED
def get_time_range(self) -> str:
"""获取时间范围字符串"""
try:
start_time = int(self.start_time) if self.start_time else 0
end_time = int(self.end_time) if self.end_time else 0
start_min, start_sec = divmod(start_time, 60)
end_min, end_sec = divmod(end_time, 60)
return f"{start_min:02d}:{start_sec:02d} - {end_min:02d}:{end_sec:02d}"
except (TypeError, ValueError):
return "00:00 - 00:00"
def calculate_duration(self):
"""计算切片时长"""
self.duration = self.end_time - self.start_time
return self.duration