# main.py — Mapa del flujo ## Estructura general ``` main.py ├── Constantes: HORARIOS (4 bloques horarios) ├── obtener_intervalo(dt) → (intervalo, modo) | None ├── segundos_hasta_proximo_inicio(dt) → int ├── non_negative_int(value) → int (validador argparse) └── main() → None ``` ## Proceso de `main()` ```mermaid flowchart TD A[Inicio main] --> B[Parsear args --dias] B --> C[Cargar .env → EMAIL, DOWNLOAD_FOLDER, OUTPUT_FOLDER] C --> D{Bucle infinito} D --> E[inicio_ciclo = datetime.now] E --> F[obtener_intervalo inicio_ciclo] F -- Sí, está en horario --> G[Extraer intervalo, modo] G --> H[run_pipeline]:::highlight H --> I[Calcular duración real] I --> J{Duración > intervalo?} J -- Sí --> K[⚠️ Warning] J -- No --> L[dormir = intervalo - duración] K --> L L --> M[💤 Próximo ciclo en dormir seg] M --> N[time.sleep dormir] N --> E F -- No, fuera de horario --> O[dormir = segundos_hasta_proximo_inicio] O --> P[Log próxima ejecución] P --> N classDef highlight fill:#fff3e0,stroke:#e65100,stroke-width:3px; ``` ### Paso a paso ``` main() │ ├── 1. Parsear args (--dias, default=2) │ ├── 2. Cargar .env → EMAIL, DOWNLOAD_FOLDER, OUTPUT_FOLDER │ ├── 3. LOOP INFINITO (while True): │ │ │ ├── 3.1. inicio_ciclo = datetime.now() │ │ │ ├── 3.2. resultado = obtener_intervalo(inicio_ciclo) │ │ │ │ ├── ¿Sí está en horario? │ │ │ │ │ ├── Extraer (intervalo, modo) │ │ ├── run_pipeline(dias, EMAIL, DOWNLOAD_FOLDER, OUTPUT_FOLDER) │ │ ├── Calcular duración real del ciclo │ │ ├── ⚠️ Si duración > intervalo → warning │ │ └── dormir = max(0, intervalo - duración) │ │ │ └── ¿No está en horario? │ │ │ ├── dormir = segundos_hasta_proximo_inicio() (06:30 del día siguiente) │ └── Log "Fuera del horario, próxima ejecución en..." │ └── 4. time.sleep(dormir) → vuelve a 3.1 ``` ## Bloques horarios definidos | Desde | Hasta | Intervalo | Modo | |---------|---------|-----------|----------| | 06:30 | 13:15 | 300s | rápido | | 13:15 | 14:00 | 1800s | full | | 14:00 | 18:30 | 300s | rápido | | 18:30 | 21:30 | 3600s | full | Fuera de ese rango → duerme hasta las 06:30 del día siguiente. ## Entry point (línea 121-130) ``` if __name__ == "__main__": 1. logger_utilities.setup_logger() 2. logger_utilities.limpiar_logs_antiguos(dias=30) 3. main() ```