Simatic_XML_Parser_to_SCL/ToUpload/x0_main.py

216 lines
7.8 KiB
Python

# 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)