Ë
    yÌjQ  ã                   óô   — U d 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dlmZ  ej"                  d	«      Zd
ZdZdZdaedz  ed<   dZdefd„Zdedz  fd„Zdefd„Zdd„Zdd„Zy)u-  
backup_service.py â€” copies de sÃ©curitÃ© automatiques de la base MySQL.

Toutes les 24 h (et une fois au dÃ©marrage), Ã©crit BACKUPS_DIR/meeconic_YYYYMMDD_HHMM.sql.gz : un dump SQL
(structure + donnÃ©es) fait en Python, donc sans dÃ©pendre du binaire `mysqldump` sur le serveur. Il se
restaure avec `gunzip -c fichier.sql.gz | mysql meeconic`. Purge les copies de plus de BACKUP_RETENTION_DAYS
jours. Un Ã©chec dÃ©clenche une alerte e-mail. (Les photos ne sont volontairement pas sauvegardÃ©es : les
originaux restent sur le serveur FTP du photographe.)
é    N)ÚDecimal)ÚPath)ÚBACKUPS_DIR)Úget_db)Úutcnow)Úalert_servicezmeeconic.backupé€Q é   iô  Úlast_backup_at))ú\z\\)ú'ú'')ú
z\n)úz\r)ú z\0)úz\ZÚreturnc                 óN  — | €yt        | t        «      r| rdS dS t        | t        t        t        f«      rt        | «      S t        | t        t        f«      r | rdt        | «      j                  «       z   S dS t        | «      }t        D ]  \  }}|j                  ||«      }Œ d|› d�S )NÚNULLÚ1Ú0Ú0xr   r   )Ú
isinstanceÚboolÚintÚfloatr   ÚstrÚbytesÚ	bytearrayÚhexÚ_ESCAPESÚreplace)ÚvÚsÚrawÚescs       ú2/var/www/photos/backend/services/backup_service.pyÚ_sql_literalr(   "   sŸ   € Ø€yØÜ�!”TÔÙˆsÐ ˜SÐ Ü�!”cœ5¤'Ð*Ô+Ü�1‹vˆÜ�!”eœYÐ'Ô(Ù()ˆt”e˜A“h—l‘l“nÑ$Ð3¨tÐ3ÜˆA‹€AÜò  ‰ˆˆSØ�I‰I�c˜3Ó‰ð àˆqˆc�ˆ8€Oó    c                  ó^  — t        j                  dd¬«       t         dt        «       j                  d«      › d�z  } | j	                  | j
                  dz   «      }t        «       5 }t        j                  |ddd	¬
«      5 }|j                  d«       |j                  d«      j                  «       D �cg c]  }t        |j                  «       «      d   ‘Œ  }}|D �]  }|j                  d|› d�«      j                  «       }|j                  d|› dt        |j                  «       «      d   › d�«       |j                  d|› d�«      j                  «       }t        dt!        |«      t"        «      D ]j  }	||	|	t"        z    }
dj%                  d„ |
d   j'                  «       D «       «      }dj%                  d„ |
D «       «      }|j                  d|› d|› d|› d�«       Œl �Œ |j                  d«       d d d «       d d d «       |j)                  | «       | S c c}w # 1 sw Y   Œ)xY w# 1 sw Y   Œ-xY w)NT)ÚparentsÚexist_okÚ	meeconic_z%Y%m%d_%H%Mz.sql.gzz.tmpÚwtzutf-8r   )ÚencodingÚnewlinez-SET FOREIGN_KEY_CHECKS=0;
SET NAMES utf8mb4;
zSHOW TABLESr   zSHOW CREATE TABLE `ú`z
DROP TABLE IF EXISTS `z`;
é   z;
zSELECT * FROM `ú, c              3   ó(   K  — | ]
  }d |› d �–— Œ y­w)r1   N© )Ú.0Úcs     r'   ú	<genexpr>z_backup_once.<locals>.<genexpr>>   s   è ø€ Ò C¨a 1 Q C q¤Ñ Cùs   ‚z,
c              3   ót   K  — | ]0  }d dj                  d„ |j                  «       D «       «      z   dz   –— Œ2 y­w)ú(r3   c              3   ó2   K  — | ]  }t        |«      –— Œ y ­w)N)r(   )r6   r#   s     r'   r8   z)_backup_once.<locals>.<genexpr>.<genexpr>?   s   è ø€ Ò3XÈ´LÀ·OÑ3Xùs   ‚ú)N)ÚjoinÚvalues)r6   Úrs     r'   r8   z_backup_once.<locals>.<genexpr>?   s1   è ø€ Ò#nÐcd C¨$¯)©)Ñ3XÈQÏXÉXËZÔ3XÓ*XÑ$XÐ[^Õ$^Ñ#nùs   ‚68zINSERT INTO `z` (z	) VALUES
z
SET FOREIGN_KEY_CHECKS=1;
)r   Úmkdirr   ÚstrftimeÚ	with_nameÚnamer   ÚgzipÚopenÚwriteÚexecuteÚfetchallÚlistr>   ÚfetchoneÚrangeÚlenÚ_BATCHr=   Úkeysr"   )ÚdestÚtmpÚconnÚoutr?   ÚtablesÚtableÚcreateÚrowsÚkÚchunkÚcolsr>   s                r'   Ú_backup_oncerZ   1   sü  € Ü×Ñ˜d¨TÕ2Ü˜9¤V£X×%6Ñ%6°}Ó%EÐ$FÀgÐNÑN€DØ
�.‰.˜Ÿ™ VÑ+Ó
,€CÜ	‹ð 3�Tœ4Ÿ9™9 S¨$¸È$ÔOð 3ÐSVØ�	‰	ÐCÔDØ/3¯|©|¸MÓ/J×/SÑ/SÓ/UÖV¨!”$�q—x‘x“zÓ" 1Ó%ÐVˆÐVØó 	QˆEØ—\‘\Ð$7¸°w¸aÐ"@ÓA×JÑJÓLˆFØ�I‰IÐ0°°°t¼DÀÇÁÃÓ<QÐRSÑ<TÐ;UÐUXÐYÔZØ—<‘< /°%°¸Ð :Ó;×DÑDÓFˆDÜ˜1œc $›i¬Ó0ò Q�Ø˜Q˜q¤6™zÐ*�Ø—y‘yÑ C°5¸±8·=±=³?Ô CÓC�ØŸ™Ñ#nÐhmÔ#nÓn�Ø—	‘	˜M¨%¨°°D°6¸ÀFÀ8È3ÐOÕPò	Qð		Qð 	�	‰	Ð1Ô2÷3÷ 3ð ‡K�K�ÔØ€Kùò W÷3ð 3ú÷ 3ð 3ús7   Á$H#Á>3HÂ1#HÃDHÇ/H#ÈHÈH 	ÈH#È#H,c                  ód  — t        j                  «       syt        j                  «       t        dz  z
  } d}t        j                  d«      D ]5  }	 |j                  «       j                  | k  r|j                  «        |dz  }Œ7 |S # t        $ r!}t        j                  d||«       Y d }~Œ_d }~ww xY w)Nr   r	   zmeeconic_*.sql.gzr2   z$Suppression backup impossible %s: %s)r   Úis_dirÚtimeÚBACKUP_RETENTION_DAYSÚglobÚstatÚst_mtimeÚunlinkÚOSErrorÚlogÚwarning)ÚcutoffÚdeletedÚfÚes       r'   Ú
_purge_oldrj   F   s¥   € Ü×ÑÔØÜ�Y‰Y‹[Ô0°5Ñ8Ñ8€FØ€GÜ×ÑÐ1Ó2ò Fˆð	FØ�v‰v‹x× Ñ  6Ò)Ø—‘”
Ø˜1‘�øð	Fð €Nøô ò 	FÜ�K‰KÐ>ÀÀ1×EÑEûð	Fús   Á2BÂ	B/ÂB*Â*B/c                  óÜ   — t        «       } | r8t        «       j                  «       at        j                  d| j                  «       t        «       }|rt        j                  d|t        «       y y )NzDB backup created: %sz#%d old backup(s) purged (> %d days))	rZ   r   Ú	isoformatr   rd   ÚinforC   rj   r^   )rO   Úpurgeds     r'   Úrun_oncero   U   sP   € ä‹>€DÙÜ›×+Ñ+Ó-ˆÜ�‰Ð(¨$¯)©)Ô4Ü‹\€FÙÜ�‰Ð6¸Ô@UÕVð r)   c               ƒ   ó^  K  — 	 	 t        j                  t        «      ƒ d {  –—†  t        j                  t        «      ƒ d {  –—†  ŒD7 Œ&# t         j                  $ r ‚ t        $ rB} t
        j                  d| d¬«       t        j                  ddt        | «      «       Y d } ~ Œ}d } ~ ww xY w7 Œh­w)NTzErreur backup DB: %s)Úexc_infozbackup-failedu   Le backup de la base a Ã©chouÃ©)ÚasyncioÚ	to_threadro   ÚCancelledErrorÚ	Exceptionrd   Úerrorr   Únotifyr   ÚsleepÚ_BACKUP_INTERVAL)ri   s    r'   Úrun_backup_looprz   `   s˜   è ø€ Ø
ð	]Ü×#Ñ#¤HÓ-×-Ð-ô �m‰mÔ,Ó-×-Ð-ð à-ùÜ×%Ñ%ò 	ØÜò 	]Ü�I‰IÐ,¨a¸$ˆIÔ?Ü× Ñ  Ð2SÔUXÐYZÓU[×\Ñ\ûð	]úð 	.úsI   ‚B-…A
 ¡A¢A
 ¦B-ÁB+ÁB-ÁA
 Á
B(Á&8B#ÂB-Â#B(Â(B-)r   N) Ú__doc__rr   rD   Úloggingr]   Údecimalr   Úpathlibr   Úcore.configr   Úcore.dbr   Úcore.timeutilr   Úservicesr   Ú	getLoggerrd   ry   r^   rM   r   r   Ú__annotations__r!   r(   rZ   r   rj   ro   rz   r5   r)   r'   ú<module>r…      s—   ðòó Û Û Û Ý Ý å #Ý Ý  Ý "à€g×ÑÐ)Ó*€àÐ ØÐ Ø	€à!€��d‘
Ó !ð i€ð�só ð�d˜T‘kó ð*�Có óWô	.r)   