+
    iWZ                        ^ RI t ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RI	H
t
 ^ RIHt ^ RIHt ^ RIHt ^ RIHtHtHt ]! 4        ]P(                  ! R	4      tR+t0 R,mtR
tR] P2                  ! R4      R] P2                  ! R4      R] P2                  ! R4      RR/tR R ltR R ltR R ltR R ltR R ltR R lt R R  lt!R! R" lt"R# R$ lt#R% R& lt$R' R( lt%R) R* lt&R# )-    N)Path)secure_filename)FileStorage)load_dotenv)Optional)datetime)crear_docs_headcrear_docs_detailobtener_siguiente_doc_linedocs_managementzhttps://file.sycelephant.comhostFTP_HOSTuserFTP_USERpasswordFTP_PASS	base_pathz/public_html/file/c                x    V ^8  d   QhR\         R\        R\        R\        R\        R\        R\        R\        /# )	   file_objorigenuser_id
created_bytitledescriptionruta_completareturn)r   strintdict)formats   "bC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\Utilities_module\DocsManagement.py__annotate__r#   8   s]     j^ j^k j^3 j^ j^RU j^j^,/j^@Cj^HLj^    c                2   Rp \         P                  RV RV 24       \        V 4      pVR,          '       gn   RRRVR,          RR	/V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        V 4      pV'       gg   RRRRRR/V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        V4      p
V
R,          '       gn   RRRV
R,          RR/V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        WtV4      pVR,          '       ga   TV'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        WV4      pVR,          '       ga   TV'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # VR,          p\        WW[R,          VR,          4      pVR,          '       ga   TV'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # RRRRV R2RRVRVR,          RVR,          RVR,          RVR,          RVR,          RV P                   //p\         P                  RVR,           24       TV'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # #   \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i  \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i  \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i  \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i  \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i  \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i  \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i  \         d   p	R\        T	4       2p\         P#                  TRR7       RRRRRR R!T/u Rp	?	T'       d   \        P                  P                  T4      '       dm    \        P                  ! T4       \         P                  R
T 24       #   \         d/   p	\         P                  RT R\        T	4       24        Rp	?	# Rp	?	ii ; i# # Rp	?	ii ; i  T'       d   \        P                  P                  T4      '       dm    \        P                  ! T4       \         P                  R
T 24       i   \         d/   p	\         P                  RT R\        T	4       24        Rp	?	i Rp	?	ii ; ii i ; i)"u<  
Función REUTILIZABLE para subir UN documento con validación completa
Puede usarse para: Formularios, Cotizaciones, Oportunidades, etc.

Args:
    file_obj (FileStorage): Objeto archivo de Flask
    origen (str): Módulo origen (ej: "Q_SpQ_FormsHead", "Q_SpQ_Quotations")
    user_id (int): ID del usuario
    created_by (str): Nombre completo del usuario
    title (str): Título del archivo
    description (str): Descripción del archivo
    ruta_completa (str): Ruta completa (ej: "Ventas/Formularios/1001-2/FormPEmx")

Returns:
    dict: Resultado de la operación
NzIniciando upload de documento: z para validsuccessFmessagecodeVALIDATION_ERRORArchivo temporal eliminado: %No se pudo eliminar archivo temporal : Error al crear archivo temporalTEMP_FILE_ERRORSECURITY_ERRORdocs_idremote_path	extensionTDocumento "" subido exitosamentedatadoc_line_iddownload_url	file_size	file_typeoriginal_namezDocumento subido exitosamente: z%Error inesperado en upload_document: exc_info&Error interno al procesar el documentoINTERNAL_ERRORtechnical_error)loggerinfovalidar_archivo_basicoospathexistsremovedebug	Exceptionwarningr   crear_archivo_temporalvalidar_seguridad_archivosubir_archivo_ftpgestionar_docs_headcrear_registro_documentofilenameerror)r   r   r   r   r   r   r   	temp_pathvalidacion_resulteseguridad_resultupload_resultdocs_head_resultr1   docs_detail_resultresultado_final	error_msgs   &&&&&&&          r"   upload_documentr[   8   sb   & IU^5eWF:,OP 38< ))5,Y7*T 	22^		)$;I;GH 39G +84	5<)B 	22^		)$;I;GH 39u 5Y?((5+I6(p 	22^		)$;I;GH 39c *)MJY'' ^ 	22^		)$;I;GH 39Y /v
K	**#T 	22^		)$;I;GH 39Q #9- 6K})Ek*
 "),,%@ 	22^		)$;I;GH 399 tUG+@A71-@n =}];.{;.{;!2!2
 	56H6W5XYZ 	22^		)$;I;GH 39  ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^!  
;CF8D	Y.u?$y	
 	
 	22^		)$;I;GH ^!FykQSTWXYTZS[\]]^	 39
 	22^		)$;I;GH ^!FykQSTWXYTZS[\]]^	 39s?  AV 5.O5&V ..P1(V 5.Q-&V 0.R)!V +.S%4V >.T!/A'V .U5P. $P))P.1Q*<$Q%%Q*-R&8$R!!R&)S"4$SS"%T0$TT!U,$UUV($VVY7$.Y2Y7Y: .X44Y-?$Y((Y-2Y77Y: :-\).[\\#$\\\\c                0    V ^8  d   QhR\         R\        /# r   r   r   )r   r    )r!   s   "r"   r#   r#      s     6
 6
[ 6
T 6
r$   c                v    V '       d   V P                   '       g   RRRR/# \        V P                   4      p\        V4      P                  P	                  4       pV\
        9  d   RRRRRP                  \
        4       2/# V P                  ^ \        P                  4       V P                  4       pV P                  ^ 4       V\        8  d   \        R,          pRRRRVR R	2/# V^ 8X  d   RRRR
/# RRRVRVRV/#   \         d2   p\        P                  R\        T4       24       RRRR/u Rp?# Rp?ii ; i)uc   
Validaciones básicas del archivo (tamaño, extensión, etc.)
REUTILIZABLE para cualquier módulo
r&   Fr(   u*   No se proporcionó ningún archivo válidou4   Tipo de archivo no permitido. Extensiones válidas: z, u2   El archivo excede el tamaño máximo permitido de z.1fMBu   El archivo está vacíoTrP   r3   r9   u   Error en validación básica: zError al validar el archivoN   )rP   r   r   suffixlowerEXTENSIONES_PERMITIDASjoinseekrD   SEEK_ENDtell   TAMAÑO_MAXIMOrI   rA   rQ   r   )r   rP   r3   r9   
   tamaño_mbrT   s   &     r"   rC   rC      sg   
1
x000G  #8#4#45N))//1	 22QRVR[R[\rRsQtu  	a%MMO	a~%';7JOPZ[^O__ab 
 >4  T	
 	
  
5c!fX>?U4
 	

s@   C< C< C< AC< A#C< %C< 2	C< <D8&D3-D83D8c                0    V ^8  d   QhR\         R\        /# )r   rR   r   r   r    )r!   s   "r"   r#   r#      s     
 
 
 
r$   c                    \        V 4      pVR,          '       g   V# \        V 4      pVR,          '       g   RRRRVR,           2/# RRRR/#   \         d2   p\        P	                  R	\        T4       24       RRRR
/u Rp?# Rp?ii ; i)uL   
Validación de seguridad usando ClamAV
REUTILIZABLE para cualquier módulo
r&   cleanFr(   z Archivo infectado o sospechoso: threatTzArchivo segurou#   Error en validación de seguridad: z)Error al validar la seguridad del archivoN)validar_headers_archivoescanear_con_clamavrI   rA   rQ   r   )rR   header_resultclamav_resultrT   s   &   r"   rL   rL      s    

/	:W%%   ,I6W%%=mH>U=VW  T'
 	

  
:3q6(CDUB
 	

s(   A )A A B
&B?B
B
c                0    V ^8  d   QhR\         R\        /# r   	file_pathr   rk   )r!   s   "r"   r#   r#      s     !
 !
s !
t !
r$   c                d    \        V R4      ;_uu_ 4       pVP                  R4      pRRR4       . ROpV F   pVXP                  4       9   g   K  RRRR/u # 	  RRRR	/#   + '       g   i     L@; i  \         d2   p\        P                  R
\        T4       24       RRRR/u Rp?# Rp?ii ; i)uO   
Validación básica de headers de archivo para detección rápida de amenazas
rbi   Nr&   Fr(   z%Archivo contiene patrones sospechososTu   Headers válidoszError al validar headers: z'Error al validar estructura del archivo)s!   X5O!P%@AP[4\PZX54(P^)7CC)7}$EICARs   <scripts   javascript:s	   vbscript:)openreadrb   rI   rA   rQ   r   )ru   fheaderpatrones_sospechosospatronrT   s   &     r"   ro   ro      s    
)T""aVVD\F # 
 +F'UF  + T)
 	
% #".  
1#a&:;U@
 	

s?   A3 A #A3 A3 A3  A0	+A3 3B/>&B*$B/*B/c                0    V ^8  d   QhR\         R\        /# rt   rk   )r!   s   "r"   r#   r#   "  s     ,
 ,
3 ,
4 ,
r$   c                    \         P                  ! RRV .RR^dR7      pVP                  ^ 8X  d   \        P	                  RV  24       RRRR/# VP
                  '       d   VP
                  P                  4       MR	p\        P                  R
V 24       RRRV/#   \         P                   d"    \        P                  RT  24       RRRR/u # \         d    \        P                  R4       RRRR/u # \         d>   p\        P                  R\        T4       24       RRRR\        T4       2/u Rp?# Rp?ii ; i)z
Escanea archivo con ClamAV
clamscanz--no-summaryT)capture_outputtexttimeoutzClamAV: Archivo limpio - rm   rn   NzAmenaza desconocidazClamAV: Amenaza detectada - FzClamAV timeout para archivo: zTimeout en escaneo de virusu3   ClamAV no está instalado o no se encuentra en PATHzSistema antivirus no disponiblezError ejecutando ClamAV: zError en escaneo: )
subprocessrun
returncoderA   rH   stdoutstriprJ   TimeoutExpiredrQ   FileNotFoundErrorrI   r   )ru   resultthreat_inforT   s   &   r"   rp   rp   "  sV   (
3	
 !LL4YK@A$ 
 4:===&----/F[KNN9+GH+ 
 $$ 
4YK@AU3
 	
  
JKU7
 	
  
0Q9:U*3q6(3
 	

sB   AB B  9B 3D=D=D=6D=?D= 2D82D=8D=c                F    V ^8  d   QhR\         R\        \        ,          /# r]   )r   r   r   )r!   s   "r"   r#   r#   T  s      [ Xc] r$   c                    \        V P                  4      p\        V4      P                  p\        P
                  ! VR7      w  r4\        P                  ! VR4      ;_uu_ 4       pV P                  ^ 4       VP                  V P                  4       4       RRR4       \        P                  RV 24       V#   + '       g   i     L*; i  \         d-   p\        P                  R\        T4       24        Rp?R# Rp?ii ; i)z,
Crea un archivo temporal desde FileStorage
)ra   wbNzArchivo temporal creado: z Error creando archivo temporal: )r   rP   r   ra   tempfilemkstemprD   fdopenre   writery   rA   rH   rI   rQ   r   )r   rP   r3   temp_fdrR   	temp_filerT   s   &      r"   rK   rK   T  s    "8#4#45N))	%--Y?YYw%%MM!OOHMMO, & 	0<= &%  7Ax@As0   A"C
 $1B7!C
 7C	C
 
D!C<<Dc                H    V ^8  d   QhR\         R\         R\         R\        /# )r   rR   r   r   r   rk   )r!   s   "r"   r#   r#   j  s.     D D DS D D Dr$   c           
        Rp \        V4      pV'       g0   R\        \        P                  ! 4       P	                  4       4       2p\
        R,          VP                  RR4      ,           pV RV 2p\         RV RV 2p\        P                  ! \
        R,          4      pVP                  \
        R,          \
        R,          4       \        W54       \        V R	4      ;_uu_ 4       pVP                  R
V 2V4       RRR4       \        P                  RV 24       \        P                  RV 24       RRRVRVRVRV/V'       d    VP!                  4        # #   + '       g   i     Lf; i    # ; i  \        P"                   dY   p	R\%        T	4       2p
\        P'                  T
4       RRRRRRRT
/u Rp	?	T'       d    TP!                  4        #     # ; i# Rp	?	i\(         dY   p	R\%        T	4       2p
\        P'                  T
4       RRRRRRRT
/u Rp	?	T'       d    TP!                  4        #     # ; i# Rp	?	ii ; i  T'       d    TP!                  4        i     i ; ii ; i)uV   
Sube archivo al servidor FTP
🆕 CORREGIDA: URL de descarga correcta para navegador
Narchivo_r   \/r   r   r   rw   zSTOR z#Archivo subido exitosamente a FTP: u   URL pública accesible: r'   Tr2   r8   rP   ftp_pathzError de permisos FTP: Fr(   z"Error de permisos al subir archivor)   FTP_PERMISSION_ERRORr@   zError subiendo archivo a FTP: z"Error al subir archivo al servidor	FTP_ERROR)r   r   r   now	timestamp
FTP_CONFIGreplaceBASE_URLftplibFTPlogincrear_directorios_ftprx   
storbinaryrA   rB   quit
error_permr   rQ   rI   )rR   r   r   conn_ftpnombre_archivoftp_directoryremote_file_path
public_urlarchivorT   rZ   s   &&&        r"   rM   rM   j  sd   
 H=(/'HLLN,D,D,F(G'HIN #;/-2G2Gc2RR+_An-=> !z=/>2BC
 ::j01z&):j+AB 	h6 )T""g%(8'9 :GD # 	9:J9KLM.zl;< t:J(
:  G #"L3  
-c!fX6	Yu;*y	
 	
$ 	   
4SVH=	Yu;Ky	
 	
 	 
 	 s   C#E5 'E=AE5 	E.E+	&E5 .E25I
,G6I7I GGI*I+,H>II %H66H:>II 	I)I! I)!I%#I)c                H    V ^8  d   QhR\         P                  R\        RR/# )r   ftp_conndirectory_pathr   N)r   r   r   )r!   s   "r"   r#   r#     s%     ' 'FJJ ' ' 'r$   c                     V P                  V4       \        P                  RV 24       R#   \        P                   d     Mi ; iTP                  R4      P                  R4      pRpT F  pT'       g   K  TRT,           ,          p T P                  T4       K1    \        P                   ds     T P                  T4       \        P                  RT 24        Ks    \        P                   d-   pR\        T4      P                  4       9  d   Th Rp? K  Rp?ii ; ii ; i	  \        P                  RT 24       R#   \         d)   p\        P                  R\        T4       24       ThRp?ii ; i)	z,
Crea directorios en FTP de forma recursiva
zDirectorio FTP existe: Nr    zDirectorio FTP creado: rF   z*Estructura de directorios FTP verificada: zError creando directorios FTP: )cwdrA   rH   r   r   r   splitmkdr   rb   rB   rI   rQ   )r   r   
path_partscurrent_pathpartrT   s   &&    r"   r   r     sI   #	LL(LL2>2BCD   		
 $))#.44S9
DC$J&L	 \*$$   LL.LL#:<.!IJ((  s1v||~5 6   " 	@@PQR 6s1vh?@sv   ). AE AAE BE D%4)C E  D!5 DD%E D!!D%%E E7#E22E7c                H    V ^8  d   QhR\         R\        R\         R\        /# )r   r   r   r   r   )r   r   r    )r!   s   "r"   r#   r#     s(     
 
 
c 
s 
t 
r$   c                     \        WV4      #   \         d4   p\        P                  R\	        T4       24       RRRRRR/u Rp?# Rp?ii ; i)	ul   
Crea un nuevo DocsHead (cada upload individual genera su propio grupo)
REUTILIZABLE para cualquier módulo
zError gestionando DocsHead: r'   Fr(   z1Error interno al gestionar registro de documentosr)   DOCS_HEAD_ERRORN)r	   rI   rA   rQ   r   )r   r   r   rT   s   &&& r"   rN   rN     sW    
	
w
;; 
3CF8<=uJ%
 	

s    A(AAAc                `    V ^8  d   QhR\         R\        R\        R\        R\        R\        /# )r   r1   r   r   rutar:   r   )r   r   r    )r!   s   "r"   r#   r#     s9     
 
c 
# 
C 
!
.1
6:
r$   c                     \        V 4      p\        WWW44      #   \         d4   p\        P	                  R\        T4       24       RRRRRR/u Rp?# Rp?ii ; i)	uA   
Crea registro en DocsDetail
REUTILIZABLE para cualquier módulo
z%Error creando registro de documento: r'   Fr(   z$Error interno al registrar documentor)   DOCS_DETAIL_ERRORN)r   r
   rI   rA   rQ   r   )r1   r   r   r   r:   doc_linerT   s   &&&&&  r"   rO   rO     se    
-g6 !EXX 
<SVHEFu='
 	

s    A(AAAc                $    V ^8  d   QhR\         /# )r   r   )r    )r!   s   "r"   r#   r#     s     & & &r$   c            
     D   . p \         R,          '       g   V P                  R4       \         R,          '       g   V P                  R4       \         R,          '       g   V P                  R4        \        P                  ! RR.R	^R
7      pVP                  ^ 8w  d   V P                  R4        \        P                  ! 4       p\        TR4      ;_uu_ 4       pTP                  R4       RRR4       \        P                  ! T4       R\        T 4      ^ 8H  RT R\        R,          R\!        \"        4      R\$        /#   \
        \        P                  3 d    T P                  R4        Li ; i  + '       g   i     L; i  \         d    T P                  R4        Li ; i)u]   
Verifica que la configuración del módulo sea correcta
REUTILIZABLE para cualquier módulo
r   zFTP_HOST no configurador   zFTP_USER no configurador   zFTP_PASS no configurador   z	--versionT)r   r   z ClamAV no responde correctamenteu(   ClamAV no está instalado o no accesiblewtestNz&No se pueden crear archivos temporalesconfiguracion_validaerroresu   tamaño_maximo_mbextensiones_permitidasbase_urlr`   )r   appendr   r   r   r   r   r   mktemprx   r   rD   rG   rI   lenrh   listrc   r   )r   r   	temp_testrz   s       r"   verificar_configuracionr     sU   
 G f01f01j!!01C[ 9$XYZ!NN=>
AOO%	)S!!QGGFO "
		)
 	G 17^{; $'=">H  z889 CABC "!  A?@As<   0=D; .)F  E-)F  ;,E*)E*-E=	8F   FFc                `    V ^8  d   QhR\         R\        R\        R\        R\        R\        /# )r   r   r1   r   r   r   r   )r   r   r   r    )r!   s   "r"   r#   r#   .  sJ     `^ `^{ `^S `^QT `^14`^EH`^MQ`^r$   c                   Rp \         P                  RV RV 24       \        V 4      pVR,          '       gn   RRRVR,          RR	/V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        V 4      pV'       gg   RRRRRR/V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        V4      pVR,          '       gn   RRRVR,          RR/V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        WRV4      p	V	R,          '       ga   T	V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # \        WW9R,          VR,          4      p
V
R,          '       ga   T
V'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # # RRRRV R2RRVRV
R,          RV	R,          RV	R,          RVR,          RVR,          RV P                  //p\         P                  RV RV
R,           24       TV'       dW   \        P                  P                  V4      '       d1    \        P                  ! V4       \         P                  R
V 24       # # #   \         d/   p\         P                  RT R\        T4       24        Rp?# Rp?ii ; i  \         d/   p\         P                  RT R\        T4       24        Rp?# Rp?ii ; i  \         d/   p\         P                  RT R\        T4       24        Rp?# Rp?ii ; i  \         d/   p\         P                  RT R\        T4       24        Rp?# Rp?ii ; i  \         d/   p\         P                  RT R\        T4       24        Rp?# Rp?ii ; i  \         d/   p\         P                  RT R\        T4       24        Rp?# Rp?ii ; i  \         d   pR\        T4       2p\         P!                  TRR7       RRRRRRR T/u Rp?T'       d   \        P                  P                  T4      '       dm    \        P                  ! T4       \         P                  R
T 24       #   \         d/   p\         P                  RT R\        T4       24        Rp?# Rp?ii ; i# # Rp?ii ; i  T'       d   \        P                  P                  T4      '       dm    \        P                  ! T4       \         P                  R
T 24       i   \         d/   p\         P                  RT R\        T4       24        Rp?i Rp?ii ; ii i ; i)!u  
Sube un documento a un DocsHead existente (no crea nuevo DocsHead)

Args:
    file_obj (FileStorage): Objeto archivo de Flask
    docs_id (int): DocsID existente donde agregar el archivo
    title (str): Título del archivo
    description (str): Descripción del archivo
    ruta_completa (str): Ruta completa (ej: "Ventas/Formularios/1001-2/FormPEmx")

Returns:
    dict: Resultado de la operación
Nz&Subiendo documento a DocsID existente r-   r&   r'   Fr(   r)   r*   r+   r,   r.   r/   r0   r2   r3   Tr4   r5   r6   r1   r7   r8   r9   r:   r;   zDocumento subido a DocsID z6Error inesperado en upload_document_to_existing_docs: r<   r>   r?   r@   )rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   r   rK   rL   rM   rO   rP   rQ   )r   r1   r   r   r   rR   rS   rT   rU   rV   rX   rY   rZ   s   &&&&&        r"    upload_document_to_existing_docsr   .  s     IN^<WIRwOP 38< ))5,Y7*F 	22^		)$;I;GH 39y +84	5<)t 	22^		)$;I;GH 39g 5Y?((5+I6(b 	22^		)$;I;GH 39U *)MJY'' P 	22^		)$;I;GH 39K 6K})Ek*
 "),,%@ 	22^		)$;I;GH 399 tUG+@A71-@n =}];.{;.{;!2!2
 	0	<N}<];^_` 	22^		)$;I;GH 39  ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^9 ^!FykQSTWXYTZS[\]]^!  
LSQRVHU	Y.u?$y	
 	
 	22^		)$;I;GH ^!FykQSTWXYTZS[\]]^	 39
 	22^		)$;I;GH ^!FykQSTWXYTZS[\]]^	 39s!  AS 5.M4&S ..N0(S 5.O,&S 0.P(!+S :.Q$+A*S .R 4N-?$N((N-0O);$O$$O),P%7$P  P%(Q!3$QQ!$R/$RR S+$SSV:'.V5V:V= .U77V0$V++V05V::V= =-Y,.XYY&$Y
YYYi    >   .doc.jpg.pdf.png.xls.docx.jpeg.xlsx)'rD   r   r   r   loggingpathlibr   werkzeug.utilsr   werkzeug.datastructuresr   dotenvr   typingr   r   )Consultas_SQL.Utilities.DocsManagementSQLr	   r
   r   	getLoggerrA   rh   rc   r   getenvr   r[   rC   rL   ro   rp   rK   rM   r   rN   rO   r   r    r$   r"   <module>r      s    
      * /      
		,	- ! ]  * BIIj!
BIIj!		*%%	
j^`6
p
>!
F,
d,DL'Z
 
2&P`^r$   