
    imK                    d   d Z ddlmZ ddl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e      j                  Zej                  j!                  d ee             ddlZ ed      Zej)                  dd       d	Zd
ZdZdZdZdZdZddZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZedk(  r e        yy)u=  Cell-2 인카다이렉트 × 관리자/조직 비전 배너 생성기.

Gemini API로 임원급 고층 오피스 야경 배경을 생성하고,
HTML/CSS + Playwright로 한글 텍스트를 정밀하게 오버레이합니다.

산출물:
  - /home/jay/workspace/output/banners/cell-2-incar-leader/meta-feed-1080x1080.html
  - /home/jay/workspace/output/banners/cell-2-incar-leader/meta-feed-1080x1080.png
  - /home/jay/workspace/output/banners/cell-2-incar-leader/google-resp-1200x628.html
  - /home/jay/workspace/output/banners/cell-2-incar-leader/google-resp-1200x628.png
    )annotationsN)Path)sync_playwrightz6/home/jay/workspace/output/banners/cell-2-incar-leaderT)parentsexist_okz0https://generativelanguage.googleapis.com/v1betazgemini-2.0-flash-expzgemini-2.5-flash-preview-04-17a   Premium high-rise office interior at night, floor-to-ceiling windows showing city skyline with warm golden lights, dark elegant workspace, leather executive chair, warm ambient lighting from desk lamp, professional meeting room atmosphere, no people, cinematic, ultra-realistic photographa  Panoramic view of city skyline at night from executive office, floor-to-ceiling windows, golden city lights reflecting, dark premium interior visible on left side, warm desk lamp glow, corporate atmosphere, no people, ultra-realistic photograph, landscape formatuU  <!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(10, 22, 40, 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: 24px; text-align: center;
    }}

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

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

    .gold-divider {{
      width: 100%;
      height: 2px;
      background: linear-gradient(to right, transparent, #C9A84C 20%, #C9A84C 80%, transparent);
      opacity: 0.60;
      flex-shrink: 0;
    }}

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

    .urgency {{
      font-size: 40px; font-weight: 500;
      color: #5C4410;
      letter-spacing: -0.02em;
      white-space: nowrap;
    }}

    .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_url}" alt="background">
    <div class="dark-overlay"></div>
    <div class="text-panel">
      <span class="badge">인카금융서비스 TOP사업단</span>
      <p class="headline">지점장 이직, 89일이 <span class="gold">골든타임</span></p>
      <div class="gold-divider"></div>
      <p class="sub-copy">본부 5개 | 지점 10개 | 200명+ 조직</p>
      <p class="urgency">사무실 개설비 지원 | 1200% 룰 시행 전 지금</p>
      <div class="cta-btn">지점장 이직 상담받기 →</div>
    </div>
  </div>
</body>
</html>uM  <!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(10,22,40,0.95) 0%,
        rgba(10,22,40,0.95) 40%,
        rgba(10,22,40,0.85) 52%,
        rgba(10,22,40,0.50) 68%,
        rgba(10,22,40,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: 58px; font-weight: 700;
      color: #FFF8E7; line-height: 1.2;
      letter-spacing: -1.2px;
      white-space: nowrap;
    }}
    .headline .gold {{ color: #C9A84C; }}

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

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

    .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: 12px;
    }}
  </style>
</head>
<body>
  <div class="canvas">
    <img class="bg-image" src="{bg_url}" alt="background">
    <div class="gradient-overlay"></div>
    <div class="accent-bar"></div>
    <div class="text-area">
      <span class="badge">인카금융서비스 TOP사업단</span>
      <p class="headline">지점장 이직, 89일이 <span class="gold">골든타임</span></p>
      <p class="sub-copy">본부 5개 | 지점 10개 | 200명+ 조직</p>
      <p class="urgency">사무실 개설비 지원 | 1200% 룰 시행 전 지금</p>
      <div class="cta-btn">지점장 이직 상담받기 →</div>
    </div>
  </div>
</body>
</html>c                ,   t        d| d       t        j                         }t         d}ddi}d|  dd}d|igd	d
|v rdnddd}t         d}	dd|igigdddgid}
d}d}dD ]w  }t         d| d}	 t        d| d| d       t        j                  |||
d      }|j
                  r|} n/t        d| d|j                   d |j                  dd!         d}y ||j
                  st        d| d#      t        d| d$|        |j                         }|j                  d%g       }|s$t        d&t        j                  |      dd        |d'   j                  d(i       j                  dg       }t        d) |D        d      }|5|D cg c]  }d|v s|j                  dd       }}t        d*|dd+        |d,   j                  d-d.      }t        j                  |d,   d/         }d0|v rd1nd2}|j!                  |      }|j#                  |       t        j                         |z
  }t        d| d3|j$                   d4t'        |      d5d6|d7d8	       |S # t        $ r}t        d| d"|        d}Y d}~!d}~ww xY wc c}w )9u?   Gemini API로 배경 이미지를 생성하고 저장합니다.u   [배경:u   ] Gemini API 생성 중...z'/models/imagen-3.0-generate-002:predictContent-Typezapplication/jsonzBearer )Authorizationr	   prompt   1080z1:1z16:9)sampleCountaspectRatio)	instances
parametersz./models/gemini-2.5-flash-image:generateContentpartstextresponseModalitiesIMAGETEXT)contentsgenerationConfigN )zgemini-2.5-flash-imagezgemini-3.1-flash-image-previewzgemini-3-pro-image-previewz/models/z:generateContentz] u
    시도...i,  )headersjsontimeoutu   ] 실패 HTTP z:    u
   ] 예외: u   ] 모든 모델 실패u   ] 사용 모델: 
candidatesu   응답에 candidates 없음: r   contentc              3  *   K   | ]  }d |v s|  yw)
inlineDataN ).0ps     P/home/jay/workspace/tools/ai-image-gen/_backup/gen_cell2_incar_leader_banners.py	<genexpr>z$generate_bg_image.<locals>.<genexpr>c  s     =Q<1+<q=s   	u'   이미지 데이터 없음. 텍스트:    r!   mimeTypez
image/jpegdatajpegz.jpgz.pngu
   ] 완료:  (,z bytes, z.1fu   초))printtimeGEMINI_API_BASErequestspostokstatus_coder   	ExceptionRuntimeErrorr   getdumpsnextbase64	b64decodewith_suffixwrite_bytesnamelen)tokenoutput_pathr   labelstart
imagen_urlheaders_jsonheaders_authimagen_payload
gemini_urlgemini_payloadresponse
used_model	try_modeltry_urler)   r   r   
image_partr$   
text_parts	mime_typeimage_bytesext
final_pathelapseds                              r%   generate_bg_imagerU   )  s%   	HUG5
67IIKE $$$KLJ"$67L #5'**L
  ()$*eO5
N $$$RSJ 01231GV3DEN
 HJ p 	$%Xi[8HI	HUG2i[
;<}}WladeH{{&
~h6J6J5K2hmm\`]`NaMbcd x{{XeW,BCDD	HUG,ZL
9:==?D,+J:4::d;KDS;Q:RSTTqMi,00"=E=%=tDJ16FA&A+aeeFB'F
FDZPRQR^DTUVV<(,,ZFI"":l#;F#CDKi'&VC((-J;'iikE!G	HUG:joo%6b[9I!8LHU\]`Taae
fg=  	HUG:aS12H	$ Gs*   89I'3-I'	J J'	J0J		Jc           
     p   d|j                          }| j                  |      }|j                  |d       t        d|        t        d| d| d       t	               5 }|j
                  j                  d	d
g      }		 |	j                  ||d      }
|
j                  d|j                          d       |
j                  d       |
j                  t        |      ddd||d       t        d|        |	j                          	 ddd       y# |	j                          w xY w# 1 sw Y   yxY w)uY   HTML 템플릿에 배경 이미지 URL을 삽입하고 Playwright로 PNG 캡처합니다.zfile://)bg_urlzutf-8)encodingu   [HTML] 저장: u   [캡처] Playwright로 xu    캡처 중...z--no-sandboxz--disable-gpu)args)widthheight)viewportnetworkidle)
wait_untili	  pngr   )rY   yr[   r\   )pathtypeclipu   [캡처] 저장 완료: N)resolveformat
write_textr-   r   chromiumlaunchnew_pagegotowait_for_timeout
screenshotstrclose)html_contentbg_pathhtml_output_pathpng_output_pathr[   r\   rW   html_filledr$   browserpages              r%   capture_html_to_pngrw   w  sC    w()*F%%V%4K g>	O,-
./	#E7!F8>
BC		 a**##./)J#K
	##u-O#PDII 0 8 8 :;<IW!!$'OO_!5EQ&IO  ,_,=>?MMO  MMO s%   #D,A:D=D,D))D,,D5c                    t        d       t        d       t        d       t        d       	 t        j                         } t        dt        |        d       t        d       t        d	z  }	 t        | |t        d
      }t        d       t        dz  }	 t        | |t        d      }t        d       t        dz  }t        dz  }	 t        t        |||dd       |j                         j                  dz  }t        d| d|dd       t        d       t        dz  }
t        dz  }	 t        t         ||
|dd        |j                         j                  dz  }t        d!| d|dd       t        d#       t        d$       t        d%|        t        d&|        t        d'|        t        d(|        t        d)|
        t        d*|        t        d       y # t        $ r}t        d|        t        d      |d }~ww xY w# t        $ r}t        d|        t        d      |d }~ww xY w# t        $ r}t        d|        t        d      |d }~ww xY w# t        $ r-}t        d|        dd l}	|	j                          Y d }~d }~ww xY w# t        $ r-}t        d"|        dd l}	|	j                          Y d }~ad }~ww xY w)+Nz<============================================================uI   Cell-2 인카다이렉트 × 관리자/조직 비전 배너 생성 시작u!   
[인증] SA 토큰 획득 중...u'   [인증] 토큰 획득 성공 (길이: z chars)u   [인증] 실패: r   u2   
[배경] 1080x1080 배경 이미지 생성 중...zbg-cell2-1080r   u   [배경:1080] 생성 실패: u1   
[배경] 1200x628 배경 이미지 생성 중...zbg-cell2-12001200u   [배경:1200] 생성 실패: u-   
[배너 1] meta-feed-1080x1080 생성 중...zmeta-feed-1080x1080.htmlzmeta-feed-1080x1080.pngi8  )rp   rq   rr   rs   r[   r\   i   u   [배너 1] 완료: r+   z.0fz KB)u   [배너 1] 실패: r   u.   
[배너 2] google-resp-1200x628 생성 중...zgoogle-resp-1200x628.htmlzgoogle-resp-1200x628.pngi  it  u   [배너 2] 완료: u   [배너 2] 실패: z=
============================================================u   Cell-2 배너 생성 완료u     배경 1080: u     배경 1200: u     배너 1 HTML: u     배너 1 PNG:  u     배너 2 HTML: u     배너 2 PNG:  )r-   gcloud_authget_access_tokenr>   r4   
SystemExit
OUTPUT_DIRrU   BG_PROMPT_1080BG_PROMPT_1200rw   	HTML_1080statst_size	traceback	print_exc	HTML_1200)r?   rM   bg_path_1080_basebg_path_1080bg_path_1200_basebg_path_1200	html_1080png_1080size_kbr   	html_1200png_1200s               r%   mainr     s   	(O	
UV	(O 

./#,,.7E
|7KL 

?@"_4#(0A>SYZ 

>?"_4#(0A>SYZ 

:;77I55H0" &$	
 --/))D0#H:R}DAB 

;<88I66H0" &$	
 --/))D0#H:R}DAB
 
/	
'(	OL>
*+	OL>
*+	i[
)*	hZ
()	i[
)*	hZ
()	(OI  #!!%&m"#  #-aS12m"#  #-aS12m"#&  0#A3'()--//0&  0#A3'()--//0sy   ,G$ /H H: AI% )AJ $	H-HH	H7H22H7:	I"II"%	J."JJ	K'"KK__main__)
r?   rn   r@   r   r   rn   rA   rn   returnr   )rp   rn   rq   r   rr   r   rs   r   r[   intr\   r   r   None)r   r   ) __doc__
__future__r   r9   r   sysr.   pathlibr   r0   playwright.sync_apir   __file__parentTOOL_DIRrb   insertrn   rz   r}   mkdirr/   MODEL_IDFALLBACK_MODEL_IDr~   r   r   r   rU   rw   r   __name__r"       r%   <module>r      s  
 #   
    / >   3x= ! JK
 
    - E!4 
7  l	`y	|I\  	
   
DNb zF r   