
    i.                       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ZddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ d	ad
ad	ad5d6dZd7dZd8dZd9dZd:dZd;dZd9dZd<dZd=d Zd>d!Zd?d&Zd@d'ZdAd*Z d	dd+dBd0Z!dCdDd2Z"dEd3Z#dFd4Z$dS )Gz.Git backup scheduler for website runtime data.    )annotationsN)datetime)Path)Any)quote)ZoneInfoF valuestrdefaultboolreturnc                |    t          | pd                                                                          }|s|S |dv S )Nr	   >   1onyestrue)r   striplower)r
   r   raws      /app/scripts/website_backup.py_truthyr      sD    
ekr


 
 
"
"
(
(
*
*C ,,,    textc                    t          t          j        d          pd          }t          | pd          }|r|                    |d          n|S )NWEBSITE_BACKUP_PATr	   z***)r   osgetenvreplace)r   patr   s      r   _mask_secretr!      sL    
bi,--3
4
4C
djb//C&)23;;sE"""s2r   c                 F    t          t          j        dd                    S )NWEBSITE_BACKUP_ENABLED0)r   r   r    r   r   _backup_enabledr&   $   s    295s;;<<<r   c                 p    t          t          j        d          pd                                          pdS )NWEBSITE_BACKUP_BRANCHmain)r   r   r   r   r%   r   r   _backup_branchr*   (   s1    ry011;V<<BBDDNNr   	data_rootr   c                ~    t          t          j        d          p| j        pd                                          pdS )NWEBSITE_BACKUP_SUBDIRRENAISS_WEBSITE)r   r   r   namer   )r+   s    r   _backup_subdirr0   ,   s:    ry011XY^XGXYY__aavevvr   c                   t          t          j        d          pd                                          }|r3t	          |                                                                          S | j        dz                                  S )NWEBSITE_BACKUP_REPO_DIRr	   z.renaiss_website_data_repo)r   r   r   r   r   
expanduserresolveparent)r+   r   s     r   _backup_repo_dirr6   0   sr    
bi1228b
9
9
?
?
A
AC
 0Cyy##%%--///;;DDFFFr   c                 p   t          t          j        d          pd                                          } t          t          j        d          pd                                          }| sdS d| v r| S |r?|                     d          r*|                     ddt          |d           dd	          S | S )
NWEBSITE_BACKUP_REPOr	   r   zx-access-token:zhttps://github.com/zhttps://x-access-token:)safez@github.com/   )r   r   r   r   
startswithr   r   )repor    s     r   _resolve_repo_urlr=   7   s    ry.//5266<<>>D
bi,--3
4
4
:
:
<
<C rD  
 st455 s||13nUSV]_M`M`M`3n3n3npqrrrKr   args	list[str]cwdc                L   t          j        dg| t          |          dd          }|j        dk    rW|j        p|j        pd                                }t          dd                    |            dt          |                     |j        pd                                S )	NgitTr@   r   capture_outputr   r	   zgit  z	 failed: )

subprocessrunr   
returncodestderrstdoutr   RuntimeErrorjoinr!   )r>   r@   resultr   s       r   _run_gitrN   C   s    ^UNTNCtTXYYYFA}33::<<N#((4..NN<;L;LNNOOOMR&&(((r   repo_urlbranchc                    t          j        ddd| |gdd          }|j        dk    r-t          dt	          |j        p|j        pd                     t          |j        pd                                          S )	NrB   z	ls-remotez--headsT)r   rD   r   zgit ls-remote failed: r	   )	rF   rG   rH   rK   r!   rI   rJ   r   r   )rO   rP   rM   s      r   _remote_has_branchrR   K   s    ^UKHfMTXimnnnFAhLAeRXR_Aece4f4fhhiii$"++--...r   c                f    t          j        g dt          |           dd          }|j        dk    S )N)rB   diffz--cachedz--quietTrC   r:   )rF   rG   r   rH   )r@   rM   s     r   _has_staged_changesrU   R   s7    ^BBBCW[lpqqqF!!r   sourcetargetinclude_volatileNonec                t   |sdhnt                      }t          j        |d           |                    dd           |                                 D ]b}|j        |v s|j        dk    r||j        z  }|                                rt          j        ||d           Mt          j        ||           cd S )Nzx_intel_jobs.jsonTignore_errorsparentsexist_ok__pycache__Fsymlinks)	setshutilrmtreemkdiriterdirr/   is_dircopytreecopy2)rV   rW   rX   volatile_namesitemdests         r   _copytree_cleanrn   W   s    2BM)**N
M&----
LLL---   % %9&&$)}*D*D	!;;== 	%OD$77777Lt$$$$% %r   c                F   |                     dd           |                                D ]^}|j        dk    r|                                rt	          j        |d           9	 |                                 O# t          $ r Y [w xY w|                                 D ]}|j        dk    r||j        z  }|                                r@|                                rt	          j        |           t	          j	        ||d           lt	          j
        ||           d S )NTr]   r`   r[   Fra   )rf   rg   r/   rh   rd   re   unlink	Exceptionexistsri   rj   )rV   rW   rl   rm   s       r   _copy_backup_to_datars   e   s;   
LLL---   	 	9%%;;== 	M$d33333      	% 	%9%%	!;;== 	%{{}} $d###OD$77777Lt$$$$	% 	%s   &A;;
BBrepo_dirproject_rootc           
        t          | |          }|j                            dd           |dz                                  sZ|r$t	          dd|d| t          |          g|           nt	          d| t          |          g|           t	          dd|g|           nct	          d	d
d| g|           |r:t	          dd|g|           t	          d|g|           t	          ddd|g|           nt	          dd|g|           t	          ddt          t          j        d          pd          g|           t	          ddt          t          j        d          pd          g|           d S )NTr]   z.gitclonez--branchz--single-branchcheckoutz-Bremotezset-urloriginfetchpullz	--ff-onlyconfigz	user.nameWEBSITE_BACKUP_GIT_NAMEzRenaiss Website Botz
user.emailWEBSITE_BACKUP_GIT_EMAILzbot@renaiss.website)rR   r5   rf   rr   rN   r   r   r   )rO   rt   rP   ru   branch_existss        r   _ensure_repor   }   s   &x88MO$666v%%'' ; 	;gz63DhPST\P]P]^`lmmmmgxX7FFFj$/::::(Ix:HEEE 	;gx0(;;;j&)8444fk8V<hGGGGj$/:::hS3L)M)M)fQf%g%ghjrssshc")4N*O*O*hSh&i&ijltuuuuur   )manualforce_overrider   r   bool | Nonedict[str, Any]c          
        |s*t          t          j        dd          d          sddddS t                      }|sddddS t	          t          j        d	          pd
                                                                          pd
}t          t          j        dd                    }t          ||n|          }|dv }|r>|                                 r*t          | 
                                          r	|sddd|dS t                      }	t          |           }
t          |           }	 t          ||
|	|           |
|z  }|                                r|                                sddd|dS |                     dd           t#          ||            ddd|	||t          |          t          |          dS # t$          $ r+}dddt'          t	          |                    dcY d}~S d}~ww xY w)zRestore persistent website data from the configured git backup repo.

    This runs before bundled data migration. It only copies data when the target
    mounted directory is empty unless WEBSITE_DATA_RESTORE_FORCE=1 is set.
    WEBSITE_DATA_RESTORE_ON_STARTUPr   T)r   Fdisabled)okrestoredreasonmissing_repoWEBSITE_DATA_RESTORE_POLICYalwaysWEBSITE_DATA_RESTORE_FORCEr$   N>   if-empty
empty-onlyif_empty
empty_onlydata_root_not_empty)r   r   r   policymissing_subdir)r   r   r   subdirr]   r   )r   r   r   rP   r   r   r   forcerestore_failed)r   r   r   error)r   r   r   r=   r   r   r   r   rr   anyrg   r*   r6   r0   r   rh   rf   rs   rq   r!   )r+   ru   r   r   rO   r   	force_envr   should_require_emptyrP   rt   r   rV   r   s                 r    restore_website_data_from_backupr      sb     E'"),Ms"S"S]abbb EDDD ""H IHHH899EXFFLLNNTTVVbZbF	">DDEEIn4.IIE!%YY b	 0 0 2 2 bs9;L;L;N;N7O7O bX] b9NZ`aaaF	**HI&&FoXx>>>F"}} 	bfmmoo 	bU>NZ`aaat444VY/// 6ll%[[	
 	
 		
  o o o:JUabefkblblUmUmnnnnnnnnos&   2AG 8AG 
G9 G4.G94G9r   c           
        t          |pd                                                              d          }t          t          j        d          pd                                                                          pd}|dk    rddd|dS t                      s	|sddd	|dS t          rddd
|dS t                      }|sddd|dS da	 t                      }t          |           }t          |           }t          t          j        dd                    }	t          ||||           t          | ||z  |	           t          ddg|           t!          |          sdd||||ddaS t#          j                                        d          }
t          ddd|
 d| dg|           t          dd|g|           dd||||ddaS # t(          $ r.}dd||t+          t          |                    dcY d }~daS d }~ww xY w# daw xY w)Nr	   r   WEBSITE_BACKUP_PROVIDERrB   FTunsupported_provider)r   skippedr   providerr   already_runningr   WEBSITE_BACKUP_INCLUDE_VOLATILEr$   )rX   addz-A)r   changedr   r   rP   r   seconds)timespeccommitz-mzbackup(website): z []pushrz   )r   r   r   r   r   )r   r   r;   r   r   r   r&   _RUNNINGr=   r*   r6   r0   r   r   rn   rN   rU   r   utcnow	isoformatrq   r!   )r+   ru   r   r   r   rO   rP   rt   r   rX   stampr   s               r   run_website_backupr      s   2$$&&11(;;F29677@5AAGGIIOOQQZUZH58N\deee ZV Z
PXYYY a8IW_``` ""H ^T\]]]H!!#I..	**"29-NPS#T#TUUXx>>>	8f#4GWXXXX%)))"8,, 	~5FPXdjv|}}  !!++Y+??(D"He"H"Hv"H"H"HI8TTT&(F+X666tv8_eqwxx   z z zX`lmpqvmwmw`x`xyyyyyyyz s8   BG -AG 
H!G?7H8H ?HH Hc                   t          t          j        d          pd                                          }t	                      t          t          j        d          pd                                                                          pdt          |          t          t          t          j        d          pd                                                    t                      t          |           t          t          |                     t          |           t          t          j        d          pd                                          pdt          t          t          j        d          pd	          pd
          t          t          t          j        d          pd          pd          t          t          j        dd	                    t          t          j        dd	                    dS )Nr8   r	   r   rB   r   WEBSITE_BACKUP_TIMEZONEAsia/TaipeiWEBSITE_BACKUP_HOURr$   r   WEBSITE_BACKUP_MINUTE10
   WEBSITE_BACKUP_RUN_ON_STARTUPr   )enabledr   has_repohas_patrP   r   rt   r+   timezonehourminuterun_on_startuprX   )r   r   r   r   r&   r   r   r*   r0   r6   intr   )r+   r<   s     r   get_website_backup_statusr      s   ry.//5266<<>>D"$$	";<<EFFLLNNTTVV_Z_JJBI&:;;ArBBHHJJKK "" ++(3344^^	";<<MNNTTVVgZgC	"788?C@@EAFFc")$;<<DEEKLL!"),KS"Q"QRR#BI.OQT$U$UVV  r   c                    t           rd S da t                     d         st          d           d S d         st          d           d S t          dd          dd	          d
d          dd         ddd         d
           d fdd         r)t          j        dd                                           dfd}t          j        |d                                           d S )NTr   z7[website-backup] disabled (WEBSITE_BACKUP_ENABLED != 1)r   z7[website-backup] disabled: WEBSITE_BACKUP_REPO is emptyz%[website-backup] scheduler data_root=r+   z
 repo_dir=rt   z branch=rP   z at r   02d:r   r   r   r   rY   c           
     >   t          |           }|                    d          r7t          d|  dt          |                    d                                d S t          d|  d|                    d          p|                    d                      d S )	N)r   r   z[website-backup] z done: changed=r   z failed/skipped: r   r   )r   getprintr   )r   rM   r+   ru   s     r   rG   z+start_website_backup_scheduler.<locals>.run  s    #I|FKKK::d 	nZfZZT&**YBWBW=X=XZZ[[[[[lfllvzz'?R?R?jV\V`V`aiVjVjllmmmmmr   r   )startup)rW   r>   daemonc                    t                              d          pd          } 	 t          |           }n# t          $ r d }Y nw xY w	 |rt	          j        |          nt	          j                    }|                    d          }|j        d         k    r)|j        d         k    rt          |k    r|a	 d           t          j        d           )	Nr   r   Tz%Y-%m-%d %H:%Mr   r   	scheduled   )r   r   r   rq   r   nowstrftimer   r   _LAST_RUN_MINUTE_KEYtimesleep)tz_nametzr   keyrG   statuss       r   loopz,start_website_backup_scheduler.<locals>.loop  s    fjj,,=>>	'""BB 	 	 	BBB		&(<(,r"""hlnnC,,/00Cx6&>))cjF8<L.L.LQeilQlQl'*$K   JrNNN	s   7 AA)rW   r   )r   r   r   rY   )r   rY   )_TIMER_STARTEDr   r   	threadingThreadstart)r+   ru   r   rG   r   s   `` @@r   start_website_backup_schedulerr      s    N&y11F) GHHH* GHHH		TK(	T 	T4::4F	T 	T"	T 	T(.vS	T 	T=CH=MS	T 	T  n n n n n n n  M,tDDDJJLLL       D...4466666r   )F)r
   r   r   r   r   r   )r   r   r   r   )r   r   )r   r   )r+   r   r   r   )r+   r   r   r   )r>   r?   r@   r   r   r   )rO   r   rP   r   r   r   )r@   r   r   r   )rV   r   rW   r   rX   r   r   rY   )rV   r   rW   r   r   rY   )
rO   r   rt   r   rP   r   ru   r   r   rY   )
r+   r   ru   r   r   r   r   r   r   r   )r   )r+   r   ru   r   r   r   r   r   )r+   r   r   r   )r+   r   ru   r   r   rY   )%__doc__
__future__r   r   rd   rF   r   r   r   pathlibr   typingr   urllib.parser   zoneinfor   r   r   r   r   r!   r&   r*   r0   r6   r=   rN   rR   rU   rn   rs   r   r   r   r   r   r%   r   r   <module>r      sN   4 4 " " " " " " 				                                          - - - - -3 3 3 3= = = =O O O Ow w w wG G G G	 	 	 	) ) ) )/ / / /" " " "
% % % %% % % %0v v v v4 "&/o /o /o /o /o /od         F   &+7 +7 +7 +7 +7 +7r   