Skip to content

Commit

Permalink
Corrige mensajes de error en FileProcessor y mejora la validación de …
Browse files Browse the repository at this point in the history
…estructuras en FolderAnalyzer. Actualiza la versión a 1.4.2 y elimina métodos innecesarios en MetadataExtractor.
  • Loading branch information
HammerDev99 committed Dec 27, 2024
1 parent dd197e1 commit 0037b69
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 77 deletions.
10 changes: 5 additions & 5 deletions assets/version_info.rc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
VSVersionInfo(
ffi=FixedFileInfo(
filevers=(1, 4, 1, 0),
prodvers=(1, 4, 1, 0),
filevers=(1, 4, 2, 0),
prodvers=(1, 4, 2, 0),
mask=0x3f,
flags=0x0,
OS=0x40004,
Expand All @@ -15,12 +15,12 @@ VSVersionInfo(
u'040904B0', [
StringStruct(u'CompanyName', u'Daniel Arbelaez Alvarez - HammerDev99'),
StringStruct(u'FileDescription', u'GestionExpedienteElectronico_Version1'),
StringStruct(u'FileVersion', u'1.4.1.0'),
StringStruct(u'FileVersion', u'1.4.2.0'),
StringStruct(u'InternalName', u'GestionExpedienteElectronico_Version1'),
StringStruct(u'LegalCopyright', u'Daniel Arbelaez - Copyright © 2024. Licensed under the MIT License.'),
StringStruct(u'OriginalFilename', u'GestionExpedienteElectronico_v1.4.1.exe'),
StringStruct(u'OriginalFilename', u'GestionExpedienteElectronico_v1.4.2.exe'),
StringStruct(u'ProductName', u'GestionExpedienteElectronico_Version1'),
StringStruct(u'ProductVersion', u'1.4.1.0'),
StringStruct(u'ProductVersion', u'1.4.2.0'),
StringStruct(u'Comments', u'Este proyecto fue desarrollado para automatizar una función administrativa, asistiendo las operaciones manuales que haría un empleado en la conformación del expediente electrónico.')
]
)
Expand Down
2 changes: 1 addition & 1 deletion file_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, input: str, indice, despacho, subserie, rdo, logger=None):
self.rdo = rdo

except Exception as e:
self.logger.error(f"Error en inicialización: {str(e)}", exc_info=True)
self.logger.error(f"Error en inicializació de FileProcessor¨: {str(e)}", exc_info=True)
raise

def rename_files(self, files, nombres_extensiones, ruta):
Expand Down
8 changes: 2 additions & 6 deletions folder_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,9 @@ def obtener_lista_rutas_subcarpetas(

if hay_archivos:
self.logger.error(
"Error en la estructura: Se encontraron archivos donde debería haber carpetas"
"Error en la estructura: Se encontraron archivos o carpetas vacías donde debería haber carpetas con contenido"
)
return (
[],
[],
set(),
) # Retorna listas vacías si la estructura contiene archivos
return [], [], set()

# Procesar cada directorio
for dir_actual, ruta_base in directorios_a_procesar:
Expand Down
118 changes: 72 additions & 46 deletions gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(self, root, logger=None):
self.profundidad = None
try:
super().__init__(root)
root.title("GestionExpedienteElectronico")
root.title("GestionExpedienteElectronico"+ "_Version1"+".4.2")
root.resizable(False, False)
# root.geometry("350x300")
root.protocol("WM_DELETE_WINDOW", self._on_closing)
Expand All @@ -51,6 +51,20 @@ def __init__(self, root, logger=None):
self.logger.error(f"Error en inicialización GUI: {str(e)}", exc_info=True)
raise

def _restablecer_variables_clase(self):
"""
Restablece las variables de la clase a su estado inicial.
"""
self.expediente = ""
self.carpetas = []
self.lista_subcarpetas = []
self.analyzer = None
self.profundidad = None
self.carpetas_omitidas = list()

self.lista_cui = []
self.estructura_directorios = {}

def create_oneProcessWidgets(self):
"""
@modules: tkinter
Expand Down Expand Up @@ -107,12 +121,15 @@ def create_oneProcessWidgets(self):
self.label_frame = tk.Frame(self)
self.label_frame.pack(side=tk.BOTTOM, padx=10, pady=10)

# Definir una constante para el literal "<Button-1>"
BUTTON_CLICK_EVENT = "<Button-1>"

self.label1 = tk.Label(
self.label_frame, text="Daniel Arbelaez Alvarez", fg="blue", cursor="hand2"
)
self.label1.pack(side=tk.LEFT)
self.label1.bind(
"<Button-1>",
BUTTON_CLICK_EVENT,
lambda e: self._callback("https://www.linkedin.com/in/daniel-arbelaez-/"),
)

Expand All @@ -121,7 +138,7 @@ def create_oneProcessWidgets(self):
)
self.label2.pack(side=tk.LEFT)
self.label2.bind(
"<Button-1>",
BUTTON_CLICK_EVENT,
lambda e: self._callback("https://github.com/HammerDev99"),
)

Expand Down Expand Up @@ -209,17 +226,17 @@ def create_oneProcessWidgets(self):

self.text_widget.insert(
tk.END,
"📋 Guía Rápida del Programa\n\n"
"\n📋 Guía Rápida del Programa\n\n"
"1. Preparación de Carpetas\n"
"• Carpetas limpias: Sin índice ni carpetas de anexos masivos\n"
"• Nombres de archivos: Organizados secuencialmente\n"
"• Nombres de archivos: Organizados mínimo secuencialmente\n"
"• Radicado: Debe contener 23 dígitos\n\n"
"2 Estructura de Carpetas\n"
"2. Estructura de Carpetas\n"
"🔹 Opción 1 (Un expediente):\n"
" RADICADO/01PrimeraInstancia/C01Principal/Archivos\n"
"🔹 Opción 2 (Varios expedientes):\n"
" SERIE_SUBSERIE/RADICADO/01PrimeraInstancia/C01Principal/Archivos\n\n"
"3 Datos del SGDE\n"
"3. Datos del SGDE\n"
"• Use exactamente los mismos datos de 'Juzgado' y 'Serie/Subserie' registrados en migrador/validador y/o la TRD\n\n",
)

Expand Down Expand Up @@ -343,10 +360,7 @@ def _cleanup(self):
)

# Restablecer variables
self.expediente = ""
self.carpetas = []
self.lista_subcarpetas = []
self.analyzer = None
self._restablecer_variables_clase()

self.logger.debug("Limpieza de recursos completada")

Expand Down Expand Up @@ -442,46 +456,54 @@ def obtener_rutas(self):
"La estructura de directorios no coincide con la OPCIÓN seleccionada.\n\n"
"Por favor, verifique la estructura interna de los directorios seleccionados.",
)
rutas_invalidas = self.validar_estructura_carpetas(estructura_directorios, self.selected_value)
rutas_invalidas = self.validar_estructura_carpetas(
estructura_directorios, self.selected_value
)
self.logger.warning(
f"La estructura de los siguientes directorios no coincide con la OPCIÓN seleccionada: {rutas_invalidas}"
)

def validar_estructura_carpetas(self, estructura_directorios, selected_value):
"""
Valida la estructura de carpetas y retorna rutas inválidas.
Args:
estructura_directorios (dict): Diccionario con estructura de carpetas
selected_value (str): Opción seleccionada ("2" o "3")
Returns:
list: Rutas que contienen subcarpetas no permitidas
"""
rutas_invalidas = []
nivel_maximo = self._obtener_nivel_maximo(selected_value)

self._analizar_estructura(estructura_directorios, "", 0, nivel_maximo, rutas_invalidas)

self._analizar_estructura(
estructura_directorios, "", 0, nivel_maximo, rutas_invalidas
)
self._mostrar_rutas_invalidas(rutas_invalidas)

return rutas_invalidas

def _obtener_nivel_maximo(self, selected_value):
"""Determina nivel máximo según opción seleccionada."""
return 2 if selected_value == "2" else 3

def _analizar_estructura(self, directorio, ruta_actual, nivel, nivel_maximo, rutas_invalidas):
def _analizar_estructura(
self, directorio, ruta_actual, nivel, nivel_maximo, rutas_invalidas
):
"""Analiza recursivamente la estructura buscando carpetas invalidas."""
if not isinstance(directorio, dict):
return

if nivel >= nivel_maximo:
self._verificar_subcarpetas(directorio, ruta_actual, rutas_invalidas)
return

for nombre, contenido in directorio.items():
nueva_ruta = os.path.join(ruta_actual, nombre)
self._analizar_estructura(contenido, nueva_ruta, nivel + 1, nivel_maximo, rutas_invalidas)
self._analizar_estructura(
contenido, nueva_ruta, nivel + 1, nivel_maximo, rutas_invalidas
)

def _verificar_subcarpetas(self, directorio, ruta_actual, rutas_invalidas):
"""Verifica si existen subcarpetas en el nivel actual."""
Expand Down Expand Up @@ -526,7 +548,8 @@ def _mostrar_carpeta_seleccionada(self, folder_selected):
folder_selected (str): Ruta de la carpeta seleccionada
"""
self.text_widget.insert(
tk.END, f"\n*******************\n❕ Carpeta seleccionada: {folder_selected}"
tk.END,
f"\n*******************\n❕ Carpeta seleccionada: {folder_selected}\n",
)
self.text_widget.see(tk.END)

Expand Down Expand Up @@ -578,11 +601,14 @@ def _mostrar_carpetas_omitidas(self):
if self.carpetas_omitidas:
# self._mensaje(None, f"Se encontraron {len(self.carpetas_omitidas)} carpetas que no cumplen con la estructura de directorios")

mensaje_detalle = "\n\n📂 Las siguientes carpetas están vacías y no serán incluidas en el procesamiento: "
# o no cumplen con la estructura de carpetas
mensaje_detalle += " ".join(
f"{carpeta}, " for carpeta in sorted(self.carpetas_omitidas)
)
mensaje_detalle = "❕ Las siguientes carpetas están vacías y no serán incluidas en el procesamiento:\n- "
carpetas_omitidas_ordenadas = sorted(self.carpetas_omitidas)

if carpetas_omitidas_ordenadas:
mensaje_detalle += ".\n- ".join(carpetas_omitidas_ordenadas[:-1])
if len(carpetas_omitidas_ordenadas) > 1:
mensaje_detalle += ".\n- "
mensaje_detalle += carpetas_omitidas_ordenadas[-1] + "."

self.text_widget.insert(tk.END, mensaje_detalle + "\n")
self.text_widget.see(tk.END)
Expand All @@ -603,13 +629,22 @@ def _mostrar_cuis_invalidos(self, cuis_invalidos, lista_cui):
if cuis_invalidos:
# self._mensaje(None, "Algunas carpetas no cumplen con el formato requerido de 23 dígitos numéricos.")

mensaje = "\n#️⃣ Se encontraron carpetas que no cumplen con el formato de 23 dígitos:\n"
mensaje = " Se encontraron radicados (CUI) que no tienen los 23 dígitos: "
if self.selected_value == "3":
mensaje += " ".join(f"{cui}, " for cui in sorted(cuis_invalidos))
cuis_invalidos_ordenados = sorted(cuis_invalidos)
if cuis_invalidos_ordenados:
mensaje += ", ".join(cuis_invalidos_ordenados[:-1])
if len(cuis_invalidos_ordenados) > 1:
mensaje += ", "
mensaje += cuis_invalidos_ordenados[-1] + "."
else:
mensaje += " ".join(f"{cui}, " for cui in lista_cui)
if lista_cui:
mensaje += ", ".join(lista_cui[:-1])
if len(lista_cui) > 1:
mensaje += ", "
mensaje += lista_cui[-1] + "."

self.text_widget.insert(tk.END, mensaje)
self.text_widget.insert(tk.END, mensaje + "\n")
self.text_widget.see(tk.END)

def handle_directory_analysis(
Expand All @@ -633,6 +668,7 @@ def handle_directory_analysis(
analyzer (FolderAnalyzer, opcional): Instancia del analizador de carpetas
"""
# Verificar si las listas están vacías o tienen valores por defecto de error
# Analizar si se debe hacer la validación en este método o en obtener_rutas
if not self._validar_estructura_expediente(
lista_cui, lista_subcarpetas, carpetas_omitidas
):
Expand Down Expand Up @@ -711,17 +747,16 @@ async def procesa_expedientes(self):

# Confirmar procesamiento
if not tk.messagebox.askyesno(
message=f'Se procesarán {total_carpetas} carpetas que contiene la carpeta {os.path.basename(self.expediente)}". \n¿Desea continuar?.',
message=f'Se procesarán {total_carpetas} cuadernos/expedientes que contiene la carpeta {os.path.basename(self.expediente)}". \n¿Desea continuar?.',
title=os.path.basename(self.expediente),
):
self.expediente = ""
self.carpetas = []
self._restablecer_variables_clase()
self._mensaje(6)
return

# Iniciar procesamiento
self.progress["value"] = 0.1
self.text_widget.insert(tk.END, "\n\nProceso iniciado...\n")
self.text_widget.insert(tk.END, "❕Proceso iniciado...\n")
self.update_idletasks()

try:
Expand Down Expand Up @@ -768,9 +803,9 @@ async def procesa_expedientes(self):
# Finalizar procesamiento
self.progress["value"] = 1.0
self.update_idletasks()
self._cleanup_state()
self._restablecer_variables_clase()
self.text_widget.insert(
tk.END, "✅ Proceso completado.\n*******************\n"
tk.END, "✅ Proceso completado.\n*******************\n\n"
)
self.progress["value"] = 0
self.update_idletasks()
Expand All @@ -779,15 +814,6 @@ async def procesa_expedientes(self):
except Exception as e:
self.logger.error(f"Error en procesamiento: {str(e)}", exc_info=True)

def _cleanup_state(self):
"""Limpia el estado de la aplicación"""
self.expediente = ""
self.carpetas = []
self.lista_cui = []
self.lista_subcarpetas = []
self.estructura_directorios = {}
self.analyzer = None

def _mensaje(self, result=None, mensaje=None):
"""
@param: result tipo int
Expand Down
22 changes: 3 additions & 19 deletions metadata_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def get_metadata(self, files):
cantidadpag.append(self.page_counter(x))
observaciones.append("")
else:
# Si es carpeta o anexo masivo
fechamod.append(str(datetime.date.fromtimestamp(os.path.getmtime(x))))
tama.append("-")
cantidadpag.append("1")
Expand All @@ -60,28 +61,11 @@ def get_metadata(self, files):
comments = dict(
zip(extensiones, map(lambda x: extensiones.count(x), extensiones))
)
nombres_extensiones, _, _, _, _ = self.format_names(x, list_files)
nombres_extensiones, _, _, _, _, _ = self.format_names(x, list_files)
self.rename_files(list_files, nombres_extensiones, x)
observaciones.append("Archivos contenidos: " + str(comments))
return fechamod, tama, cantidadpag, observaciones

def set_comments_folder(self, extensiones):
"""
Establece la carpeta de comentarios contando las ocurrencias de cada extensión.
Args:
extensiones (List): Una lista de extensiones de archivos.
Returns:
Dict: Un diccionario con las extensiones como claves y sus conteos como valores.
Ejemplo:
>>> set_comments_folder(['.txt', '.pdf', '.txt'])
{'.txt': 2, '.pdf': 1}
"""
resultado = dict(
zip(extensiones, map(lambda x: extensiones.count(x), extensiones))
)

return resultado

@staticmethod
def separate_path(files):
"""
Expand Down Expand Up @@ -162,7 +146,7 @@ def format_names(self, ruta, files):
extensiones,
numeraciones,
ban,
nombres_indice,
nombres_indice
)

def _extraer_nombres_extensiones(self, ruta, files):
Expand Down

0 comments on commit 0037b69

Please sign in to comment.