Files
C.E.L_Slide_test2/scripts/verify_core_v3.py
kyeongmin 29f56187c0 Phase P~S 전체 작업물: 검증 스크립트, 블록 템플릿, 설계 문서, 코드 수정
포함 내용:
- Phase P/Q/R/S 설계 문서 (IMPROVEMENT-PHASE-*.md)
- 영역별 검증 스크립트 (scripts/verify_*.py, test_*.py)
- 블록 템플릿 추가 (cards, emphasis 변형)
- 코드 수정: block_search, content_editor, design_director, slide_measurer
- catalog.yaml 블록 목록 업데이트
- CLAUDE.md, PROGRESS.md, README.md 업데이트

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 08:38:06 +09:00

136 lines
5.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""검증 B 재시도: 본심 — 참고 이미지 구조 반영.
참고 이미지 구조:
- DX 박스(이미지+텍스트) | BIM 박스(이미지+텍스트) 좌우 나란히
- 각 박스 안에 관련 이미지 + 설명
- 비교표는 팝업(details)으로 오른쪽 상단
"""
from __future__ import annotations
import asyncio, sys, time, datetime, base64, re
from pathlib import Path
ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(ROOT))
async def main():
from src.slide_measurer import capture_slide_screenshot
from src.config import settings
import anthropic
out_dir = ROOT / "data" / "runs" / f"verify_core_v3_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}"
out_dir.mkdir(parents=True, exist_ok=True)
client = anthropic.AsyncAnthropic(api_key=settings.anthropic_api_key)
t0 = time.time()
prompt = """다음 콘텐츠를 본심 영역 HTML로 만들어라. 707px × 293px.
## 참고 레이아웃 (이 구조를 따르라)
실제 기획서 슬라이드의 본심 영역 레이아웃:
- 좌우 2단으로 DX 영역과 BIM 영역이 나란히 배치
- 각 영역 안에 관련 이미지/다이어그램 + 핵심 설명 텍스트
- 상단 오른쪽에 "📊 상세 비교표 보기" 팝업 링크
- 하단에 핵심 메시지 강조
## 구조
1. 상단 바: 좌측에 섹션 소제목, 우측에 팝업 링크
- 좌: 빈 공간 또는 소제목
- 우: <details><summary>📊 DX vs BIM 상세 비교표</summary>
표 내용:
| 기준 | DX | BIM |
| 범위 | BIM << DX (Engineering + Management 통합) | Only 3D (형상 구현 중심) |
| 프로세스 | 근본적 문제의식을 통한 개선 | 기존 2D 설계 방식 유지 |
| 활용 | 설계/시공 생산성 혁신 | 3D 모델에 의한 일반적 이해 향상 |
| 확장성 | 전 생애주기 활용 시스템 | (설계/시공/운영) 분야별 단절 |
| 주체 | 자체 수행 능력 | S/W 제작사 판매 정책에 의존 |
</details>
2. 본문: 좌우 2단 (각 50%)
왼쪽 — DX (디지털 전환):
- 상단: 이미지 <img src="/assets/images/dx1.png" style="width:100%; border-radius:6px;">
(이미지가 없으면 placeholder: 연한 파란 배경 + "DX 기술융합 관계도" 텍스트)
- 하단 텍스트:
"DX (Digital Transformation) : 상위개념"
• BIM, GIS, 디지털 트윈 등 핵심기술의 융합을 통해서만 실현 가능
• Engineering + Management 통합
• 전 생애주기 활용 시스템
오른쪽 — BIM:
- 상단: placeholder 이미지 (연한 초록 배경 + "BIM 3D 모델 기반" 텍스트, border-radius:6px)
- 하단 텍스트:
"BIM (Building Information Modeling) : 하위기술"
• Only 3D (형상 구현 중심)
• 기존 2D 설계 방식 유지
• (설계/시공/운영) 분야별 단절
3. 하단: 핵심 메시지
- background: #f0f9ff, border: 2px solid #bae6fd, border-radius: 8px
- "BIM ≠ DX — BIM은 DX를 실현하기 위한 핵심 기술 중 하나일 뿐이다"
- "BIM ≠ DX": color: #dc2626, font-weight: 900
## 디자인
- DX 영역: border-left: 3px solid #2563eb
- BIM 영역: border-left: 3px solid #10b981
- 이미지 placeholder: height: 100px, border-radius: 6px, display:flex, align-items:center, justify-content:center
- DX placeholder: background: #eff6ff, color: #2563eb
- BIM placeholder: background: #f0fdf4, color: #10b981
- 제목: 12px bold
- 불릿: 11px #475569, line-height: 1.5
- <summary>: 11px bold #2563eb, cursor: pointer, float: right 또는 text-align: right
- 표: font-size: 10px, 헤더 #1e293b/white
- 전체 293px 안에 맞출 것
HTML + inline <style>만 반환. 설명 없이 코드만."""
print("=== 검증 B v3: 본심 (참고 이미지 구조) ===")
try:
response = await client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=8192,
messages=[{"role": "user", "content": prompt}],
)
text = response.content[0].text if response.content else ""
match = re.search(r"```html\s*(.*?)```", text, re.DOTALL)
html = match.group(1).strip() if match else text.strip()
wrapped = f"""<!DOCTYPE html>
<html lang="ko"><head><meta charset="UTF-8">
<style>
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
.slide {{
width: 1280px; height: 720px; overflow: hidden; background: white;
font-family: 'Pretendard Variable', sans-serif;
display: flex; align-items: center; justify-content: center;
}}
.test-container {{ width: 707px; }}
</style>
</head><body>
<div class="slide"><div class="test-container">
{html}
</div></div>
</body></html>"""
(out_dir / "B_core_v3.html").write_text(wrapped, encoding="utf-8")
s = await asyncio.to_thread(capture_slide_screenshot, wrapped)
if s:
(out_dir / "B_core_v3.png").write_bytes(base64.b64decode(s))
print(f" [{time.time()-t0:.0f}s] 완료")
print(f" 결과: {out_dir}")
except Exception as e:
print(f" 오류: {e}")
if __name__ == "__main__":
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s", datefmt="%H:%M:%S")
logging.getLogger("selenium").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("httpx").setLevel(logging.WARNING)
asyncio.run(main())