diff --git a/server/app.py b/server/app.py index a7690d5..d988753 100644 --- a/server/app.py +++ b/server/app.py @@ -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,