
    3iU@                        d Z ddlmZ ddlZddlZddlZddlmZ ddlZddl	m
Z
  ed      Z ed      Z ed      Zed	z  Zed
z  ZdZdZdZdZdZddZddZdZdZddZd Zedk(  r e        yy)u   Cell-7 서울대보험쌤 × 정당한 보상 배너 생성 (v3.2 최종본)
- meta-feed-1080x1080.png  (Template B: 전체 배경 + 크림 패널)
- google-resp-1200x628.png (Template A: 좌측 텍스트 + 우측 배경)
    )annotationsN)Path)sync_playwrightz&/home/jay/workspace/tools/ai-image-genz2/home/jay/workspace/output/banners/cell-7-snu-fairzT/home/jay/workspace/output/meta-ads/concept-catalog/45-oneshow-finance-luxury/bg.jpgzbg-cell7-1080.pngzbg-cell7-1200.pngz0https://generativelanguage.googleapis.com/v1betaz)gemini-2.0-flash-preview-image-generationzgemini-2.0-flash-expa?  Warm cozy study room with mahogany bookshelves filled with books, a vintage desk lamp casting warm golden light, leather armchair, reading glasses on an open notebook, warm brown and amber tones, intimate and professional atmosphere, photorealistic interior photography, no people, no text, no logos. Square 1:1 format.aT  Wide panoramic view of a warm professional study with floor-to-ceiling mahogany bookshelves, vintage brass desk lamp glowing warmly, leather-bound books and a coffee cup on the desk, golden hour sunlight filtering through curtains, warm brown and amber atmosphere, photorealistic, no people, no text, no logos. Wide landscape 1.91:1 format.c                     t         j                  j                  dt        t                     dd l} | j                  d      xs dS )Nr   GEMINI_API_KEY'AIzaSyDEy7IcOoTbQsI4nxfPOw3ZFbYqEL_PgFU)syspathinsertstrBASE_DIRgcloud_authget_api_key)r   s    L/home/jay/workspace/tools/ai-image-gen/_backup/gen_cell7_snu_fair_banners.pyr   r   3   s3    HHOOAs8}%""#34a8aa    c                   |j                         r/|j                         j                  dkD  rt        d| d|        yt	               }dd| igigddd	gid
}t
        t        dg}|D ][  }t         d| d| }t        d| d| d       	 t        j                  ||d      }|j                  dk7  r)t        d|j                   d|j                  dd         u|j                         }
|
j                  dg       }|st        d       |d   j                  di       j                  dg       }t        d |D        d      }|s5t        d|D cg c]  }t!        |j#                                c}        t%        j&                  |d   d         }|j)                  |       t        d| d t+        |      d!d"        y y## t        $ r}	t        d|	        Y d}	~	}d}	~	ww xY wc c}w )$u>   Gemini API로 배경 이미지 생성. 성공 시 True 반환.i0u  [u   ] 기존 배경 재사용: TpartstextresponseModalitiesIMAGETEXT)contentsgenerationConfigzgemini-1.5-flashz/models/z:generateContent?key=u   ] Gemini 요청 중 (모델: z)...x   )jsontimeoutu     요청 예외: N   z  HTTP z: 
candidatesu     candidates 없음r   contentc              3  *   K   | ]  }d |v s|  yw)
inlineDataN ).0ps     r   	<genexpr>z-generate_gemini_background.<locals>.<genexpr>Z   s     A|q/@1As   	u!     inlineData 없음. parts keys: r"   dataz  [OK]  (,z bytes)F)existsstatst_sizeprintr   GEMINI_MODELGEMINI_FALLBACK_MODELGEMINI_API_BASErequestspost	Exceptionstatus_coder   r   getnextlistkeysbase64	b64decodewrite_byteslen)promptout_pathlabelapi_keypayloadmodelsmodelurlresper'   r   r   
image_partr%   	img_bytess                   r   generate_gemini_backgroundrI   9   s	   X]]_44v=%3H:>?mG 01231GV3DEG
 13EFF  !%0EgYO%5eWDAB	==7C@D
 s"GD,,-R		$3/@AByy{XXlB/
')1!!)R044WbAAeA4H
5u6U!tAFFH~6U5VWX$$Z%=f%EF	Y'zC	N1#5W=>9< 3  	%aS)*	" 7Vs   G G-	G*G%%G*u  <!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=1080">
  <style>
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Black.otf') format('opentype'); font-weight: 900; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-ExtraBold.otf') format('opentype'); font-weight: 800; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Bold.otf') format('opentype'); font-weight: 700; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-SemiBold.otf') format('opentype'); font-weight: 600; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Medium.otf') format('opentype'); font-weight: 500; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Regular.otf') format('opentype'); font-weight: 400; }

    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    html, body { width: 1080px; height: 1080px; overflow: hidden; font-family: 'Pretendard', sans-serif; word-break: keep-all; }

    .canvas { position: relative; width: 1080px; height: 1080px; overflow: hidden; }
    .bg-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
    .dark-overlay { position: absolute; inset: 0; background: rgba(62, 39, 35, 0.58); }

    .text-panel {
      position: absolute;
      top: 50%; left: 50%;
      transform: translate(-50%, -50%);
      width: 860px;
      padding: 56px 48px;
      background: rgba(255, 248, 231, 0.82);
      border-radius: 12px;
      backdrop-filter: blur(4px);
      box-shadow: 0 8px 32px rgba(0,0,0,0.2);
      display: flex; flex-direction: column;
      align-items: center;
      gap: 28px; text-align: center;
    }

    .badge {
      display: inline-block;
      background: #C9A84C; color: #1A0E00;
      font-size: 40px; font-weight: 700;
      height: 52px; line-height: 52px;
      padding: 0 24px;
      border-radius: 6px;
      white-space: nowrap;
      letter-spacing: -0.03em;
    }

    .headline {
      font-size: 60px; font-weight: 700;
      color: #3E2723; line-height: 1.25;
      letter-spacing: -1.5px;
    }
    .headline .gold { color: #C9A84C; }

    .sub-copy {
      font-size: 44px; font-weight: 500;
      color: #A07828;
      white-space: nowrap;
      letter-spacing: -0.02em;
    }

    .sub-copy-2 {
      font-size: 44px; font-weight: 500;
      color: #A07828;
      white-space: nowrap;
      letter-spacing: -0.02em;
    }

    .cta-btn {
      display: inline-block;
      background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
      color: #1A0E00;
      font-size: 48px; font-weight: 700;
      height: 76px; line-height: 76px;
      padding: 0 40px;
      min-width: 360px;
      width: auto;
      border-radius: 6px;
      box-shadow: 0 6px 24px rgba(201,168,76,0.45);
      white-space: nowrap;
      letter-spacing: -0.03em;
      text-align: center;
    }
  </style>
</head>
<body>
  <div class="canvas">
    <img class="bg-image" src="bg-cell7-1080.png" alt="background">
    <div class="dark-overlay"></div>
    <div class="text-panel">
      <span class="badge">서울대보험쌤</span>
      <p class="headline">3년째 참았던 수수료,<br>저는 <span class="gold">바꿨어요</span></p>
      <p class="sub-copy">경력직 직전연봉 최대 50% 정착지원금</p>
      <p class="sub-copy-2">검증된 조직</p>
      <div class="cta-btn">수익 구조 직접 확인 →</div>
    </div>
  </div>
</body>
</html>
u  <!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=1200">
  <style>
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Black.otf') format('opentype'); font-weight: 900; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-ExtraBold.otf') format('opentype'); font-weight: 800; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Bold.otf') format('opentype'); font-weight: 700; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-SemiBold.otf') format('opentype'); font-weight: 600; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Medium.otf') format('opentype'); font-weight: 500; }
    @font-face { font-family: 'Pretendard'; src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Regular.otf') format('opentype'); font-weight: 400; }

    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    html, body { width: 1200px; height: 628px; overflow: hidden; font-family: 'Pretendard', sans-serif; word-break: keep-all; }

    .canvas { position: relative; width: 1200px; height: 628px; overflow: hidden; }
    .bg-image { position: absolute; right: 0; top: 0; width: 65%; height: 100%; object-fit: cover; object-position: center right; }

    .gradient-overlay {
      position: absolute; inset: 0;
      background: linear-gradient(
        to right,
        rgba(62,39,35,0.95) 0%,
        rgba(62,39,35,0.95) 40%,
        rgba(62,39,35,0.85) 52%,
        rgba(62,39,35,0.50) 68%,
        rgba(62,39,35,0.15) 82%,
        transparent 100%
      );
    }

    .accent-bar {
      position: absolute;
      top: 80px; left: 0;
      width: 4px; height: 460px;
      background: linear-gradient(to bottom, #C9A84C, #D4B87A);
      border-radius: 2px;
    }

    .text-area {
      position: absolute;
      top: 0; left: 0;
      width: 62%; height: 100%;
      padding: 48px 56px 48px 60px;
      display: flex; flex-direction: column;
      justify-content: center;
      gap: 20px;
    }

    .badge {
      display: inline-block;
      background: #C9A84C; color: #1A0E00;
      font-size: 40px; font-weight: 700;
      height: 48px; line-height: 48px;
      padding: 0 20px;
      border-radius: 6px;
      white-space: nowrap;
      letter-spacing: -0.03em;
      align-self: flex-start;
      margin-bottom: 6px;
    }

    .headline {
      font-size: 54px; font-weight: 700;
      color: #FFF8E7; line-height: 1.2;
      letter-spacing: -1.2px;
    }
    .headline .gold { color: #C9A84C; }

    .sub-copy {
      font-size: 44px; font-weight: 500;
      color: #C9A84C;
      text-shadow: 0 1px 3px rgba(0,0,0,0.5);
      white-space: nowrap;
      letter-spacing: -0.02em;
    }

    .sub-copy-2 {
      font-size: 40px; font-weight: 500;
      color: rgba(255,248,231,0.8);
      text-shadow: 0 1px 3px rgba(0,0,0,0.5);
      white-space: nowrap;
    }

    .cta-btn {
      display: inline-block;
      background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
      color: #1A0E00;
      font-size: 44px; font-weight: 700;
      height: 56px; line-height: 56px;
      padding: 0 32px;
      min-width: 220px;
      width: auto;
      border-radius: 6px;
      box-shadow: 0 4px 16px rgba(201,168,76,0.35);
      white-space: nowrap;
      letter-spacing: -0.03em;
      align-self: flex-start;
      text-align: center;
      margin-top: 16px;
    }
  </style>
</head>
<body>
  <div class="canvas">
    <img class="bg-image" src="bg-cell7-1200.png" alt="background">
    <div class="gradient-overlay"></div>
    <div class="accent-bar"></div>
    <div class="text-area">
      <span class="badge">서울대보험쌤</span>
      <p class="headline">3년째 참았던 수수료,<br>저는 <span class="gold">바꿨어요</span></p>
      <p class="sub-copy">경력직 직전연봉 최대 50%<br>정착지원금 | 검증된 조직</p>
      <div class="cta-btn">수익 구조 직접 확인 →</div>
    </div>
  </div>
</body>
</html>
c           
        t               5 }|j                  j                         }	 |j                  ||d      }|j	                  d| j                          d       |j                  d       |j                  t        |      ddd||d	
       |j                         j                  dz  }t        d|j                   d| d       |j                          	 ddd       y# |j                          w xY w# 1 sw Y   yxY w)u-   Playwright로 HTML을 PNG로 캡처합니다.)widthheight)viewportzfile://networkidle)
wait_untili	  pngr   )xyrK   rL   )r
   typeclip   u     [렌더링 완료] r(    KB)N)r   chromiumlaunchnew_pagegotoresolvewait_for_timeout
screenshotr   r+   r,   r-   nameclose)	html_pathrK   rL   r>   r%   browserpagesize_kbs           r   render_html_to_pngrd   J  s    		 a**##%	##u-O#PDII	 1 1 345-IP!!$'OO]1uG  
 mmo--5G)(--7)4HIMMO  MMO s#   C;B%C&C;&C88C;;Dc                 d   t        d       t        d       t        d       t        j                  dd       t        d       t        t        t
        d      } | sBt        dt                dd l}|j                  t        t
               t        d	t
                t        t        t        d
      }|sBt        dt                dd l}|j                  t        t               t        d	t                t        d       t        dz  }t        dz  }|j                  t        d       t        d|        |j                  t        d       t        d|        t        d       t        dz  }t        dz  }t        d       t        |dd|       t        d       t        |dd|       t        d       t        d       t
        t        ||||g}|D ]O  }|j                         r.t        d| d|j!                         j"                  dz   d       At        d| d        Q t        d       y )!Nz<============================================================u;   Cell-7 서울대보험쌤 × 정당한 보상 배너 생성T)parentsexist_oku!   
[Step 1] 배경 이미지 생성u   1080x1080 배경u#     Gemini 실패 → 폴백 사용: r   u     폴백 복사 완료: u   1200x628 배경u   
[Step 2] HTML 파일 저장zmeta-feed-1080x1080.htmlzgoogle-resp-1200x628.htmlzutf-8)encodingu
     저장: u   
[Step 3] Playwright 렌더링zmeta-feed-1080x1080.pngzgoogle-resp-1200x628.pngu     1080x1080 렌더링 중...i8  u     1200x628 렌더링 중...i  it  z=
============================================================u   완료!z  OK  z  (rU   rV   z  !!  u
     (없음))r-   
OUTPUT_DIRmkdirrI   PROMPT_1080BG_1080_PATHFALLBACK_BGshutilcopy2PROMPT_1200BG_1200_PATH
write_text	HTML_1080	HTML_1200rd   r*   r+   r,   )	ok_1080rn   ok_1200html_1080_pathhtml_1200_pathout_1080out_1200filesfs	            r   mainr}   _  s   	(O	
GH	(OTD1 

./(lDVWG3K=AB[,/(78(lDUVG3K=AB[,/(78 

)*"<<N"==Ni':	J~&
'(i':	J~&
'( 

+,55H66H	
()~tT8<	
'(~tS(; 
/	)<S[\E *88:F1#S!1!1T!9 :$?@F1#Z()	*
 
(Or   __main__)returnr   )r=   r   r>   r   r?   r   r   bool)
r`   r   rK   intrL   r   r>   r   r   None)__doc__
__future__r   r9   r	   timepathlibr   r1   playwright.sync_apir   r   ri   rm   rl   rq   r0   r.   r/   rk   rp   r   rI   rs   rt   rd   r}   __name__r#   r   r   <module>r      s   
 #  
    / 89FG
ij////D:. 7 . b+`c	Jw	x*=@ zF r   