recommend.py에 cuts_from_state() 추가 — 세 탭 공통 조립 함수

받아쓰기 상태(압축 타임라인 places/captions + 원본 시각 orig_ranges)와 댓글을
받아 검토 화면용 cuts[]를 만든다. 자동·유튜브구간·붙여넣기 세 탭이 각자 조립
코드를 갖던 걸 이 함수 하나로 모아 좌표계 실수(압축 vs 원본 시각)를 한 곳에서만
막으면 되게 했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hehihoho3@gmail.com 2026-08-05 10:31:31 +09:00
parent 58fab2b2a4
commit 3dd5eee684

View File

@ -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)