feat: add segment tracking to audiobook projects and update UI to display progress

This commit is contained in:
2026-03-13 16:00:31 +08:00
parent d1503b08cb
commit cdb9d2ebb8
4 changed files with 59 additions and 22 deletions

View File

@@ -6,6 +6,7 @@ from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, status
from fastapi.responses import FileResponse, StreamingResponse
from sqlalchemy import func, case
from sqlalchemy.orm import Session
from api.auth import get_current_user
@@ -42,7 +43,7 @@ async def require_nsfw(current_user: User = Depends(get_current_user), db: Sessi
return current_user
def _project_to_response(project) -> AudiobookProjectResponse:
def _project_to_response(project, segment_total: int = 0, segment_done: int = 0) -> AudiobookProjectResponse:
return AudiobookProjectResponse(
id=project.id,
user_id=project.user_id,
@@ -54,6 +55,8 @@ def _project_to_response(project) -> AudiobookProjectResponse:
script_config=getattr(project, 'script_config', None),
created_at=project.created_at,
updated_at=project.updated_at,
segment_total=segment_total,
segment_done=segment_done,
)
@@ -160,7 +163,14 @@ async def list_projects(
db: Session = Depends(get_db),
):
projects = crud.list_audiobook_projects(db, current_user.id, skip=skip, limit=limit)
return [_project_to_response(p) for p in projects]
project_ids = [p.id for p in projects]
counts = db.query(
AudiobookSegment.project_id,
func.count(AudiobookSegment.id).label('total'),
func.sum(case((AudiobookSegment.status == 'done', 1), else_=0)).label('done'),
).filter(AudiobookSegment.project_id.in_(project_ids)).group_by(AudiobookSegment.project_id).all()
count_map = {r.project_id: (int(r.total), int(r.done)) for r in counts}
return [_project_to_response(p, *count_map.get(p.id, (0, 0))) for p in projects]
@router.post("/projects/generate-synopsis")

View File

@@ -45,6 +45,8 @@ class AudiobookProjectResponse(BaseModel):
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)