recommend.py 모듈, 카드 배치가 자동 탭(card_cuts→_cards_by_cut)과
나머지 탭(_load_comment_cards 전체 균등)으로 갈린 이유, 그리고 서버가
카드 시간을 미리 확정하지 않는 이유(무음 제거 시 자막만 재매핑되고
카드가 혼자 어긋나는 것을 방지)를 문서에 남겨 나중에 이 설계를
실수로 되돌리는 것을 막는다. SETUP.md 문제 해결표에도 추천 실패
폴백 증상 두 건을 추가.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
서버가 하이라이트마다 컷 단위 추천(hl.cuts)을 내려주기 시작해서(6~8번
커밋), 화면도 컷 소속을 알아야 카드를 그 컷 구간 안에 배치할 수 있다.
카드가 어느 컷에 속하는지(selCut)를 추적해 컷별 상한(quota)을 걸고,
sel[hlId]를 항상 컷 순서로 정렬해 업로드 파일명(001.png…)과
card_cuts 배열 인덱스가 어긋나지 않게 했다. hl.cuts가 없으면(추천
실패) 기존 ⭐ 통짜 화면으로 그대로 폴백한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
_load_comment_cards를 _card_paths/_load_comment_cards/_cards_by_cut로 분리했다.
자동 탭은 카드가 어느 컷 소속인지(card_cuts)만 넘기면 그 컷 구간 안에서 균등
배치되어, 한 컷의 카드가 모자라도 다음 컷 카드가 앞으로 밀리지 않는다(기존
전체 균등 배치의 약점). 카드 시간은 무음 제거 전 placements 직후에 계산하고,
자막과 동일하게 _remap_caps()로 재매핑한다 — 카드 튜플(start,end,path)이
자막 튜플(start,end,text)과 모양이 같아 그대로 재사용 가능하다. card_cuts가
없으면 기존 _load_comment_cards 폴백으로 떨어져 파일/유튜브 구간 탭은 영향
없다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
댓글 매칭 후 recommend.build_highlight_cuts()를 호출해 하이라이트별
cuts/need를 SSE result에 실어 보낸다. Gemini 호출이 블로킹이라
asyncio.to_thread로 스레드에서 돌리고, 실패해도 기존 matched/candidates로
화면이 폴백하도록 warnings에만 기록하고 드래프트 생성은 막지 않는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
리뷰에서 잡힌 구멍이 계획서 참고 코드에도 그대로 있었다. str.format 의
ValueError 와 .decode 의 UnicodeDecodeError(= ValueError 서브클래스)가
빠져 있어, 그대로 옮기면 "어떤 실패에도 예외 없음" 계약이 깨진다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
correct.py의 텍스트 호출 패턴을 따라 ai_pick_cuts() 및 헬퍼 함수(_candidate_lines, _cut_lines, _parse_ai)를 추가했다.
- 목차 댓글 필터링(MAX_TIMES 기준)
- 좋아요순 정렬
- 응답 파싱 시 형식 오류는 조용히 버림
- 모든 실패(키 없음, 타임아웃, JSON 깨짐 등)에 {} 반환
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- RECOMMEND_PATH 상수 추가 (프롬프트/댓글_추천.md)
- DEFAULT_RECOMMEND 기본 프롬프트 추가 ({cuts}, {comments}, {k} 치환자 포함)
- load_recommend() 함수 구현 (없으면 기본값으로 생성 후 읽기, load_step1()과 같은 패턴)
사용자가 메모장에서 프롬프트를 직접 수정할 수 있도록 설계.
Task 4에서 .format(cuts=…, comments=…, k=…)으로 채워져 Gemini에 전달됨.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
배정 규칙(타임스탐프 우선·중복 제거·Gemini 폴백)을 댓글 수집·HTTP 처리와
분리해 순수 함수로 구현. 기준 카드 길이 3초(CARD_SEC)로 컷별 쿼터 계산.
타임스탠프 매칭은 match_ranges() 이용, Gemini 없이 검증 가능.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
통짜 모드에서 영상 구간을 n개 슬롯으로 나누고 각 슬롯에 댓글을 배정하는 순수 함수를 추가했다.
- match_ranges()를 활용해 슬롯 시간대와 매칭되는 댓글을 찾음
- 좋아요 높은 댓글부터 슬롯에 배정 (슬롯당 최대 1개)
- 한 댓글이 여러 슬롯에 중복되지 않도록 관리
- exclude 집합으로 사전에 제외된 댓글 처리
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
컷별 댓글 추천 작업을 태스크 단위로 되돌릴 수 있게 버전관리를 시작한다.
.gitignore 로 영상·캐시(.downloads 2.7G, .comments 72M, .media 28M)와
비밀키(.gemini_key)를 제외했다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>