# -*- coding: utf-8 -*- """generator/output 스캔 → content 테이블 upsert. 디스크의 완성 mp4 와 DB 를 잇는다. 시작 시 + 잡 완료 시 호출. """ import re from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from .config import OUTPUT_DIR, ENGINE_SCENARIO from .database import SessionLocal from .models import Content _TITLE_RE = re.compile(r"\[제목\]\s*(.+)") def _title(job_dir) -> str: txt = job_dir / "narration.txt" if txt.exists(): for line in txt.read_text(encoding="utf-8", errors="ignore").splitlines(): m = _TITLE_RE.match(line.strip()) if m: return m.group(1).strip() return job_dir.name def _scan() -> list[dict]: rows = [] if not OUTPUT_DIR.is_dir(): return rows for engine, sc in ENGINE_SCENARIO.items(): d = OUTPUT_DIR / engine if not d.is_dir(): continue for job in d.iterdir(): if not job.is_dir(): continue mp4s = sorted(job.glob("*.mp4")) if not mp4s: continue rel = mp4s[0].relative_to(OUTPUT_DIR).as_posix() rows.append({"id": job.name, "sc": sc, "title": _title(job), "video": f"/videos/{rel}"}) return rows async def sync_output(session: AsyncSession | None = None, owner_uuid: str | None = None) -> int: """새 output 폴더를 content 로 삽입. 삽입 개수 반환.""" own = session is None session = session or SessionLocal() try: existing = set((await session.execute(select(Content.id))).scalars().all()) added = 0 for r in _scan(): if r["id"] in existing: continue session.add(Content( id=r["id"], scenario=r["sc"], title=r["title"], video=r["video"], owner_uuid=owner_uuid, )) added += 1 if added: await session.commit() return added finally: if own: await session.close()