fix: /auto/prepare 가 dict 컷을 튜플로 정규화 안 해 준비가 전면 실패하던 문제 수정

highlights 의 paste.cuts 는 화면용 dict 인데 paste_analyze 는 parse_paste 출력형
튜플을 기대한다. 옛 /auto/build 는 프런트 JSON 재파싱으로 변환을 공짜로 얻었지만
새 /auto/prepare 는 서버 보관본을 직접 넘겨서, dict 언패킹이 키 문자열을 풀어
모든 ID 가 "end 는 start 보다 커야 합니다"(문자열 "end"<="start" 비교)로 즉사했다.
_hl_paste_payload() 로 호출 직전에 변환한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hehihoho3@gmail.com 2026-08-05 14:47:10 +09:00
parent 7ea17127b1
commit bb1f168e36

View File

@ -704,6 +704,21 @@ async def auto_stream(aid: str) -> StreamingResponse:
"X-Accel-Buffering": "no"})
def _hl_paste_payload(paste: dict) -> dict:
"""하이라이트의 paste(화면용 dict 컷) → paste_analyze 가 받는 튜플 컷 payload.
highlights cuts 화면 표시용 dict({"start":,"end":,})인데 paste_analyze
parse_paste 출력형 [(s,e,bottom,effect)] 튜플을 기대한다. /auto/build 프런트가
되보낸 JSON parse_paste 재파싱해 변환을 공짜로 얻었지만, /auto/prepare
서버 보관본을 직접 쓰므로 여기서 변환해야 한다 dict 그대로 넘기면 언패킹이
문자열("start","end",) 풀어 다운로드가 시간 형식 오류로 전면 실패한다.
"""
cuts = [(float(c["start"]), float(c["end"]),
c.get("bottom") or "", c.get("effect") or "")
for c in paste["cuts"]]
return {**paste, "cuts": cuts}
@app.post("/auto/prepare")
async def auto_prepare(aid: str = Form(...), ids: str = Form(...)) -> JSONResponse:
"""자동 탭 2단계 — 검토 화면에서 제외하지 않은 ID만 준비 예약. 실제 작업은 /auto/prepare/{pid} 에서.
@ -782,8 +797,9 @@ async def auto_prepare_stream(pid: str) -> StreamingResponse:
# build_bg_template_draft 의 allow_replace=True 가 뒤엣것으로 앞을 덮어쓴다
# (옛 /auto/build 의 tag→name_suffix 메커니즘 — 여기서도 반드시 넘겨야 한다).
safe_tag = "".join(ch for ch in f"하이라이트{hid}" if ch.isalnum() or ch in "-_")[:20]
payload = _hl_paste_payload(h["paste"]) # dict 컷 → 튜플 컷 (필수 — docstring 참고)
try:
async for ev in paste_analyze(h["paste"], f"auto_{aid}_{hid}",
async for ev in paste_analyze(payload, f"auto_{aid}_{hid}",
remove_silence=True, asr_bottom=True,
name_suffix=safe_tag):
if ev.get("type") == "state": # 내부 전용 — 밖으로 흘리지 않는다
@ -819,7 +835,7 @@ async def auto_prepare_stream(pid: str) -> StreamingResponse:
f"({type(exc).__name__}: {exc})")
PSTATES[f"{aid}:{hid}"] = {"state": state, "places": places, "orig": orig,
"payload": h["paste"]}
"payload": payload}
matched = hlab.match_ranges(comments, orig) if comments else []
highlights_out.append({
"id": hid, "cuts": cuts, "need": need,