playreel/backend/routers/view.py
2026-09-08 13:00:23 +09:00

74 lines
2.5 KiB
Python

"""잡 행을 프론트가 그리는 모양으로 옮김
필드는 web/lib/api.ts 의 Job, web/lib/playreel.ts 의 PlayreelJob 과 맞춤
"""
from models.motion import MotionPlan
from models.pipeline_state import PlayreelState, PosterAliveState, initial_timings
from pipelines.gate import build_review
from tables.task import PlayreelTask, PosterAliveTask
def current_stage(task) -> str | None:
return next((key for key, entry in (task.stage_timings or {}).items()
if entry["status"] == "running"), None)
def error_view(task) -> dict | None:
if not task.error_stage:
return None
return {"stage": task.error_stage, "detail": task.error_detail or ""}
def motion_elements(motion_plan: dict | None) -> list[str] | None:
if not motion_plan:
return None
return [item.motion for item in MotionPlan.model_validate(motion_plan).kept]
def base_view(task, state_type) -> dict:
return {
"id": task.id,
"name": task.name,
"status": task.status,
"stage": current_stage(task),
"stages": task.stage_timings or initial_timings(state_type),
"error": error_view(task),
"created_at": task.created_at.timestamp(),
"credits_used": task.credits_used,
"queue_size": 0,
}
def poster_alive_view(task: PosterAliveTask) -> dict:
return {
**base_view(task, PosterAliveState),
"kind": "f1",
"narration": task.narration_lines,
"motion_elements": motion_elements(task.motion_plan),
"metadata": task.poster_metadata,
"template_id": None,
"poster_size": [task.poster_width, task.poster_height],
"low_res": task.is_low_resolution,
"artifacts": {key: url for key, url in (
("video", task.video_url),
("thumbnail", task.thumbnail_url),
("check_jpg", task.detect_check_url),
) if url},
}
def playreel_view(task: PlayreelTask) -> dict:
return {
**base_view(task, PlayreelState),
"kind": "playreel",
"source": {"url": task.source_url, "goods_id": task.goods_id, "slug": task.slug},
"gate": task.gate,
"review": build_review(task, task.gate) if task.gate else None,
"version": task.version,
"narration": [line["text"] for line in task.narration_lines or []] or None,
"metadata": None,
"artifacts": {key: url for key, url in (
("video", task.video_url),
("thumbnail", task.analysis_grid_url),
) if url},
}