
    8j5                       d dl m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
mZ d dlZd dlZd dlZd dlmZ d dlmZmZ d dlmZmZ dZdZ ed	      d
z  Z ej6                  dej8                        Z ed       G d d             Z ed       G d d             Z G d de       Z!d)dZ"d*dZ#d+dZ$d,d-dZ%de%fd.dZ&efd/dZ'd0dZ(d1dZ)d2dZ*d3dZ+d4dZ,d5d6d Z-d7d!Z.e-e.d"	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d8d#Z/e0e%e-e.d$	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d9d%Z1e0e%e-e.d$	 	 	 	 	 	 	 	 	 	 	 	 	 d:d&Z2e0e%e-e.d$	 	 	 	 	 	 	 	 	 	 	 	 	 d:d'Z3d;d<d(Z4y)=    )annotationsN)datetime	timedelta)	dataclass)PathPurePosixPath)CallableMappingz$http://aiwk.yjm.kr/down/_St_ver.htmlz_St_ver.htmlAutoDistributezAutoDistribute.pyzT<meta\s+name=["\'](?P<name>st-[^"\']+)["\']\s+content=["\'](?P<value>.*?)["\']\s*/?>T)frozenc                  :    e Zd ZU ded<   ded<   ded<   dZded<   y)	VersionInfostrversionintbuildfile sha256N)__name__
__module____qualname____annotations__r         D:\_St\Auto8700\st_update8700.pyr   r      s    LJ
IFCr   r   c                  @    e Zd ZU ded<   ded<   ded<   ded<   ded<   y	)
UpdateDecisionr   actionr   localremotebool	publisherreasonN)r   r   r   r   r   r   r   r   r   %   s    KOKr   r   c                      e Zd Zy)UpdateErrorN)r   r   r   r   r   r   r&   r&   .   s    r   r&   c                      t        dddd      S )N0r   _St.zipr   r   r   r   r   )r   r   r   r   empty_versionr+   2   s    s!)BGGr   c           	     >   i }t         j                  | xs d      D ]T  }t        j                  |j	                  d      j                               ||j	                  d      j                         <   V 	 t        |j                  dd            }|dk  rt        d      t        |j                  d	d      xs d||j                  d
d      xs d|j                  dd      j                         j                               S # t        $ r}t        d      |d }~ww xY w)Nr   valuenamezst-buildr(   u0   _St_ver.html st-build가 정수가 아닙니다.r   u5   _St_ver.html st-build는 0 이상이어야 합니다.z
st-versionzst-filer)   z	st-sha256r*   )META_REfinditerhtmlunescapegroupstripcasefoldr   get
ValueErrorr&   r   )textvaluesmatchr   excs        r   parse_version_htmlr<   6   s    F!!$*"-15u{{7?S?Y?Y?[1\u{{6"++-. .WFJJz3/0 qyQRR

<-4ZZ	9-:zz+r*002;;=	 	  WLMSVVWs   4D 	DDDc                    | t         z  }|j                         s
t               S 	 t        |j	                  d            S # t
        $ r}t        dt          d|       |d }~ww xY w)N	utf-8-sig)encodingu   로컬 u    읽기 실패: )LOCAL_VERSION_NAMEis_filer+   r<   	read_text	Exceptionr&   )st_rootpathr;   s      r   read_local_versionrF   H   sj    ''D<<>X!$..+."FGG XG$6#77GuMNTWWXs   A   	A$	AA$      @c           	         t         j                  j                  | ddd      }t         j                  j                  |t	        dt        |                  5 }|j                         j                  dd	      cd d d        S # 1 sw Y   y xY w)
Nno-cacheAuto8700-Updater/1zCache-Controlz
User-Agentheadersg      ?timeoutr>   stricterrors)urllibrequestRequesturlopenmaxfloatreaddecode)urlrO   rT   responses       r   
fetch_textr]   R   sk    nn$$SJ^r2s$tG			S%.1I		Jh}}%%k(%C 
K	J	Js   !BBc                    	 t         || |            S # t        $ r%}t        |t              r t        d|       |d }~ww xY w)Nu   서버 버전 확인 실패: )r<   rC   
isinstancer&   )r[   rO   getterr;   s       r   fetch_remote_versionra   X   sN    J!&g"677 Jc;'9#?@cIJs    	A =Ac                :    | t        |      z  j                         S N)r   rA   )rD   markers     r   is_publisherre   a   s    d6l"++--r   c                   |rt        d| |dd      S |j                  | j                  kD  rt        d| |dd      S |j                  | j                  k(  rt        d| |dd      S t        d	| |dd
      S )NPUBLISHER_SKIPTu&   배포자 AutoDistribute marker 감지UPDATEFu    서버 build가 로컬보다 큼SAMEu   build 동일LOCAL_NEWERu    로컬 build가 서버보다 큼)r   r   )r    r!   r#   s      r   decide_updaterk   e   su    .vtEmnn||ekk!hvu>`aa||u{{"feVUNKK-?abbr   c                ^    t         j                  j                  | |j                  xs d      S )Nr)   )rS   parseurljoinr   )version_urlr!   s     r   remote_zip_urlrp   o   s"    <<V[[-EIFFr   c                    t        j                         }| j                  d      5 t        fdd      D ]  }|j	                  |        	 d d d        |j                         j                         S # 1 sw Y   'xY w)Nrbc                 &     j                  d      S )N   )rY   )handles   r   <lambda>zsha256_file.<locals>.<lambda>v   s    &++k":r   r   )hashlibr   openiterupdate	hexdigestr5   )rE   digestchunkru   s      @r   sha256_filer~   s   sb    ^^F	4F:C@EMM%  A 
 &&(( 
s   &A44A=c                Z   d}t        j                  | d      5 }|j                         }|rt        d|       |j	                         D ]  }|j
                  j                  dd      }t        |      }|j                         sd|j                  v rt        d|j
                         |j                  r |j                  d   j                         dk7  rt        d	|j
                         |j                         r|d
z  } 	 d d d        |dk(  rt        d      |S # 1 sw Y   xY w)Nr   ru   업데이트 ZIP CRC 오류: \/z..u    업데이트 ZIP 위험 경로: _stu#   업데이트 ZIP base_root 위반:    u(   업데이트 ZIP이 비어 있습니다.)zipfileZipFiletestzipr&   infolistfilenamereplacer   is_absolutepartsr5   is_dir)rE   countzfbadinfo
normalizedps          r   validate_update_zipr   {   s   E	s	#rjjl =cUCDDKKMD..tS9Jj)A}}$!''/!$DT]]O"TUU77aggaj113u<!$G"WXX;;=
 "	 
$ zDEEL 
$	#s   C%D!?D!!D*c                T   t        j                  | d      5 }	 |j                  d      }	 d d d        	 t        j                  dd            S # t        $ r}t	        d      |d }~ww xY w# 1 sw Y   CxY w# t        $ r%}t        |t              r t	        d|       |d }~ww xY w)Nr   z_St/_St_ver.htmlu9   업데이트 ZIP 내부 _St/_St_ver.html이 없습니다.r>   rP   rQ   u(   ZIP 내부 버전 파일 읽기 실패: )	r   r   rY   KeyErrorr&   r<   rZ   rC   r_   )rE   r   rawr;   s       r   read_zip_versionr      s    	s	#r	d'',-C 
$
U!#**[*"JKK  	dYZ`cc	d 
$	#  Uc;'DSEJKQTTUs?   A-AA9 	A*A%%A**A--A69	B' B""B'c           	     d   |j                   j                  dd       |j                  |j                  dz         }|j	                  d       t
        j                  j                  | ddd      }	 t
        j                  j                  |t        d	t        |            
      5 }|j                  d      5 }t        j                  ||d       d d d        d d d        t        j                  ||       |S # 1 sw Y   )xY w# 1 sw Y   -xY w# t         $ r |j	                  d        w xY w)NTparentsexist_okz.part
missing_okrI   rJ   rK   rL   rG   rN   wbrt   )length)parentmkdirwith_suffixsuffixunlinkrS   rT   rU   rV   rW   rX   rx   shutilcopyfileobjosr   rC   )r[   targetrO   temprT   r\   outs          r   download_zipr      s    
MMt4fmmg56DKK4K nn$$SJ^r2s$tG^^##GSeGn5M#NRZ\`\e\efj\korx[A ]lN


4  M ]l\kNN  t$s<   34D 'D9C:DD :D	?DDD D/c                l   t        |      t        j                  t        j                  t        j                  d}t        j                  j                  d      rFd}|t        t        t        dd            z  }|t        t        t        dd            z  }||d<   d|d<   t        j                  | fi |S )	N)cwdstdinstdoutstderrwinr   DETACHED_PROCESSCREATE_NEW_PROCESS_GROUPcreationflagsT	close_fds)	r   
subprocessDEVNULLsysplatform
startswithr   getattrPopen)commandr   kwargsflagss       r   _spawn_detachedr      s    s8j.@.@JL^L^jtj|j|}F
||u%WZ);Q?@@WZ)CQGHH"'"{G.v..r   )
downloaderspawnerc                   |j                   r t        j                  d|j                         st        d      t	        t        j                               dz  d|j                   z  }|j                  dd       |dz  }t        ||      }	 |d|j                           ||	||        |d	|         |d
       t        |      }
|
|j                   k7  r-|j                  d       t        d|j                    d|
       t        |       t        |      }|j                  |j                  k7  r7|j                  d       t        d|j                   d|j                          |d|
 d|j                          t	        t              j                         j                   dz  }|j#                         st        d|       |dz  }t%        j&                  ||       | dz  dz  }t(        j*                  t-        |      dt-        t/        j0                               dt-        |      dt-        |       dt-        |      dt-        |j                        g} |d        |||        |d|j                          |S )Nz[0-9a-f]{64}uK   서버 _St_ver.html의 SHA256이 없거나 형식이 잘못되었습니다.st_update8700build_Tr   r)   uC   [자동업데이트][UP-03][체크시작] ZIP 다운로드 / build=uD   [자동업데이트][UP-03][체크완료] ZIP 다운로드 완료 / uC   [자동업데이트][UP-04][체크시작] SHA256·ZIP 구조 검증r   u   SHA256 불일치 / server=z local=u$   서버/ZIP build 불일치 / server=z zip=uI   [자동업데이트][UP-04][체크완료] SHA256·ZIP·build 검증 OK / z	 / build=zst_update_apply.pyu   updater 적용 파일 없음: Auto8700zauto_service8700_manager.pyz--parent-pidz--zipz	--st-rootz	--managerz--expected-builduD   [자동업데이트][UP-05][체크시작] TEMP updater 실행 예약uH   [자동업데이트][UP-05][체크완료] updater 실행 예약 / build=)r   re	fullmatchr&   r   tempfile
gettempdirr   r   rp   r~   r   r   r   __file__resolver   rA   r   copy2r   
executabler   r   getpid)rD   r!   ro   rO   loggerr   r   runtimezip_pathr[   actual_hashembeddedsource_apply
apply_copymanagerr   s                   r   prepare_updater      sW    ==_fmm Lghh8&&()O;v||n>UUGMM$M."H
f
-C
PQWQ]Q]P^_`sHg&
QRZQ[\]
PQh'Kfmm#4(6v}}oW[MZ[[!)H~~%4(@eT\TbTbScdee
VWbVcclmum{m{l|}~>))+225IIL!:<.IJJ//J
LLz*
"%BBGJBIIKHGGFLLG QRGW
UV\VbVbUcdeOr   )r   remote_getterr   r   c          
     *   t        | j                  d      t              rt        | j                  d      xs i       ni }t	        |j                  dd            s |d|        yt        |j                  d      xs t              j                         xs t        }t        |j                  d      xs d      }	t        |j                  d	      xs t        t                    j                         }
 |d
|        t        |      }t        ||
      }	 t        ||	|      } |d|j                   d|j                   dt        |       d|        t!        |||      } |d|j"                   d|j$                   d|        |j"                  dk7  ry	 t'        |||t        |j                  d      xs d      |||       y# t        $ r} |d| d| d       Y d}~yd}~ww xY w# t        $ r} |d| d| d       Y d}~yd}~ww xY w)ul   한 번 build를 확인한다. True면 updater를 예약했으므로 현재 Auto8700를 종료해야 한다.auto_updateenabledTuP   [자동업데이트][UP-00][체크완료] 자동업데이트 비활성 / source=Fro   timeout_secrG   publisher_markeruN   [자동업데이트][UP-01][체크시작] 로컬/서버 build 확인 / source=)r`   uO   [자동업데이트][UP-01][체크실패] 서버 버전 확인 실패 / source=z / u    / 현재 버전 계속 실행Nu6   [자동업데이트][UP-01][체크완료] local_build=z server_build=z publisher=z source=)r#   u1   [자동업데이트][UP-02][체크완료] 판단=z
 / source=rh   download_timeout_secg      ^@)rD   r!   ro   rO   r   r   r   uN   [자동업데이트][UP-05][체크실패] 업데이트 준비 실패 / source=)r_   r6   r
   dictr"   r   DEFAULT_VERSION_URLr4   rX   PUBLISHER_MARKERrF   re   ra   rC   r   r   rk   r   r$   r   )cfgrD   sourcer   r   r   r   
update_cfgro   rO   rd   r    r#   r!   r;   decisions                   r   update_check_oncer      s2    8B#''-BXZa7bcggm,23hjJ
y$/0abhaijkjnn]3J7JKQQSjWjKJNN=18S9G 23Ls;K7LMSSUF
[\b[cdew'EWf-I%k7=Q 
@^\b\h\h[i j^$HVH	6
 UFi@H
>x>OsS[SbSbRccmntmuvw("#*..)?@IEJ!	
 A  ]^d]eehe13	
 4  \]c\ddge13	
 s0   G .G0 	G-G((G-0	H9HHc          	     "   t        | j                  d      t              rt        | j                  d      xs i       ni }t	        |j                  dd            rt	        |j                  dd            s	 |d       yt        | |d||||      S )	ul   시작 시 1회 확인. True면 updater를 실행했으므로 현재 Auto8700는 즉시 종료해야 한다.r   r   Tcheck_on_startuY   [자동업데이트][UP-00][체크완료] 시작 버전 체크 비활성 / source=startupFstartuprD   r   r   r   r   r   r_   r6   r
   r   r"   r   r   rD   r   r   r   r   r   s          r   startup_update_checkr   .  s     8B#''-BXZa7bcggm,23hjJ
y$/0Z^^L\^b=c8djk# r   c          	        t        | j                  d      t              rt        | j                  d      xs i       ni }t	        |j                  dd            rt	        |j                  dd            syt        | |d||||      S )uB   실행 중 정시 확인. True면 updater 예약 완료 상태다.r   r   Tcheck_hourlyFhourlyr   r   r   s          r   hourly_update_checkr   G  s~     8B#''-BXZa7bcggm,23hjJ
y$/0Z^^N\`=a8b# r   c                    | xs t        j                         }|j                  ddd      t        d      z   }t	        d||z
  j                               S )uf   로컬 시스템 시각 기준 다음 HH:00:00까지 남은 초. 항상 다음 정시를 반환한다.r   )minutesecondmicrosecondr   )hoursgMbP?)r   nowr   r   rW   total_seconds)r   current	next_hours      r   seconds_until_next_hourr   _  sL    #X\\^GqBYUVEWWIuy7*99;<<r   )returnr   )r8   r   r   r   )rD   r   r   r   )rG   )r[   r   rO   rX   r   r   )r[   r   rO   rX   r`   Callable[[str, float], str]r   r   )rD   r   rd   z
str | Pathr   r"   )r    r   r!   r   r#   r"   r   r   )ro   r   r!   r   r   r   )rE   r   r   r   )rE   r   r   r   )rE   r   r   r   )g      N@)r[   r   r   r   rO   rX   r   r   )r   z	list[str]r   r   r   zsubprocess.Popen)rD   r   r!   r   ro   r   rO   rX   r   Callable[[str], None]r   "Callable[[str, Path, float], Path]r   #Callable[[list[str], Path], object]r   r   )r   Mapping[str, object]rD   r   r   r   r   r   r   r   r   r  r   r  r   r"   )r   r  rD   r   r   r   r   r   r   r  r   r  r   r"   rc   )r   zdatetime | Noner   rX   )5
__future__r   rw   r1   r   r   r   r   r   r   r   r   urllib.parserS   urllib.requestr   dataclassesr   pathlibr   r   typingr	   r
   r   r@   r   compile
IGNORECASEr/   r   r   RuntimeErrorr&   r+   r<   rF   r]   ra   re   rk   rp   r~   r   r   r   r   r   printr   r   r   r   r   r   r   <module>r     s}   "   	 	   
  (    ! ' $< # (),?? 
"**[MM $   $  	, 	H$XD 58_i J 6F .cG)*U/$ 6B3B88 8 	8
 8 "8 38 18 
8@ %*1;5A3B9	9 9 	9
 "9 /9 39 19 
9@ %*1;5A3B	  "	
 / 3 1 
: %*1;5A3B	  "	
 / 3 1 
0=r   