playreel/backend/tests/playreel/test_analyze_poster.py

71 lines
2.6 KiB
Python

"""analyze 수동 확인용.
사용: uv run python -m tests.playreel.test_analyze_poster <goods_id>
test_result/playreel/nol_<goods_id>/upscaled.png 을 쓰고, 없으면 poster.* 로 떨어진다.
ip_risk는 meta.json 의 goods_name 으로 판정한다.
결과는 같은 폴더의 analysis.json 과 review_grid.jpg.
"""
import asyncio
import json
import sys
from pathlib import Path
from models.nol import NolMeta
from services.analyze_poster import analyze_poster
TEST_RESULT_DIR = Path(__file__).parent.parent / "test_result" / "playreel"
def find_poster(product_dir: Path) -> Path:
upscaled = product_dir / "upscaled.png"
if upscaled.exists():
return upscaled
originals = sorted(product_dir.glob("poster.*"))
if not originals:
raise SystemExit(f"{product_dir}에 포스터가 없다 — test_fetch_nol 을 먼저 돌릴 것")
print("※ upscaled.png 가 없어 원본 포스터를 쓴다")
return originals[0]
def load_title(product_dir: Path) -> str:
meta_path = product_dir / "meta.json"
if not meta_path.exists():
return ""
return NolMeta.model_validate_json(meta_path.read_text(encoding="utf-8")).goods_name or ""
async def main() -> None:
goods_id = sys.argv[1]
product_dir = TEST_RESULT_DIR / f"nol_{goods_id}"
poster_path = find_poster(product_dir)
title = load_title(product_dir)
print(f"{title or '(공연명 없음)'} · {poster_path.name}")
analysis = await analyze_poster(poster_path, title)
grid_path = product_dir / "review_grid.jpg"
summary_path = product_dir / "analysis.json"
analysis.grid.save(grid_path, quality=90)
summary_path.write_text(json.dumps({
"model": analysis.model,
"ip_risk": analysis.ip_risk,
"has_qr": analysis.has_qr,
"movable": [choice.model_dump() for choice in analysis.movable],
"fixed": [layer.model_dump() for layer in analysis.fixed],
"prompt": analysis.plan.prompt,
}, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"모델 {analysis.model} · QR {'있음' if analysis.has_qr else '없음'}"
f" · IP 위험 {'있음' if analysis.ip_risk else '없음'}")
print("움직일 요소:")
for choice in analysis.movable:
print(f" {'[o]' if choice.on else '[ ]'} {choice.label:10} {choice.what}")
print("고정 요소: " + " ".join(layer.label for layer in analysis.fixed))
if not any(choice.on for choice in analysis.movable):
print("\n※ 켜진 요소가 없다 — 검수 화면에서 사람이 켜야 i2v로 갈 수 있다")
print(f"\n{grid_path}\n{summary_path}")
if __name__ == "__main__":
asyncio.run(main())