
    z&i.                     t   d Z ddlZddlZddlZddl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mZ ddlZ ej                  d      ZdZ e
d      Zdee   fd	Zd(d
edee   defdZdededee   fdZdedededee   fdZ	 d)dededededee   f
dZ	 d(d
ededee   dee   fdZ	 d*d
ede
dede
fdZd+de
dedefdZedk(  rr ej>                  ej@                  d       dZ! e       Z"e"r( e#d         ee!d!      Z$e$r e#d"e$        y e#d#       y e#d$        ee!ed%z  d&      Z% e#d'e%        yy),u+  
Genesis Clone Pipeline — Netlify Deployment Module
===================================================
Deploys cloned HTML to Netlify via API (automated, no UI needed).
Falls back to local file server if no Netlify token is available.

Netlify API docs: https://docs.netlify.com/api/get-started/
    N)Path)Optionalzclone_pipeline.deployerzhttps://api.netlify.com/api/v1z3/mnt/e/genesis-system/scripts/clone_pipeline/outputreturnc                      dD ]'  } t         j                  j                  |       }|s%|c S  	 t        j                  j                  dd       ddlm}  |d      xs  |d      }|r|S 	 y# t        $ r Y yw xY w)z7Resolve Netlify personal access token from environment.)NETLIFY_TOKENNETLIFY_ACCESS_TOKENNETLIFY_AUTH_TOKENr   z/mnt/e/genesis-system/core)_get_envr   r   N)	osenvirongetsyspathinsertsecrets_loaderr
   	Exception)keyvalr
   tokens       8/mnt/e/genesis-system/scripts/clone_pipeline/deployer.py_get_netlify_tokenr   %   s    N jjnnS!J78+)MX6L-ML 
   s   ;A, ,	A87A8html_contentextra_filesc                 "   t        j                         }t        j                  |dt        j                        5 }|j                  d| j                  d             |j                  dd       |j                  dd       |r\|j                         D ]I  \  }}t        |t              r"|j                  ||j                  d             8|j                  ||       K ddd       |j                         S # 1 sw Y   |j                         S xY w)	z
    Create an in-memory ZIP file for Netlify deployment.

    Args:
        html_content: The main index.html content
        extra_files: Optional dict of {filename: content} for additional files

    Returns:
        Bytes of the ZIP archive
    w
index.htmlutf-8
_redirectsz/* /index.html 200
z
robots.txtzUser-agent: *
Allow: /
N)ioBytesIOzipfileZipFileZIP_DEFLATEDwritestrencodeitems
isinstancestrgetvalue)r   r   
zip_bufferzffilenamecontents         r   _create_zipr.   =   s     J	S'*>*>	? 32
L,"5"5g">? 	L"89 	L"=>%0%6%6%8 3!'gs+KK'..*ABKK'2	33    !3    s   B$C66Dr   	site_namec                    dj                  d |j                         j                  dd      D              }ddl}|j	                  dd|      j                  d      }t        |      dk  rd	| }t        |      d
kD  r|dd
 j                  d      }t        j                  |j                               j                         dd }| d| dd
 }t        j                  d|        	 t        j                  t          dd|  ddd|id      }|j#                          |j%                         }|d   |j'                  d      xs |j'                  d      |j'                  d      |j'                  d      dS # t        j(                  j*                  $ r"}|j,                  j.                  dk(  rd| }	t        j                  d|	        	 t        j                  t          dd|  ddd|	id      }
|
j#                          |
j%                         }|d   |j'                  d      xs |j'                  d      |j'                  d      |j'                  d      dcY d}~S # t0        $ r&}t        j3                  d|        Y d}~Y d}~yd}~ww xY wt        j3                  d|        Y d}~yd}~wt0        $ r"}t        j3                  d|        Y d}~yd}~ww xY w)zy
    Create a new Netlify site and return site info.

    Returns dict with 'id' and 'url' keys, or None on failure.
     c              3   N   K   | ]  }|j                         s|d k(  r|nd   yw)-N)isalnum).0cs     r   	<genexpr>z'_create_netlify_site.<locals>.<genexpr>c   s+       YY[AH#-s   #% r3   r   Nz-{2,}   zgenesis-?      z"[Deployer] Creating Netlify site: z/sitesBearer zapplication/jsonAuthorizationzContent-Typename   )headersjsontimeoutidssl_urlurl	admin_url)rD   rF   r?   rG   i  zgenesis-tradie-z[Deployer] Name taken, trying: z*[Deployer] Fallback site creation failed: z![Deployer] Site creation failed: z+[Deployer] Unexpected error creating site: )joinlowerreplaceresubstriplenrstriphashlibmd5r%   	hexdigestloggerinforequestspostNETLIFY_API_BASEraise_for_statusrB   r   
exceptions	HTTPErrorresponsestatus_coder   error)r   r/   
clean_namerK   suffix
final_namerespdataealt_nameresp2data2e2s                r   _create_netlify_siterh   \   s     "**34 J
 #z288=J
:
|,

:_++C0
 [[))+,668!<F<q)#2.J
KK4ZLAB0}} '#*5'!2 2 *%
 	yy{t*88I&9$((5/HHV$+.	
 	
 (( ::!!S((1HKK9(DE '(/+25'):(: !(+ &&(

+ 99Y/C599U3C!IIf-!&;!7	   I"NOt 	8<= B1#FGsP   )BE; ;K$6J6BI'!K$'	J0JJ6JJ66K$KK$site_id	zip_bytesc           	      4   t         j                  dt        |       d| d       	 t        j                  t
         d| dd|  dd|d	
      }|j                          |j                         }|j                  d      }|j                  dd      }t         j                  d| d|        |j                  d      xs |j                  d      }|dvrt        | ||d      }|rt         j                  d|        |S # t        j                  j                  $ rP}t         j                  d|j                  j                   d|j                  j                  dd         Y d}~yd}~wt         $ r"}t         j                  d|        Y d}~yd}~ww xY w)zo
    Deploy a ZIP file to an existing Netlify site.

    Returns the live URL on success, None on failure.
    z[Deployer] Deploying ZIP (z bytes) to site z.../sites/z/deploysr<   zapplication/zipr=   x   )rA   rb   rC   rD   stateunknownz[Deployer] Deploy created: z	, state: rE   deploy_ssl_urlreadycurrent<   )rC   z[Deployer] Site live at: z[Deployer] Deploy failed HTTP z: Ni  z[Deployer] Deploy failed: )rS   rT   rN   rU   rV   rW   rX   rB   r   _wait_for_deployrY   rZ   r]   r[   r\   textr   )	r   ri   rj   ra   rb   	deploy_idrn   site_urlrc   s	            r   _deploy_zip_to_sitery      s    KK,S^,<<LWIUXYZ }} y9#*5'!2 1 
 	yy{HHTN	),1)IeWMN 88I&D$((3C*D,,'w	2NHKK3H:>?(( 5ajj6L6L5MRPQPZPZP_P_`dadPeOfgh 1!56s%   CD FAE))F5FFrw   rC   c                    t        j                          }t        j                          |z
  |k  r	 t        j                  t         d| d| dd|  id      }|j	                          |j                         }|j                  dd      }|d	v r$|j                  d
      xs |j                  d      S |dk(  r)t        j                  d|j                  dd              yt        j                  d| d       t        j                  d       t        j                          |z
  |k  rt        j                  d       y# t        $ r7}t        j                  d|        t        j                  d       Y d}~ld}~ww xY w)z.Poll Netlify until deploy is ready or timeout.rl   z	/deploys/r>   r<      )rA   rC   rn   r1   rq   rE   rp   r]   z[Deployer] Deploy errored: error_messagero   Nz[Deployer] Deploy state: z, waiting...   z[Deployer] Poll error: z'[Deployer] Timed out waiting for deploy)timerU   r   rW   rX   rB   rS   r]   rT   sleepr   warning)	r   ri   rw   rC   startra   rb   rn   rc   s	            r   ru   ru      sS    IIKE
))+

'	<<#$GG9Ii[I(GE7*;<D
 !!#99;DHHWb)E,,xx	*Hdhh7G.HH'!:488OU^;_:`abKK3E7,GHJJqM! ))+

'* NN<=  	NN4QC89JJqMM	s$   BE  3-E  !.E   	F 	-E;;F c                    t               }|st        j                  d       yt        ||      }|st        j	                  d       yt        j                  d|d    d|d    d       t        | |      }t        ||d   |      }|rt        j                  d	|        |S |j                  d
      xs	 d|d    d}t        j                  d|        |S )a|  
    Deploy HTML to Netlify via API.

    Args:
        html_content: Complete HTML string to deploy as index.html
        site_name: Name for the Netlify site (will be slugified)
        extra_files: Optional additional files dict {filename: content}

    Returns:
        Live HTTPS URL (e.g. https://bob-s-plumbing-a1b2c3.netlify.app),
        or None if deployment fails.
    z?[Deployer] No NETLIFY_TOKEN found. Skipping Netlify deployment.Nz([Deployer] Failed to create Netlify sitez[Deployer] Site created: r?   z (rD   )z"[Deployer] Deployment successful: rF   zhttps://z.netlify.appz+[Deployer] Deploy initiated, expected URL: )	r   rS   r   rh   r]   rT   r.   ry   r   )r   r/   r   r   	site_inforj   live_urlexpected_urls           r   deploy_to_netlifyr      s    "  EXY %UI6I?@
KK+If,=+>b4@QQRST L+6I"5)D/9EH8
CD !}}U+Y)F:K9LL/YA,PQ    
output_dirr,   c                     |j                  dd       ||z  }|j                  | d       t        j                  d|        |S )zz
    Save HTML to local file as fallback when no Netlify token is available.

    Returns the path to the saved file.
    T)parentsexist_okr   )encodingz[Deployer] HTML saved locally: )mkdir
write_textrS   rT   )r   r   r,   out_paths       r   save_locallyr   #  sM     TD1H$Hw7
KK1(<=Or   portc                     ddl }ddlddl}|j                  j                  j
                  t        |             fd}|j                  |d      }|j                          d S )z^
    Start a simple HTTP server to preview the cloned site locally.

    Returns the URL.
    r   N)	directoryc                      j                   j                  df      5 } t        j                  d        | j	                          d d d        y # 1 sw Y   y xY w)Nz0.0.0.0z4[Deployer] Local server running at http://localhost:)server
HTTPServerrS   rT   serve_forever)httpdhandlerhttpr   s    r   
run_serverz&start_local_server.<locals>.run_serverC  sS    [[##Y$5w? 	"5KKNtfUV!	" 	" 	"s   )AAT)targetdaemonzhttp://localhost:)		threadinghttp.server	functoolspartialr   SimpleHTTPRequestHandlerr(   Threadr   )r   r   r   r   r   threadr   r   s    `    @@r   start_local_serverr   4  si     ,,j/   G
"
 Z=F
LLNtf%%r   __main__z%(levelname)s %(message)s)levelformatzU<html><body><h1>Test Deployment</h1><p>Genesis Clone Pipeline test.</p></body></html>z-Netlify token found, attempting deployment...zgenesis-test-deployz
Deployed: zDeployment failedz'No NETLIFY_TOKEN set, saving locally...testz	test.htmlzSaved: )N)rt   )r   )iS"  )&__doc__r   r   r   rB   r~   loggingr!   rP   pathlibr   typingr   rU   	getLoggerrS   rW   LOCAL_DEPLOY_DIRr(   r   dictbytesr.   rh   ry   intru   r   r   r   __name__basicConfigINFO	test_htmlr   printrF   r    r   r   <module>r      s   
 
 	        			4	5 4 MN HSM 0!c ! !% !>J J J JZ(s (S (U (xPS} (X >@),7:c]J #'*** $* c]	*` !  
	"&4 &s &c &< zGgll3NOgI E=?	+@AJse$%%&78I'7&'@+Nv! r   