import argparse import subprocess import os import sys import locale import glob # (Función get_console_encoding y variable CONSOLE_ENCODING como antes) def get_console_encoding(): """Obtiene la codificación preferida de la consola, con fallback.""" try: return locale.getpreferredencoding(False) except Exception: # Fallback común en Windows si falla getpreferredencoding return "cp1252" # O prueba con 'utf-8' si cp1252 da problemas CONSOLE_ENCODING = get_console_encoding() # print(f"Detected console encoding: {CONSOLE_ENCODING}") # (Función run_script como antes, usando CONSOLE_ENCODING) def run_script(script_name, xml_arg): """Runs a given script with the specified XML file argument.""" # Asegurarse que la ruta al script sea absoluta o relativa al script actual script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), script_name) # Usar la ruta absoluta al ejecutable de Python actual python_executable = sys.executable command = [python_executable, script_path, xml_arg] # Usar la ruta absoluta de python print(f"\n--- Running {script_name} with argument: {xml_arg} ---") try: # Ejecutar el proceso hijo result = subprocess.run( command, check=True, # Lanza excepción si el script falla (return code != 0) capture_output=True,# Captura stdout y stderr text=True, # Decodifica stdout/stderr como texto encoding=CONSOLE_ENCODING, # Usa la codificación detectada errors='replace' # Reemplaza caracteres no decodificables ) # Imprimir stdout y stderr si no están vacíos stdout_clean = result.stdout.strip() if result.stdout else "" stderr_clean = result.stderr.strip() if result.stderr else "" if stdout_clean: print(stdout_clean) if stderr_clean: # Imprimir stderr claramente para errores del script hijo print(f"--- Stderr ({script_name}) ---", file=sys.stderr) # Imprimir en stderr print(stderr_clean, file=sys.stderr) print("--------------------------", file=sys.stderr) print(f"--- {script_name} finished successfully ---") return True # Indicar éxito except FileNotFoundError: # Error si el script python o el ejecutable no se encuentran print(f"Error: Script '{script_path}' or Python executable '{python_executable}' not found.", file=sys.stderr) return False except subprocess.CalledProcessError as e: # Error si el script hijo devuelve un código de error (ej., sys.exit(1)) print(f"Error running {script_name}: Script returned non-zero exit code {e.returncode}.", file=sys.stderr) # Decodificar e imprimir stdout/stderr del proceso fallido stdout_decoded = e.stdout.strip() if e.stdout else "" stderr_decoded = e.stderr.strip() if e.stderr else "" if stdout_decoded: print(f"--- Stdout ({script_name}) ---", file=sys.stderr) print(stdout_decoded, file=sys.stderr) if stderr_decoded: print(f"--- Stderr ({script_name}) ---", file=sys.stderr) print(stderr_decoded, file=sys.stderr) print("--------------------------", file=sys.stderr) return False # Indicar fallo except Exception as e: # Otros errores inesperados print(f"An unexpected error occurred while running {script_name}: {e}", file=sys.stderr) # Imprimir traceback para depuración import traceback traceback.print_exc(file=sys.stderr) return False # Indicar fallo # --- NO SE NECESITA select_xml_file() si procesamos todos --- if __name__ == "__main__": # --- PARTE 1: BUSCAR ARCHIVOS --- # Directorio base donde buscar los archivos XML (relativo al script) base_search_dir = "XML Project" # Obtener la ruta absoluta del directorio donde está x0_main.py script_dir = os.path.dirname(os.path.abspath(__file__)) xml_project_dir = os.path.join(script_dir, base_search_dir) print(f"Buscando archivos XML recursivamente en: '{xml_project_dir}'") # Verificar si el directorio 'XML Project' existe if not os.path.isdir(xml_project_dir): print(f"Error: El directorio '{xml_project_dir}' no existe o no es un directorio.", file=sys.stderr) print("Por favor, crea el directorio 'XML Project' en la misma carpeta que este script y coloca tus archivos XML dentro.") sys.exit(1) # Salir con error # Buscar todos los archivos .xml recursivamente search_pattern = os.path.join(xml_project_dir, "**", "*.xml") xml_files_found = glob.glob(search_pattern, recursive=True) if not xml_files_found: print(f"No se encontraron archivos XML en '{xml_project_dir}' o sus subdirectorios.") sys.exit(0) # Salir limpiamente si no hay archivos print(f"Se encontraron {len(xml_files_found)} archivos XML para procesar:") xml_files_found.sort() # Ordenar para consistencia for xml_file in xml_files_found: print(f" - {os.path.relpath(xml_file, script_dir)}") # --- PARTE 2: PROCESAR CADA ARCHIVO --- # Scripts a ejecutar en secuencia script1 = "x1_to_json.py" script2 = "x2_process.py" script3 = "x3_generate_scl.py" processed_count = 0 failed_count = 0 # Procesar cada archivo encontrado en el bucle for xml_filepath in xml_files_found: relative_path = os.path.relpath(xml_filepath, script_dir) print(f"\n--- Iniciando pipeline para: {relative_path} ---") # Usar la ruta absoluta para los scripts hijos absolute_xml_filepath = os.path.abspath(xml_filepath) # Derivar nombres esperados para archivos intermedios (para depuración) xml_base_name = os.path.splitext(os.path.basename(absolute_xml_filepath))[0] xml_dir = os.path.dirname(absolute_xml_filepath) parsing_dir = os.path.join(xml_dir, "parsing") expected_json_file = os.path.join(parsing_dir, f"{xml_base_name}.json") expected_processed_json = os.path.join(parsing_dir, f"{xml_base_name}_processed.json") # Ejecutar los scripts en secuencia success = True if not run_script(script1, absolute_xml_filepath): print(f"\nPipeline falló en el script '{script1}' para el archivo: {relative_path}", file=sys.stderr) success = False elif not run_script(script2, absolute_xml_filepath): print(f"\nPipeline falló en el script '{script2}' para el archivo: {relative_path}", file=sys.stderr) success = False elif not run_script(script3, absolute_xml_filepath): print(f"\nPipeline falló en el script '{script3}' para el archivo: {relative_path}", file=sys.stderr) success = False # Actualizar contadores y mostrar estado if success: print(f"--- Pipeline completado exitosamente para: {relative_path} ---") processed_count += 1 else: failed_count += 1 print(f"--- Pipeline falló para: {relative_path} ---", file=sys.stderr) # Indicar fallo # --- PARTE 3: RESUMEN FINAL --- print("\n--- Resumen Final del Procesamiento ---") print(f"Total de archivos XML encontrados: {len(xml_files_found)}") print(f"Archivos procesados exitosamente por el pipeline completo: {processed_count}") print(f"Archivos que fallaron en algún punto del pipeline: {failed_count}") print("---------------------------------------") # Salir con código 0 si todo fue bien, 1 si hubo fallos if failed_count > 0: sys.exit(1) else: sys.exit(0) # --- FIN: Se elimina la lógica redundante que venía después del bucle ---