feat: Reddit 수집, 쇼츠 텔레그램 미리보기, 코너 9개 체계 정비
- Reddit 트렌딩 수집기 추가 (/reddit collect, /pick 명령어) - 쇼츠 영상 텔레그램 미리보기 후 승인 기반 YouTube 업로드 - 코너 9개로 통합 (앱추천→제품리뷰, 재테크절약→재테크, TV로보는세상/건강정보 추가) - RSS 피드 73개로 확대 (9개 코너 전체 커버) - 블로그 중복 검토 알림 수정, 글 잘림 방지 (max_tokens 8192) - 제품리뷰 다중 이미지 지원, 저품질 이미지 필터링 강화 - HookOptimizer LLM 연동, 인스타/X/틱톡 스케줄러 비활성화 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+23
-3
@@ -143,7 +143,8 @@ def _is_converted(article_id: str) -> bool:
|
||||
|
||||
# ─── 파이프라인 ───────────────────────────────────────────────
|
||||
|
||||
def produce(article: dict, dry_run: bool = False, cfg: Optional[dict] = None) -> ShortsResult:
|
||||
def produce(article: dict, dry_run: bool = False, cfg: Optional[dict] = None,
|
||||
skip_upload: bool = False) -> ShortsResult:
|
||||
"""
|
||||
블로그 글 → 쇼츠 영상 생산 + (선택) YouTube 업로드.
|
||||
|
||||
@@ -151,6 +152,7 @@ def produce(article: dict, dry_run: bool = False, cfg: Optional[dict] = None) ->
|
||||
article: article dict
|
||||
dry_run: True이면 렌더링까지만 (업로드 생략)
|
||||
cfg: shorts_config.json dict (None이면 자동 로드)
|
||||
skip_upload: True이면 영상 렌더링까지만 (업로드는 별도 승인 후 진행)
|
||||
|
||||
Returns:
|
||||
ShortsResult
|
||||
@@ -193,10 +195,23 @@ def produce(article: dict, dry_run: bool = False, cfg: Optional[dict] = None) ->
|
||||
manifest = resolve(article, script=script, cfg=cfg)
|
||||
result.steps_completed.append('script_extract')
|
||||
|
||||
# ── STEP 1.5: Hook Optimization ─────────────────────────
|
||||
# ── STEP 1.5: Hook Optimization (LLM 연동) ──────────────
|
||||
hook_optimizer = HookOptimizer(threshold=70)
|
||||
original_hook = script.get('hook', '')
|
||||
optimized_hook = hook_optimizer.optimize(original_hook, article)
|
||||
|
||||
# LLM 함수 생성 — 기존 엔진 로더 활용
|
||||
llm_fn = None
|
||||
try:
|
||||
from engine_loader import EngineLoader
|
||||
writer = EngineLoader().get_writer()
|
||||
if writer:
|
||||
def _hook_llm(prompt: str) -> str:
|
||||
return writer.write(prompt).strip()
|
||||
llm_fn = _hook_llm
|
||||
except Exception as e:
|
||||
logger.warning(f'[{article_id}] 훅 LLM 로드 실패 (규칙 기반으로 진행): {e}')
|
||||
|
||||
optimized_hook = hook_optimizer.optimize(original_hook, article, llm_fn=llm_fn)
|
||||
if optimized_hook != original_hook:
|
||||
script['hook'] = optimized_hook
|
||||
logger.info(f'[{article_id}] 훅 최적화: "{original_hook[:20]}" → "{optimized_hook[:20]}"')
|
||||
@@ -256,6 +271,11 @@ def produce(article: dict, dry_run: bool = False, cfg: Optional[dict] = None) ->
|
||||
result.success = True
|
||||
return result
|
||||
|
||||
if skip_upload:
|
||||
logger.info(f'[{article_id}] STEP 6: 건너뜀 (승인 대기 — skip_upload)')
|
||||
result.success = True
|
||||
return result
|
||||
|
||||
logger.info(f'[{article_id}] STEP 6: YouTube Upload')
|
||||
from shorts.youtube_uploader import upload
|
||||
upload_record = upload(video_path, article, script, ts, cfg=cfg)
|
||||
|
||||
Reference in New Issue
Block a user