From 3dd5eee68428ba6a871bb5d57e74368c3a7bd92a Mon Sep 17 00:00:00 2001 From: "hehihoho3@gmail.com" Date: Wed, 5 Aug 2026 10:31:31 +0900 Subject: [PATCH] =?UTF-8?q?recommend.py=EC=97=90=20cuts=5Ffrom=5Fstate()?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=E2=80=94=20=EC=84=B8=20=ED=83=AD=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=A1=B0=EB=A6=BD=20=ED=95=A8=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 받아쓰기 상태(압축 타임라인 places/captions + 원본 시각 orig_ranges)와 댓글을 받아 검토 화면용 cuts[]를 만든다. 자동·유튜브구간·붙여넣기 세 탭이 각자 조립 코드를 갖던 걸 이 함수 하나로 모아 좌표계 실수(압축 vs 원본 시각)를 한 곳에서만 막으면 되게 했다. Co-Authored-By: Claude Opus 5 (1M context) --- capcut_agent/recommend.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/capcut_agent/recommend.py b/capcut_agent/recommend.py index 002c70e..02c57e7 100644 --- a/capcut_agent/recommend.py +++ b/capcut_agent/recommend.py @@ -349,3 +349,24 @@ def build_highlight_cuts(hl, comments, *, key=None, quotas=None): "bottom": c.get("bottom") or "", "quota": quotas[i], "picks": picks[i]} for i, c in enumerate(cuts)] return out, sum(quotas), ai_failed + + +def cuts_from_state(places, orig_ranges, captions, comments, *, key=None): + """받아쓰기 상태 + 댓글 → 검토 화면용 (cuts[], need, ai_failed). 세 탭 공통. + + ⚠ 좌표계가 둘이다. 섞으면 카드가 통째로 어긋난다(스펙 §4): + - `places`·`captions` = 압축 타임라인 → 자막 추출·장수·배치 + - `orig_ranges` = 원본 영상 시각 → ⭐ 분:초 매칭 + 둘은 같은 길이여야 하고 인덱스로만 짝지어 다닌다. + """ + from .pipeline import captions_for_places # 순환 임포트 회피: pipeline은 draft·comments를 + # 임포트하고 app.py가 pipeline·recommend를 둘 다 임포트하므로, 파일 상단에서 + # pipeline을 가져오면 임포트 순환이 생긴다. 호출 시점(함수 안)에서만 가져온다. + if not places or len(places) != len(orig_ranges): + return [], 0, False + bottoms = captions_for_places(captions, places) + quotas = [max(1, int((p1 - p0) // CARD_SEC)) for p0, p1 in places] + cuts = [{"start": s, "end": e, "bottom": b, "effect": ""} + for (s, e), b in zip(orig_ranges, bottoms)] + return build_highlight_cuts({"paste": {"cuts": cuts}}, comments, + key=key, quotas=quotas)