se agrega manejo de ejecución por horarios
This commit is contained in:
1 parent
9c7634f975
commit
fcc80d3c6e
2 files changed
+105
-16
No files matched your search
@@ -1,11 +1,42 @@
|
|||||||
import os
|
import os
|
||||||
|
import time
|
||||||
import argparse
|
import argparse
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
import logger_utilities
|
import logger_utilities
|
||||||
from pipeline import run_pipeline
|
from pipeline import run_pipeline
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
HORARIOS = [
|
||||||
|
(6, 30, 13, 15, 300, "rapido"), # 06:30 - 13:15 -> cada 5 minutos
|
||||||
|
(13, 15, 14, 0, 1800, "full"), # 13:15 - 14:00 -> cada 30 minutos
|
||||||
|
(14, 0, 18, 30, 300, "rapido"), # 14:00 - 17:30 -> cada 5 minutos
|
||||||
|
(18, 30, 21, 30, 3600, "full"), # 17:30 - 21:30 -> cada 60 minutos
|
||||||
|
]
|
||||||
|
# ============================================================================
|
||||||
|
def obtener_intervalo(dt: datetime) -> tuple[int, str] | None:
|
||||||
|
minutos = dt.hour * 60 + dt.minute
|
||||||
|
|
||||||
|
for hi, mi, hf, mf, intervalo, modo in HORARIOS:
|
||||||
|
inicio = hi * 60 + mi
|
||||||
|
fin = hf * 60 + mf
|
||||||
|
|
||||||
|
if inicio <= minutos < fin:
|
||||||
|
return (intervalo, modo)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
def segundos_hasta_proximo_inicio(dt: datetime) -> int:
|
||||||
|
inicio = dt.replace(hour=6, minute=30, second=0, microsecond=0)
|
||||||
|
|
||||||
|
if dt >= inicio:
|
||||||
|
inicio += timedelta(days=1)
|
||||||
|
|
||||||
|
return int((inicio - dt).total_seconds())
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
def non_negative_int(value: str) -> int:
|
def non_negative_int(value: str) -> int:
|
||||||
ivalue = int(value)
|
ivalue = int(value)
|
||||||
@@ -33,18 +64,57 @@ def main() -> None:
|
|||||||
|
|
||||||
dias = args.dias
|
dias = args.dias
|
||||||
|
|
||||||
if dias == 0:
|
|
||||||
print("📋 Obteniendo correos electrónicos de Office365 hoy.")
|
|
||||||
else:
|
|
||||||
print(f"📋 Obteniendo correos electrónicos de Office365 desde hace {dias} días hasta hoy.")
|
|
||||||
|
|
||||||
load_dotenv(dotenv_path=".env.dev")
|
load_dotenv(dotenv_path=".env.dev")
|
||||||
|
|
||||||
EMAIL = os.getenv("EMAIL", "")
|
EMAIL = os.getenv("EMAIL", "")
|
||||||
DOWNLOAD_FOLDER = os.getenv("DOWNLOAD_FOLDER", "")
|
DOWNLOAD_FOLDER = os.getenv("DOWNLOAD_FOLDER", "")
|
||||||
OUTPUT_FOLDER = os.getenv("OUTPUT_FOLDER", "")
|
OUTPUT_FOLDER = os.getenv("OUTPUT_FOLDER", "")
|
||||||
|
|
||||||
run_pipeline(dias, EMAIL, DOWNLOAD_FOLDER, OUTPUT_FOLDER)
|
print("🚀 Demonio iniciado")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
inicio_ciclo = datetime.now()
|
||||||
|
|
||||||
|
resultado = obtener_intervalo(inicio_ciclo)
|
||||||
|
|
||||||
|
if resultado is not None:
|
||||||
|
|
||||||
|
intervalo, modo = resultado
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n[{inicio_ciclo:%Y-%m-%d %H:%M:%S}] "
|
||||||
|
f"Iniciando ciclo [{modo}] (cada {intervalo}s)"
|
||||||
|
)
|
||||||
|
|
||||||
|
run_pipeline(dias, EMAIL, DOWNLOAD_FOLDER, OUTPUT_FOLDER)
|
||||||
|
|
||||||
|
duracion = (datetime.now() - inicio_ciclo).total_seconds()
|
||||||
|
|
||||||
|
if duracion > intervalo:
|
||||||
|
print(
|
||||||
|
f"⚠️ El ciclo demoró {duracion:.1f}s "
|
||||||
|
f"(intervalo configurado {intervalo}s)"
|
||||||
|
)
|
||||||
|
|
||||||
|
dormir = max(0, intervalo - duracion)
|
||||||
|
|
||||||
|
print(f"💤 Próximo ciclo [{modo}] en {dormir:.0f}s...")
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
dormir = segundos_hasta_proximo_inicio(inicio_ciclo)
|
||||||
|
|
||||||
|
despertar = inicio_ciclo + timedelta(seconds=dormir)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n[{inicio_ciclo:%Y-%m-%d %H:%M:%S}] "
|
||||||
|
f"Fuera del horario.\n"
|
||||||
|
f"Próxima ejecución: {despertar:%Y-%m-%d %H:%M:%S}"
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(dormir)
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
@@ -52,17 +122,9 @@ if __name__ == "__main__":
|
|||||||
log_path = logger_utilities.setup_logger()
|
log_path = logger_utilities.setup_logger()
|
||||||
logger_utilities.limpiar_logs_antiguos(dias=30)
|
logger_utilities.limpiar_logs_antiguos(dias=30)
|
||||||
|
|
||||||
inicio = datetime.now()
|
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
print(f"🚀 INICIO DE EJECUCIÓN: {inicio.strftime('%Y-%m-%d %H:%M:%S')}")
|
print(f"🚀 Demonio iniciado: {datetime.now():%Y-%m-%d %H:%M:%S}")
|
||||||
print(f"📄 Log guardado en: {log_path}")
|
print(f"📄 Log guardado en: {log_path}")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
fin = datetime.now()
|
|
||||||
duracion = fin - inicio
|
|
||||||
print("\n" + "=" * 60)
|
|
||||||
print(f"🏁 FIN DE EJECUCIÓN: {fin.strftime('%Y-%m-%d %H:%M:%S')}")
|
|
||||||
print(f"⏱️ Duración total: {str(duracion).split('.')[0]}")
|
|
||||||
print("=" * 60)
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=64"]
|
||||||
|
build-backend = "setuptools.backends._legacy:_Backend"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "descarga_factura_transporte"
|
||||||
|
version = "1.1.0"
|
||||||
|
description = "Descarga y procesamiento de facturas de transporte desde Office365"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = [
|
||||||
|
"certifi==2026.6.17",
|
||||||
|
"cffi==2.1.0",
|
||||||
|
"charset-normalizer==3.4.9",
|
||||||
|
"cryptography==49.0.0",
|
||||||
|
"dotenv==0.9.9",
|
||||||
|
"idna==3.18",
|
||||||
|
"msal==1.37.0",
|
||||||
|
"pdfminer.six==20260107",
|
||||||
|
"pdfplumber==0.11.10",
|
||||||
|
"pillow==12.3.0",
|
||||||
|
"pycparser==3.0",
|
||||||
|
"PyJWT==2.13.0",
|
||||||
|
"pypdfium2==5.11.0",
|
||||||
|
"python-dotenv==1.2.2",
|
||||||
|
"requests==2.34.2",
|
||||||
|
"urllib3==2.7.0",
|
||||||
|
]
|
||||||
Reference in new issue
Block a user