From bb1f168e36cc28f4c620b92259a9e06b79a95cd4 Mon Sep 17 00:00:00 2001 From: "hehihoho3@gmail.com" Date: Wed, 5 Aug 2026 14:47:10 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20/auto/prepare=20=EA=B0=80=20dict=20?= =?UTF-8?q?=EC=BB=B7=EC=9D=84=20=ED=8A=9C=ED=94=8C=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EA=B7=9C=ED=99=94=20=EC=95=88=20=ED=95=B4=20=EC=A4=80=EB=B9=84?= =?UTF-8?q?=EA=B0=80=20=EC=A0=84=EB=A9=B4=20=EC=8B=A4=ED=8C=A8=ED=95=98?= =?UTF-8?q?=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- server/app.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) 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,