71 lines
2.6 KiB
Python
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())
|