ssulbox/backend/app/content_sync.py

68 lines
2.0 KiB
Python

# -*- 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()