Ë
    yÌjv  ã                   óV  — d 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	  ej                  e«      ZdZ ej                  d«      Z ej                  d«      Zdd
„Zded	eeef   fd„Zded	ee   fd„Zdedeeef   d	eeef   fd„Zdeded	ee   fd„Zdeded	efd„Zdededed	dfd„Zy)uu  
photographer_service.py â€” fotÃ³grafos de un colegio y su "QR pegajoso".

Igual que en hec-photo-app, cada fotÃ³grafo se identifica por el PREFIJO del nombre de archivo de su
cÃ¡mara (p. ej. `DSC` â†’ "xavier", `CAR` â†’ "carlos"). Eso permite que dos fotÃ³grafos trabajen a la vez
sobre el mismo FTP sin pisarse: cada uno tiene SU Ãºltimo QR escaneado ("sticky"), asÃ­ que las fotos de
uno no acaban en la familia que estÃ¡ fotografiando el otro.

Sin fotÃ³grafos configurados el organizer usa uno implÃ­cito ("photographer") que acepta cualquier prefijo:
una instalaciÃ³n con un solo fotÃ³grafo funciona sin configurar nada.
é    N)ÚOptional)Úget_dbÚTABLE_OPTIONS)Ú
utcnow_isoÚphotographerz^[A-Z0-9_]{1,12}$z^[a-z0-9][a-z0-9_-]{0,39}$Úreturnc                  ó’   — t        «       5 } | j                  dt        › �«       | j                  «        d d d «       y # 1 sw Y   y xY w)Nab  
            CREATE TABLE IF NOT EXISTS photographers (
                school_id  VARCHAR(64) NOT NULL,
                prefix     VARCHAR(16) NOT NULL,
                name       VARCHAR(64) NOT NULL,
                last_qr    VARCHAR(64),
                created_at VARCHAR(40) NOT NULL,
                PRIMARY KEY (school_id, prefix)
            ) )r   Úexecuter   Úcommit)Úconns    ú8/var/www/photos/backend/services/photographer_service.pyÚinit_photographer_tabler      sF   € Ü	‹ð 
�TØ�‰ð ô ˆoð!ô 	"ð 	�‰Œ÷
÷ 
ñ 
ús	   ‹)=½AÚ	school_idc                 óº   — t        «       5 }|j                  d| f«      j                  «       }d d d «       D �ci c]  }|d   |d   “Œ c}S # 1 sw Y   Œ xY wc c}w )Nz8SELECT prefix, name FROM photographers WHERE school_id=?ÚprefixÚname)r   r
   Úfetchall©r   r   ÚrowsÚrs       r   Úget_photographer_mapr   )   s`   € Ü	‹ð q�TØ�|‰|ÐVÐYbÐXdÓe×nÑnÓpˆ÷qà,0Ö1 qˆAˆh‰K˜˜6™Ñ"Ò1Ð1÷qð qüâ1s   ‹"A¹AÁAc                 ó¾   — t        «       5 }|j                  d| f«      j                  «       }d d d «       D �cg c]  }t        |«      ‘Œ c}S # 1 sw Y   Œ"xY wc c}w )NzWSELECT prefix, name, last_qr FROM photographers WHERE school_id=? ORDER BY name, prefix)r   r
   r   Údictr   s       r   Úlist_photographersr   /   sY   € Ü	‹ð 5�TØ�|‰|ÐuØ&˜Ló*ß*2©(«*ð 	÷5ð "Ö"˜ŒD��GÒ"Ð"÷5ð 5üò #s   ‹"A¹AÁAÚnew_mapc                 ó8  — i }|j                  «       D ]·  \  }}t        |«      j                  «       j                  «       t        |«      j                  «       j	                  «       }}|s|sŒYt
        j                  |«      st        d|›d�«      ‚t        j                  |«      st        d|›d�«      ‚||v rt        d|› �«      ‚|||<   Œ¹ t        «       }t        «       5 }|j                  d| f«      D �	ci c]  }	|	d   |	d   “Œ }
}	|j                  d	| f«       |j                  «       D ]+  \  }}|j                  d
| |||
j                  |«      |f«       Œ- |j                  «        ddd«       t        j                  d| |«       |S c c}	w # 1 sw Y   Œ'xY w)u¾   Sustituye el mapa del colegio (prefijo â†’ nombre). Valida antes de tocar nada y conserva el
    Ãºltimo QR de los fotÃ³grafos que siguen existiendo. ValueError si algÃºn dato no es vÃ¡lido.zInvalid prefix: z (1-12 letters, digits or _)zInvalid name: z3 (lowercase, digits, - or _; it is the folder name)zPrefijo repetido: zQSELECT name, last_qr FROM photographers WHERE school_id=? AND last_qr IS NOT NULLr   Úlast_qrz+DELETE FROM photographers WHERE school_id=?z[INSERT INTO photographers (school_id, prefix, name, last_qr, created_at) VALUES (?,?,?,?,?)Nu(   [%s] Mapa de fotÃ³grafos actualizado: %s)ÚitemsÚstrÚstripÚupperÚlowerÚ
_PREFIX_REÚmatchÚ
ValueErrorÚ_NAME_REr   r   r
   Úgetr   ÚloggerÚinfo)r   r   Ú
normalizedÚkÚvr   r   Únowr   r   Úpreviouss              r   Úupdate_photographer_mapr/   6   s¤  € ð "$€JØ—‘“ò 
"‰ˆˆ1Ü˜1“v—|‘|“~×+Ñ+Ó-¬s°1«v¯|©|«~×/CÑ/CÓ/E�ˆÙ™dØÜ×Ñ Ô'ÜÐ/°¨uÐ4PÐQÓRÐRÜ�~‰~˜dÔ#Ü˜~¨a¨UÐ2eÐfÓgÐgØ�ZÑÜÐ1°&°Ð:Ó;Ð;Ø!ˆ
�6Òð
"ô ‹,€CÜ	‹ð �TØ59·\±\Ø_ÐbkÐamó6oö p°�A�f‘I˜q ™|Ñ+ð pˆð pà�‰ÐBÀYÀLÔQØ&×,Ñ,Ó.ò 	M‰LˆF�DØ�L‰LÐvØ# V¨T°8·<±<ÀÓ3EÀsÐKõMð	Mð 	�‰Œ÷ô ‡K�KÐ:¸IÀzÔRØÐùòp÷ð ús   Ã!FÃ7FÄA#FÆFÆFÚfilenamec                 óê   — t        | «      }|st        S |j                  «       }t        |t        d¬«      D ]  }|j                  |«      sŒ||   c S  t        j                  d| |t        |«      «       y)u¤   FotÃ³grafo de un archivo por el prefijo de su nombre (el mÃ¡s largo gana). None = prefijo desconocido.
    Sin fotÃ³grafos configurados, uno implÃ­cito acepta todo.T)ÚkeyÚreversez1[%s] Prefijo no reconocido para %r (prefijos: %s)N)r   ÚIMPLICIT_PHOTOGRAPHERr!   ÚsortedÚlenÚ
startswithr(   Úwarning)r   r0   Úpmapr!   r   s        r   Úresolve_photographerr:   R   ss   € ô   	Ó*€DÙÜ$Ð$Ø�N‰NÓ€EÜ˜¤3°Ô5ò  ˆØ×Ñ˜FÕ#Ø˜‘<Òð ô ‡N�NÐFÈ	ÐS[Ô]cÐdhÓ]iÔjØó    r   c                 ó8  — t        «       5 }|t        k(  rHt        | «      s=|j                  dd| › d|› �f«      j	                  «       }|r|d   nd xs dcd d d «       S |j                  d| |f«      j	                  «       }d d d «       r|d   S dS # 1 sw Y   ŒxY w)Nz$SELECT value FROM app_kv WHERE key=?ústicky:ú:ÚvalueÚ_no_qrz^SELECT last_qr FROM photographers WHERE school_id=? AND name=? AND last_qr IS NOT NULL LIMIT 1r   )r   r4   r   r
   Úfetchone)r   r   r   Úrows       r   Úget_sticky_qrrC   `   s°   € Ü	‹ð 9�TØÔ(Ò(Ô1EÀiÔ1PØ—,‘,ÐEÈ'ÐR[ÐQ\Ð\]Ð^bÐ]cÐHdÐGfÓg×pÑpÓrˆCÙ$'�C˜’L¨TÒ>°h÷9ñ 9ð �l‰lÐ{Ø% tÐ,ó.ß.6©h«jð 	÷	9ñ !ˆ3ˆy‰>Ð. hÐ.÷9ð 9ús   ‹ABÁ"BÂBÚcodec                 óê   — t        «       5 }|t        k(  r&t        | «      s|j                  dd| › d|› �|f«       n|j                  d|| |f«       |j	                  «        ddd«       y# 1 sw Y   yxY w)uY   Persiste el Ãºltimo QR para TODOS los prefijos de ese fotÃ³grafo (sobrevive a reinicios).z7INSERT OR REPLACE INTO app_kv (key, value) VALUES (?,?)r=   r>   z?UPDATE photographers SET last_qr=? WHERE school_id=? AND name=?N)r   r4   r   r
   r   )r   r   rD   r   s       r   Úset_sticky_qrrF   j   sy   € ä	‹ð �TØÔ(Ò(Ô1EÀiÔ1PØ�L‰LÐRÐW^Ð_hÐ^iÐijÐkoÐjpÐUqÐswÐTxÕyà�L‰LÐZÐ]aÐclÐnrÐ\sÔtØ�‰Œ÷÷ ñ ús   ‹AA)Á)A2)r   N)Ú__doc__ÚloggingÚreÚtypingr   Úcore.dbr   r   Úcore.timeutilr   Ú	getLoggerÚ__name__r(   r4   Úcompiler#   r&   r   r   r   r   Úlistr   r/   r:   rC   rF   © r;   r   ú<module>rR      s  ðñ
ó Û 	Ý ç )Ý $à	ˆ×	Ñ	˜8Ó	$€à&Ð ØˆR�Z‰ZÐ,Ó-€
àˆ2�:‰:Ð3Ó4€óð2 Cð 2¨D°°c°©Nó 2ð# #ð #¨$¨t©*ó #ð sð °T¸#¸s¸(±^ð ÈÈSÐRUÈXÉó ð8 Cð °3ð ¸8ÀC¹=ó ð/˜Sð /¨ð /°ó /ð˜Sð ¨ð °3ð ¸4ô r;   