Files
MP-Manager/scripts/sync_workflows.py
T
2026-05-30 14:31:19 -06:00

127 lines
5.2 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Sincroniza y lista todos los workflows de todas las cuentas."""
import argparse
import os
import sys
import concurrent.futures
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT_DIR not in sys.path:
sys.path.insert(0, ROOT_DIR)
import sync_engine
import db
import error_logging
import script_audit
def fetch_and_save_workflows_for_location(location):
location_id = location["location_id"]
nombre = location["nombre"]
token = location["token"]
print(f"[{nombre}] Consultando workflows...")
try:
workflows = sync_engine.ghl_client.get_workflows(token, location_id)
db.save_workflows(location_id, workflows)
print(f"[{nombre}] Sincronizados {len(workflows)} workflows.")
return location_id, nombre, workflows, None
except Exception as e:
error_id = error_logging.log_error("sync_workflows_single_location_failed", e, {"location_id": location_id})
print(f"[{nombre}] Error: {str(e)} | error_id={error_id}")
return location_id, nombre, [], str(e)
def main():
parser = argparse.ArgumentParser(description="Sincroniza y lista todos los workflows de todas las cuentas.")
parser.add_argument("--location", help="ID de ubicación específica para sincronizar (por defecto todas)")
parser.add_argument("--include-main", action="store_true", help="Incluye la cuenta de marca principal")
parser.add_argument("--run-id", help="ID de auditoría para la ejecución del script")
args = parser.parse_args()
# Informar el inicio en la auditoría si hay run_id
if args.run_id:
script_audit.update_run_status(args.run_id, "running")
print("=== CONTROL DE SCRIPTS: sync_workflows.py ===")
print("Descripción: Obtiene todos los workflows de todas las cuentas de GHL y los almacena en SQLite.")
print("----------------------------------------------------------------------")
try:
# Cargar todas las cuentas
accounts = sync_engine.parse_accounts_csv()
if not args.include_main:
# Filtrar marca principal a menos que se especifique --include-main o se use una específica
accounts = [acc for acc in accounts if acc["location_id"] != "GbKkBpCmKu2QmloKFHy3" or args.location == "GbKkBpCmKu2QmloKFHy3"]
if args.location:
accounts = [acc for acc in accounts if acc["location_id"] == args.location]
if not accounts:
print(f"Error: No se encontró la ubicación {args.location} en el CSV.")
if args.run_id:
script_audit.update_run_status(args.run_id, "failed", error_message=f"Location {args.location} not found")
sys.exit(1)
print(f"Se procesarán {len(accounts)} cuenta(s)...")
# Ejecutar en paralelo con un máximo de 5 hilos
results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(fetch_and_save_workflows_for_location, acc) for acc in accounts]
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
# Imprimir resumen de los resultados
total_workflows = 0
total_active = 0
total_inactive = 0
total_draft = 0
failed_accounts = []
print("\n=== RESUMEN DE WORKFLOWS POR CUENTA ===")
print(f"{'Cuenta':<40} | {'Total':<6} | {'Active':<6} | {'Inactive':<8} | {'Draft':<6} | {'Estado':<10}")
print("-" * 88)
for loc_id, nombre, wfs, err in results:
if err:
failed_accounts.append((nombre, err))
print(f"{nombre:<40} | {'-':<6} | {'-':<6} | {'-':<8} | {'-':<6} | ERROR")
continue
active = sum(1 for w in wfs if w.get("status") in ("active", "published"))
inactive = sum(1 for w in wfs if w.get("status") == "inactive")
draft = sum(1 for w in wfs if w.get("status") == "draft")
total = len(wfs)
total_workflows += total
total_active += active
total_inactive += inactive
total_draft += draft
print(f"{nombre:<40} | {total:<6} | {active:<6} | {inactive:<8} | {draft:<6} | OK")
print("-" * 88)
print(f"{'TOTAL GENERAL':<40} | {total_workflows:<6} | {total_active:<6} | {total_inactive:<8} | {total_draft:<6} |")
print("----------------------------------------------------------------------")
# Mostrar detalle de errores si los hubo
if failed_accounts:
print("\nDetalle de errores:")
for name, err in failed_accounts:
print(f"- {name}: {err}")
# Registrar éxito en la auditoría si hay run_id
if args.run_id:
script_audit.update_run_status(args.run_id, "success")
print("\nSincronización completada con éxito.")
except Exception as e:
error_id = error_logging.log_error("sync_workflows_script_failed", e)
print(f"Error crítico en la ejecución del script: {e} | error_id={error_id}")
if args.run_id:
script_audit.update_run_status(args.run_id, "failed", error_message=str(e))
sys.exit(1)
if __name__ == "__main__":
main()