173 lines
7.8 KiB
Python
173 lines
7.8 KiB
Python
import sys
|
||
import json
|
||
import os
|
||
import outlook_utilities
|
||
import database_utilities
|
||
import email_services
|
||
import logger_utilities
|
||
import document_processor
|
||
import file_manager
|
||
from datetime import datetime, timedelta
|
||
from config_loader import CONFIG
|
||
|
||
|
||
########################################################
|
||
if __name__ == "__main__":
|
||
|
||
# Configurar Logger (Redirige stdout a archivo y consola)
|
||
log_path = logger_utilities.setup_logger()
|
||
logger_utilities.limpiar_logs_antiguos(dias=30)
|
||
|
||
inicio_ejecucion = datetime.now()
|
||
print("="*60)
|
||
print(f"🚀 INICIO DE EJECUCIÓN: {inicio_ejecucion.strftime('%Y-%m-%d %H:%M:%S')}")
|
||
print(f"📄 Log guardado en: {log_path}")
|
||
print("="*60)
|
||
|
||
# Inicializar Base de Datos
|
||
database_utilities.init_db()
|
||
|
||
# Calcular fechas
|
||
hoy = datetime.now()
|
||
ayer = hoy - timedelta(days=1)
|
||
|
||
fecha_inicio = ayer.strftime("%Y-%m-%d")
|
||
fecha_fin = hoy.strftime("%Y-%m-%d")
|
||
|
||
print(f"Rango de búsqueda: {fecha_inicio} al {fecha_fin}")
|
||
|
||
try:
|
||
print("Intentando obtener token de acceso...")
|
||
outlook_token = outlook_utilities.get_access_token()
|
||
print("✅ Token obtenido exitosamente.")
|
||
print(f"Token prefix: {outlook_token[:15]}...")
|
||
except Exception as e:
|
||
print(f"❌ Error: {e}")
|
||
sys.exit(1)
|
||
|
||
todos_procesados = []
|
||
|
||
for mail in CONFIG.mails:
|
||
print("\n" + "="*60)
|
||
print(f"[MAIL] {mail.email}")
|
||
|
||
emails = outlook_utilities.get_emails(mail.email, outlook_token, fecha_inicio, fecha_fin)
|
||
print(f"Se encontraron {len(emails)} correos.")
|
||
|
||
# Filtrar y guardar usando el servicio de emails
|
||
emails_a_procesar = email_services.filtrar_correos_nuevos(emails)
|
||
|
||
if emails_a_procesar:
|
||
print(f"Descargando adjuntos en: {mail.ruta_descarga}")
|
||
emails_finales = [] # Lista definitiva de correos con adjuntos válidos
|
||
|
||
for e in emails_a_procesar:
|
||
try:
|
||
# Guardar lista original para el log
|
||
archivos_orig = outlook_utilities.download_attachments(
|
||
mail.email,
|
||
e['id'],
|
||
outlook_token,
|
||
mail.ruta_descarga
|
||
)
|
||
|
||
if archivos_orig:
|
||
# Encabezado del correo con fecha
|
||
print(f"\n📬 [{e['fecha']}] {e['subject'][:80]}...")
|
||
|
||
# --- SECCIÓN 1: ADJUNTOS ORIGINALES ---
|
||
print(f" ├── 📂 Adjuntos originales:")
|
||
for idx, a in enumerate(archivos_orig):
|
||
prefijo = " │ └── " if idx == len(archivos_orig)-1 else " │ ├── "
|
||
print(f"{prefijo}{a}")
|
||
|
||
# 1. Procesar adjuntos (unzip + filtro)
|
||
# Usamos una copia de la lista original
|
||
archivos_unzipped = email_services.procesar_adjuntos_email(e, archivos_orig.copy(), mail.ruta_descarga)
|
||
|
||
if archivos_unzipped:
|
||
# 2. Extraer metadatos iniciales (antes del renombrado)
|
||
metadatos = document_processor.procesar_adjuntos_enriquecidos(e, mail.ruta_descarga)
|
||
e['metadatos_adjuntos'] = metadatos
|
||
|
||
# 3. Aplicar lógica de agrupación y renombrado
|
||
# Esto modifica e['metadatos_adjuntos'] in-place
|
||
agrupacion = file_manager.procesar_renombrado_agrupado(e, mail.ruta_descarga)
|
||
e['agrupacion_archivos'] = agrupacion
|
||
|
||
# --- SECCIÓN 2: PROCESO ---
|
||
print(f" ├── ⚙️ Proceso:")
|
||
logs_proceso = []
|
||
|
||
# Detectar ZIPs procesados
|
||
zips = [a for a in archivos_orig if a.lower().endswith('.zip')]
|
||
for z in zips:
|
||
logs_proceso.append(f"📦 Descomprimido: {z}")
|
||
|
||
# Detectar Renombrados (si el nombre final no está en los unzipped filtrados)
|
||
for m in e['metadatos_adjuntos']:
|
||
if m['archivo'] not in archivos_unzipped:
|
||
logs_proceso.append(f"🏷️ Renombrado a: {m['archivo']}")
|
||
|
||
if not logs_proceso:
|
||
print(f" │ └── Sin cambios especiales")
|
||
else:
|
||
for idx, log in enumerate(logs_proceso):
|
||
prefijo = " │ └── " if idx == len(logs_proceso)-1 else " │ ├── "
|
||
print(f"{prefijo}{log}")
|
||
|
||
# 4. Mover archivos a carpeta de resultados final
|
||
file_manager.mover_archivos_a_resultado(e, mail.ruta_descarga, mail.ruta_final)
|
||
|
||
# --- SECCIÓN 3: RESULTADO FINAL ---
|
||
print(f" └── 📄 Resultado Final:")
|
||
for idx, m in enumerate(e['metadatos_adjuntos']):
|
||
prefijo = " └── " if idx == len(e['metadatos_adjuntos'])-1 else " ├── "
|
||
icono = "📕" if m['extension'] == ".pdf" else "🌐"
|
||
info_extra = f"[{m['tipo']}] {m['serie_numero']} - RUC: {m['ruc']}"
|
||
print(f"{prefijo}{icono} {m['archivo']} -> {info_extra}")
|
||
|
||
emails_finales.append(e)
|
||
else:
|
||
print(f" └── ℹ️ Descartado (sin archivos PDF/XML válidos).")
|
||
|
||
except Exception as ex:
|
||
print(f" ❌ Error procesando {e['id'][:10]}: {ex}")
|
||
|
||
# 5. Sincronizar a SMB al terminar de procesar TODOS los correos de esta cuenta
|
||
if emails_finales:
|
||
import smb_utils
|
||
smb_utils.sincronizar_a_smb(mail.ruta_final, mail.smb_folder)
|
||
|
||
# 6. Limpiar carpeta de descarga original
|
||
file_manager.limpiar_carpeta_descarga(mail.ruta_descarga)
|
||
|
||
# Actualizamos el listado con los que realmente tienen contenido útil
|
||
emails_a_procesar = emails_finales
|
||
print(f"\n✅ Proceso completado para {mail.email}. {len(emails_a_procesar)} correos listos para procesar.")
|
||
|
||
# Acumular para el guardado final en JSON
|
||
todos_procesados.extend(emails_a_procesar)
|
||
|
||
# Guardar resultados globales en JSON
|
||
if todos_procesados:
|
||
output_dir = "output_json"
|
||
if not os.path.exists(output_dir):
|
||
os.makedirs(output_dir)
|
||
|
||
timestamp_json = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||
json_path = os.path.join(output_dir, f"{timestamp_json}.json")
|
||
|
||
with open(json_path, "w", encoding="utf-8") as f:
|
||
json.dump(todos_procesados, f, ensure_ascii=False, indent=4)
|
||
|
||
print("\n" + "="*60)
|
||
print(f"💾 Resultados exportados a: {json_path}")
|
||
|
||
fin_ejecucion = datetime.now()
|
||
duracion = fin_ejecucion - inicio_ejecucion
|
||
print("\n" + "="*60)
|
||
print(f"🏁 FIN DE EJECUCIÓN: {fin_ejecucion.strftime('%Y-%m-%d %H:%M:%S')}")
|
||
print(f"⏱️ Duración total: {str(duracion).split('.')[0]}") # Sin microsegundos
|
||
print("="*60)
|