U
    —âñj�E  ã                   @   s€  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mZ ddlZddlmZ ddlmZ ddlmZmZ d	Zd
ZdZdddœZejdd�Ze ¡ Zeƒ Zi Z da!da"da#da$da%da&dd„ Z'dd„ Z(dd„ Z)dd„ Z*dd„ Z+dd„ Z,dd„ Z-d d!„ Z.e
d"d#„ ƒZ/d$d%„ Z0d&d'„ Z1d(d)„ Z2d*d+„ Z3d6d,d-„Z4d.d/„ Z5d0d1„ Z6d2d3„ Z7d7d4d5„Z8dS )8zPAltas conservadoras fuera de la ingesta; habilitadas tras preparar la instancia.é    N)Úcontextmanager)Údatetime)Úrelativedelta)ÚMongoClient)ÚDuplicateKeyError)Úinsert_log_in_user_historyÚlog_centros)ÚenviroÚnanooxÚscappÚpssÚflux)ÚitgÚitg7z%/var/lib/itgmanager/centros-auto.lockÚautoÚ	pendiente)ÚorigenÚestado_altaiô  )ÚmaxsizeFc                 C   s   | a d S ©N)Ú_guardar_permiso)Úguardar_permiso© r   ú8/var/www/itgmanager/itgmanager/centros_autodetectados.pyÚ
configurar$   s    r   c              
   C   sL   zt | jd||ƒ W n2 tk
rF } zt d|||¡ W 5 d}~X Y nX dS )u[   Historial visible en 'Logs Usuarios' para acciones automÃ¡ticas; su fallo no revierte nada.z$Systemz:autodeteccion.auditoria_fallida centro=%s tipo=%s error=%sN)r   Úhistorial_usersÚ	ExceptionÚlogÚwarning)ÚdbÚslugÚtipoÚerrorr   r   r   Úauditar)   s    r#   c                 C   s   t | tƒotdd„ | D ƒƒS )Nc                 s   s"   | ]}|  d d¡d dkV  qdS )Ú.é   r   >   Úautodeteccionr   r   N)Úsplit)Ú.0Úkeyr   r   r   Ú	<genexpr>2   s    z$campos_reservados.<locals>.<genexpr>)Ú
isinstanceÚdictÚany)Údatosr   r   r   Úcampos_reservados1   s    ÿr/   c                 C   sè   |t kr| S dd„ | tddi¡D ƒ}|s.| S t | ¡}tƒ }t| ¡ ƒD ]|\}}t|t	ƒrJ|sbqJt| ¡ ƒD ]L\}}	t|	t	ƒrn| 
|	¡rn| | 
|	¡¡ |D ]}
|	 |
d ¡ qž|	sn||= qn|sJ||= qJ|rät d|d t|ƒ¡¡ |S )Nc                 S   s   h | ]}|d  ’qS )Ú	centro_idr   )r(   Údr   r   r   Ú	<setcomp>9   s     z!sin_pendientes.<locals>.<setcomp>r0   r%   z;permisos.pendientes_excluidos usuario_destino=%s centros=%sú,)ÚITGÚfindÚ	PENDIENTEÚcopyÚdeepcopyÚsetÚlistÚitemsr+   r,   ÚintersectionÚupdateÚpopr   ÚinfoÚjoinÚsorted)ÚpermisosÚciclosÚusernameZ
pendientesÚ	resultadoZ	excluidosÚregionÚareasÚareaÚcentrosr    r   r   r   Úsin_pendientes6   s2    
 ÿrJ   c                 C   sf   | dkst |ƒdkrd S |\}}}| dkr2d\}}|||f}tdd„ |D ƒƒsRd S d dd„ |D ƒ¡S )	N)r
   r   r   é   r   )r   Úbarcosc                 s   s<   | ]4}t |tƒo2t d |¡o2| ¡  ¡ | ¡  ¡ kV  qdS )z[A-Za-z0-9]{1,60}N)r+   ÚstrÚreÚ	fullmatchÚlowerÚtitleÚ
capitalize©r(   Úpr   r   r   r*   X   s   ÿzidentidad.<locals>.<genexpr>ú-c                 s   s   | ]}|  ¡ V  qd S r   )rP   rS   r   r   r   r*   [   s     )ÚlenÚallr@   )ÚservicioÚrawrF   rH   ÚcentroÚpartesr   r   r   Ú	identidadQ   s    

ÿr\   c                 C   s   t  d| ¡ ¡ }t dd|¡S )NZNFKDz	[^a-z0-9]Ú )ÚunicodedataZ	normalizeÚcasefoldrN   Úsub)ÚnombreZnormalr   r   r   Úplegar^   s    rb   c                    s  t | d¡d ƒ‰ | jji ddidd�D ]@}| dd¡}t|tƒr(||kr(t | dd¡d ƒˆ kr( d	S q(| jjd|id
didd�rˆdS | j	ji ddidd�D ]`}| d¡p®i  
¡ D ]H}t|tƒsÄq´| 
¡ D ].}t|tƒrÌt‡ fdd„|D ƒƒrÌ   d	S qÌq´qždS )NrU   r   r0   r%   éÐ  ©Zmax_time_msr]   é   TÚ_idFrB   c                 3   s&   | ]}t | d d¡d ƒˆ kV  qdS )rU   re   r   N)rb   Úrsplit)r(   Úc©ra   r   r   r*   p   s    zconflicto.<locals>.<genexpr>)rb   r'   rC   r5   Úgetr+   rM   rg   Úfind_oneÚusersÚvaluesr,   r-   )r   r    ÚdocZotroÚuserrG   rI   r   ri   r   Ú	conflictoc   s"    *
ÿrp   c                    s  |dkr0| j ˆ ¡ › d� ji ddidd�d k	S |dkrX| jjjdˆiddidd�d k	S ˆ d	¡d
 ‰ | j‰ˆˆ › d� jddddddgiiddidd�D ]}| d¡ˆkrš dS qšd}d| D ]4}ˆˆ › d|› � jddˆiiddidd�rÀ dS qÀt	‡ ‡‡fdd„|D ƒƒS )Nr   Ú_flux_tsrf   r%   rc   rd   r   r0   rU   éÿÿÿÿZ_estructura_logicaú$inÚmodulosZaviotsÚcansÚbombasF)Úsensoresru   Zgenerador_comap_timeseries)ZmetadataÚ_z$nec                 3   s8   | ]0}ˆˆ › d |› � j dˆiddidd�dk	V  qdS )rx   r0   rf   r%   rc   rd   N)rk   )r(   Úsufijo©rZ   r   Úid_almr   r   r*   ˆ   s   ÿ$ÿzhay_datos.<locals>.<genexpr>)
ÚFLUX__TSrP   rk   ÚScappDBÚdata_analyticr'   Ú
NANOOX__TSr5   rj   r-   )ÚclientrX   r{   rn   Zsufijosry   r   rz   r   Ú	hay_datosv   s(    (   ÿ
*ÿr�   c                  c   s�   t ttdd ƒƒstdƒ‚t ttjtjB d¡} t 	| d¡�L}t
 |t
jt
jB ¡ z t d¡� d V  W 5 Q R X W 5 t
 |t
j¡ X W 5 Q R X d S )NÚtimeoutõ.   La autodetecciÃ³n requiere PyMongo con timeouté€  Úaé
   )ÚcallableÚgetattrÚpymongoÚRuntimeErrorÚosÚopenÚ	LOCK_PATHÚO_CREATÚO_RDWRÚfdopenÚfcntlZflockZLOCK_EXZLOCK_NBZLOCK_UNr‚   )Ú
descriptorZarchivor   r   r   Úbloqueo_automaticosŒ   s    r“   c                 C   sÖ   t  ¡ tk rtS t}dat  ¡ d atttdd ƒƒsFt dtj	¡ dS | j
}tdd„ |j ¡ D ƒƒ}dd„ |j
jd	ttƒid
dœddidd�D ƒttƒk}|o |ats¼t d|s´dnd¡ n|sÒt dd t¡¡ tS )NFéX  r‚   z?autodeteccion.desactivada motivo=pymongo_sin_timeout version=%sc                 s   sJ   | ]B}|  d ¡o@t|  di ¡ ¡ ƒdgko@|  d¡ o@|  d¡ V  qdS )Úuniquer)   )r0   r%   ZpartialFilterExpressionZsparseN)rj   r:   r;   )r(   Úxr   r   r   r*   ¦   s
   þ$
ÿzhabilitado.<locals>.<genexpr>c                 S   s   h | ]}|d  ’qS ©rD   r   ©r(   Úur   r   r   r2   ©   s     zhabilitado.<locals>.<setcomp>rs   ÚSuperusuario)rD   ÚcargorD   r%   rc   rd   z#autodeteccion.desactivada motivo=%sZfalta_indice_unicoZ faltan_usuarios_itg_superusuarioz;autodeteccion.habilitada indice=centro_id_unico usuarios=%sr3   )ÚtimeÚ	monotonicÚ_habilitado_hastaÚ_habilitado_valorr‡   rˆ   r‰   r   r   Úversionrl   r-   rC   Zlist_indexesr5   r:   r4   r9   r?   r@   )r€   Zanteriorr   ZindiceÚusuariosr   r   r   Ú
habilitado›   s6    þ  ÿÿ
ÿr¢   c                 C   sæ   t ttddƒƒstdƒ‚dat d¡�Š t| ƒr<t d¡ npz| j	j
jddd	� W n0 tk
r‚ } zt d
|¡ ‚ W 5 d}~X Y nX t d¡ dat| ƒs¬t d¡ tdƒ‚W 5 Q R X t ttjtjB d¡}t |¡ t dt¡ dS )zMPreflight de despliegue: nunca modifica ciclos, permisos ni datos de equipos.r‚   Nrƒ   r   é   z*autodeteccion.preparacion indice=existenter0   T)r•   z>autodeteccion.preparacion_fallida motivo=indice_unico error=%szNautodeteccion.preparacion indice=creado coleccion=users.ciclos clave=centro_idz5autodeteccion.preparacion_fallida motivo=usuarios_itgz.Instancia sin preparar: comprobar usuarios ITGr„   z&autodeteccion.preparacion exclusion=%s)r‡   rˆ   r‰   rŠ   rž   r‚   r¢   r   r?   rl   rC   Zcreate_indexr   r"   r‹   rŒ   r�   rŽ   r�   Úclose)r€   r"   r’   r   r   r   Úpreparar_instancia´   s&    


r¥   c                 C   sR   |   d¡}| tdd�   d¡}||t |d¡t ¡   koHt |d¡kn  dœS )Nz%Y-%m-%dé   )Zmonths©ÚinitÚfinÚstatus)Ústrftimer   r   ÚstrptimeÚnow)ÚrecibidoÚinicior©   r   r   r   ÚventanaÏ   s
    
*ÿr°   c              
   C   sV   dd„ t D ƒ}|j| ddddidd d d dœd d dœd	œ||d
dœd� t|ƒ||< |S )Nc                 S   s   i | ]}|d d ddœ“qS )NFr§   r   )r(   Úsr   r   r   Ú
<dictcomp>×   s      znuevo_ciclo.<locals>.<dictcomp>r   r   Zspecier]   )ÚlatÚlonÚ	timestamp)r³   r´   )ÚactiveÚmanualr   F)rX   ÚfechaÚalta_completa)r0   r   r   Z
cicle_infoÚgps_coordinatesr&   )Ú	SERVICIOSr=   r°   )r    rX   r®   rn   r   r   r   Únuevo_cicloÖ   s    ÿ
ýr¼   c           	   	   C   sŠ  |  d¡dks |  di ¡  d¡r$dS |d  d¡\}}}d|› d	|› d	|d › �}| jjd|d id
ddddœidd� |p~t| j|||ƒ dd„ | j ddttƒi|ddiiddi¡D ƒ}|t	tƒkrôt
 d|d d tt	tƒ| ƒ¡¡ tdƒ‚| j d|d i¡�s"t
 d|d ¡ tdƒ‚| j d|d idddii¡}|j�s`t
 d|d ¡ tdƒ‚|j�r€t
 d|d d t¡¡ t|jƒS ) u:   Devuelve True solo si esta llamada dejÃ³ el alta completa.r   r   r&   r¹   Fr0   rU   z	permisos.r$   ú$setOnInsertÚB)r	   r
   r   T©Úupsertc                 S   s   h | ]}|d  ’qS r—   r   r˜   r   r   r   r2   é   s     z!completar_alta.<locals>.<setcomp>rD   rs   z$existsr%   zNautodeteccion.alta_incompleta centro=%s motivo=faltan_permisos_itg usuarios=%sr3   z$Alta incompleta: faltan permisos ITGz;autodeteccion.alta_incompleta centro=%s motivo=falta_estadozAlta incompleta: falta estadorf   ú$setzautodeteccion.alta_completaz>autodeteccion.alta_incompleta centro=%s motivo=ciclo_eliminadozEl ciclo ya no existezMautodeteccion.alta_completada centro=%s permisos=%s estado=creado_o_existente)rj   r'   ÚestadosÚ
update_oner   rl   r5   r:   r4   r9   r   r   r@   rA   rŠ   rk   rC   Úmatched_countÚmodified_countr?   Úbool)	r   rn   r   rZ   rH   rF   ÚpathZ	presentesÚresultr   r   r   Úcompletar_altaà   sF       ÿÿ ÿ ÿ ÿrÉ   c           	         s  |  ˆ ¡}|dk	r.t|tƒr*|  d¡dkr.dS d|d ˆ › d�dddgii}‡ fd	d
„t|ƒ ¡ D ƒ}ˆ |kr–|dkr–d|d ˆ ddii}ˆ t|ƒi}| j |d|i¡}|jsÄt 	d|d ˆ ¡ dS t|ƒ}t 	d|d ˆ |d |d |  dd¡¡ t
| |d dƒ dS )uO   Devuelve True solo si abriÃ³ la ventana; registra el resultado y la auditorÃ­a.Nr¨   )Nr]   Frf   z.initrs   r]   c                    s    i | ]\}}ˆ › d |› �|“qS )r$   r   )r(   r)   Úval©rX   r   r   r²     s      z!abrir_ventana.<locals>.<dictcomp>z$typeÚnullrÁ   zRautodeteccion.ventana_sin_cambios centro=%s servicio=%s motivo=editada_en_paralelor0   zLautodeteccion.ventana_abierta centro=%s servicio=%s init=%s fin=%s origen=%sr©   r   r·   Úedit_centerT)rj   r+   r,   r°   r;   rC   rÃ   rÅ   r   r?   r#   )	r   rn   rX   r®   ÚbloqueÚfiltroZcamposrÈ   Zabiertar   rË   r   Úabrir_ventanaü   s2    
  ÿ    
ÿrÐ   c              	   C   s`  t ||ƒ}|s,t d|d tt|ƒ¡¡ d S t| ƒs8d S | j}|jj	d|idd�}|ov| 
d¡dkov| 
di ¡ 
d	¡ }|p~i  
|¡}	t|	tƒr¢|	 
d
¡r¢|s¢d S |sât||ƒrÂt d||¡ d S t| ||ƒsât d|||¡ d S |�r
| 
d¡dk�r
t||||ƒ d S tƒ ��D |jj	d|idd�}
|�r`|
�rF|
d |d k�r`t d|¡ W 5 Q R £ d S |
d k�rt||ƒ�r’t d||¡ W 5 Q R £ d S zN|jjd|idt|||ƒidd�}|jd k	�rÞt d|||¡ t||dƒ W n" tk
�r   t d|¡ Y nX |j 	d|i¡}
|
�s4t d|¡ W 5 Q R £ d S t||
ƒ |�sRt||
||ƒ W 5 Q R X d S )NzOautodeteccion.descartado motivo=nombre_no_apto servicio=%s raw=%s (alta manual)ú/r0   rc   rd   r   r   r&   r¹   r¨   ui   autodeteccion.descartado motivo=conflicto centro=%s servicio=%s (homÃ³nimo o permiso previo; alta manual)zaautodeteccion.descartado motivo=sin_datos_de_identidad centro=%s servicio=%s id_almacenamiento=%srf   zDautodeteccion.descartado motivo=ciclo_cambiado_en_paralelo centro=%sr½   Tr¿   zUautodeteccion.alta_creada centro=%s servicio=%s estado=pendiente id_almacenamiento=%sÚ
add_centeruG   autodeteccion.alta_concurrente centro=%s (otro escritor creÃ³ el ciclo)zAautodeteccion.descartado motivo=ciclo_ausente_tras_alta centro=%s)r\   r   r?   r@   ÚmaprM   r¢   rl   rC   rk   rj   r+   r,   rp   r   r�   rÐ   r“   rÃ   r¼   Zupserted_idr#   r   rÉ   )r€   rX   rY   r{   r®   r    r   rn   Z
incompletorÎ   ZactualrE   r   r   r   Úprocesar  s„    
 ÿ&
 ÿ  ÿ

 ÿ  ÿ  ÿ
rÔ   c                  C   s0  t  ¡ \} }}}}zžz>tj dd¡dkrPtd kr@tddddd�att||||ƒ W nZ tk
r€   t d	|d
 tt|ƒ¡¡ Y n. tk
r¬   t d|d
 tt|ƒ¡¡ Y nX W 5 t�d t | ¡ t ¡ }ttƒD ]}t| |krÒt|= qÒt	tƒdk�r
t 
tttƒƒ¡ |d t| < W 5 Q R X t  ¡  X q d S )Niè  r”   ÚAUTODETECCION_CENTROSÚ1zmongodb://localhost:27017/i¸  i'  )ZserverSelectionTimeoutMSZconnectTimeoutMSZsocketTimeoutMSzYautodeteccion.pospuesto motivo=exclusion_ocupada servicio=%s raw=%s (reintento en 10 min)rÑ   z<autodeteccion.error servicio=%s raw=%s (reintento en 10 min))Ú_colarj   Ú_memoriaÚ_en_colaÚdiscardrœ   r�   r:   Ú_cacherV   r>   ÚnextÚiterZ	task_doner‹   ÚenvironÚ_clienter   rÔ   ÚBlockingIOErrorr   r   r@   rÓ   rM   r   Ú	exception)ÚclaverX   rY   r{   r®   Zahorar)   r   r   r   Ú	_trabajarJ  s:     ÿ ÿ ÿ
rã   c                 C   s4  zÀt j dd¡dks tjdd�s&W d S zŒ| t|ƒf}|tksPt |d¡t	 
¡ krZW ¢`W d S td ksjt ¡ s‚tjtddd�at ¡  t || t|ƒ||p t ¡  ¡ f¡ t |¡ W 5 t ¡  X W nn tk
�r. } zNz2t	 
¡ t d	k�rt	 
¡ at d
t|ƒj| ¡ W n tk
�r   Y nX W 5 d }~X Y nX d S )NrÕ   rÖ   F)Úblockingr   Tzcentros-autodetectados)ÚtargetÚdaemonÚnameé<   z/autodeteccion.no_encolado motivo=%s servicio=%s)r‹   rÞ   rj   rØ   ÚacquireÚreleaseÚtuplerÙ   rÛ   rœ   r�   Ú_hiloÚis_aliveÚ	threadingÚThreadrã   Ústartr×   Z
put_nowaitr   r­   Ú
astimezoneÚaddr   Ú_ultimo_aviso_colar   r   ÚtypeÚ__name__)rX   rY   r{   r®   râ   r"   r   r   r   Úencolar_dato_recibidog  s(    
$rö   )N)N)9Ú__doc__r7   r‘   r‹   ZqueuerN   rî   rœ   r^   Ú
contextlibr   r   Zdateutil.relativedeltar   r‰   r   Úpymongo.errorsr   Úshared_db_utilsr   r   r   r»   r4   r�   r6   ZQueuer×   ÚLockrØ   r9   rÙ   rÛ   rì   rß   rž   rŸ   r   ró   r   r#   r/   rJ   r\   rb   rp   r�   r“   r¢   r¥   r°   r¼   rÉ   rÐ   rÔ   rã   rö   r   r   r   r   Ú<module>   s`   



7