# ToUpload/x0_main.py import argparse import subprocess import os import sys import locale import glob import time import traceback # <--- Mover import aquí # --- Funciones --- def get_console_encoding(): """Obtiene la codificación preferida de la consola, con fallback.""" try: return locale.getpreferredencoding(False) except Exception: return "cp1252" CONSOLE_ENCODING = get_console_encoding() def run_script(script_name, xml_arg, *extra_args): """Runs a given script with the specified XML file argument and optional extra args.""" script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), script_name) python_executable = sys.executable command = [python_executable, script_path, os.path.abspath(xml_arg)] command.extend(extra_args) print( f"\n--- Running {script_name} with arguments: {[os.path.relpath(arg) if os.path.exists(arg) else arg for arg in command[2:]]} ---" ) try: result = subprocess.run( command, check=True, capture_output=True, text=True, encoding=CONSOLE_ENCODING, errors="replace", ) 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: print(f"--- Stderr ({script_name}) ---", file=sys.stderr) print(stderr_clean, file=sys.stderr) print("--------------------------", file=sys.stderr) return True except FileNotFoundError: print( f"Error: Script '{script_path}' or Python executable '{python_executable}' not found.", file=sys.stderr, ) return False except subprocess.CalledProcessError as e: print( f"Error running {script_name}: Script returned non-zero exit code {e.returncode}.", file=sys.stderr, ) stdout_decoded = e.stdout.strip() if e.stdout else "" stderr_decoded = e.stderr.strip() if e.stderr else "" # Asegurar indentación correcta aquí 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) # El return debe estar fuera de los if, pero dentro del except return False except Exception as e: print( f"An unexpected error occurred while running {script_name}: {e}", file=sys.stderr, ) # No necesitamos importar traceback aquí si ya está al inicio traceback.print_exc(file=sys.stderr) return False # --- Bloque Principal --- if __name__ == "__main__": # --- PARTE 1: BUSCAR ARCHIVOS --- base_search_dir = "XML Project" 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}'") if not os.path.isdir(xml_project_dir): print(f"Error: El directorio '{xml_project_dir}' no existe.", file=sys.stderr) sys.exit(1) 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) print(f"Se encontraron {len(xml_files_found)} archivos XML para procesar:") xml_files_found.sort() for xml_file in xml_files_found: print(f" - {os.path.relpath(xml_file, script_dir)}") # --- PARTE 2: EJECUTAR x1 PARA TODOS LOS ARCHIVOS --- print("\n--- Fase 1: Ejecutando x1_to_json.py para todos los archivos XML ---") script1 = "x1_to_json.py" failed_x1_files = [] processed_x1_count = 0 for xml_filepath in xml_files_found: relative_path = os.path.relpath(xml_filepath, script_dir) if run_script(script1, xml_filepath): print(f"--- {script1} completado para: {relative_path} ---") processed_x1_count += 1 else: print(f"--- {script1} FALLÓ para: {relative_path} ---", file=sys.stderr) failed_x1_files.append(relative_path) # ... (Resumen Fase 1 y manejo de errores sin cambios) ... print(f"\n--- Resumen Fase 1 (x1) ---") print(f"Archivos procesados por x1: {processed_x1_count}") print(f"Archivos fallidos en x1: {len(failed_x1_files)}") if failed_x1_files: print("Archivos fallidos:") [print(f" - {f}") for f in failed_x1_files] print("---------------------------") if len(failed_x1_files) == len(xml_files_found): print( "\nError Crítico: Todos los archivos fallaron en la Fase 1 (x1). Abortando.", file=sys.stderr, ) sys.exit(1) elif failed_x1_files: print( "\nAdvertencia: Algunos archivos fallaron en la Fase 1 (x1). Se continuará con los exitosos.", file=sys.stderr, ) successful_xml_files = [ f for f in xml_files_found if os.path.relpath(f, script_dir) not in failed_x1_files ] else: successful_xml_files = xml_files_found # --- PARTE 3: EJECUTAR x2 y x3 PARA LOS ARCHIVOS EXITOSOS DE x1 --- print("\n--- Fase 2: Ejecutando x2_process.py y x3_generate_scl.py ---") script2 = "x2_process.py" script3 = "x3_generate_scl.py" processed_pipeline_count = 0 failed_pipeline_files = set() for xml_filepath in successful_xml_files: relative_path = os.path.relpath(xml_filepath, script_dir) print(f"\n--- Iniciando pipeline (x2, x3) para: {relative_path} ---") # Ejecutar x2 success_x2 = run_script(script2, xml_filepath) if not success_x2: print( f"--- Pipeline falló en '{script2}' para: {relative_path} ---", file=sys.stderr, ) failed_pipeline_files.add(relative_path) continue print(f"--- {script2} completado para: {relative_path} ---") # Ejecutar x3, PASANDO la ruta raíz del proyecto success_x3 = run_script(script3, xml_filepath, xml_project_dir) if not success_x3: print( f"--- Pipeline falló en '{script3}' para: {relative_path} ---", file=sys.stderr, ) failed_pipeline_files.add(relative_path) continue print(f"--- {script3} completado para: {relative_path} ---") print( f"--- Pipeline (x2, x3) completado exitosamente para: {relative_path} ---" ) processed_pipeline_count += 1 # --- PARTE 4: RESUMEN FINAL --- total_processed_initially = len(successful_xml_files) final_failed_count = len(failed_pipeline_files) final_success_count = total_processed_initially - final_failed_count print("\n--- Resumen Final del Procesamiento Completo ---") print(f"Total de archivos XML encontrados: {len(xml_files_found)}") print( f"Archivos procesados por Fase 1 (x1): {processed_x1_count} (Fallidos: {len(failed_x1_files)})" ) print(f"Archivos procesados por Fase 2 (x2 y x3): {final_success_count}") print(f"Archivos que fallaron en Fase 2 (x2 o x3): {final_failed_count}") if failed_pipeline_files: print("Archivos fallidos en Fase 2:") for f in sorted(list(failed_pipeline_files)): print(f" - {f}") print("------------------------------------------------") if failed_x1_files or final_failed_count > 0: sys.exit(1) else: sys.exit(0)