Simatic_XML_Parser_to_SCL/x0_main.py

145 lines
5.8 KiB
Python

import argparse
import subprocess
import os
import sys
import locale
import glob # <--- Importar glob para buscar archivos
# (Función get_console_encoding y variable CONSOLE_ENCODING como en la respuesta anterior)
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()
# Descomenta la siguiente línea si quieres ver la codificación detectada:
# print(f"Detected console encoding: {CONSOLE_ENCODING}")
# (Función run_script como en la respuesta anterior, usando CONSOLE_ENCODING)
def run_script(script_name, xml_arg):
"""Runs a given script with the specified XML file argument."""
script_path = os.path.join(os.path.dirname(__file__), script_name)
command = [sys.executable, script_path, xml_arg]
print(f"\n--- Running {script_name} with argument: {xml_arg} ---")
try:
result = subprocess.run(command,
check=True,
capture_output=True,
text=True,
encoding=CONSOLE_ENCODING,
errors='replace') # 'replace' para evitar errores
# Imprimir stdout y stderr
# Eliminar saltos de línea extra al final si existen
stdout_clean = result.stdout.strip()
stderr_clean = result.stderr.strip()
if stdout_clean:
print(stdout_clean)
if stderr_clean:
print("--- Stderr ---")
print(stderr_clean)
print("--------------")
print(f"--- {script_name} finished successfully ---")
return True
except FileNotFoundError:
print(f"Error: Script '{script_path}' not found.")
return False
except subprocess.CalledProcessError as e:
print(f"Error running {script_name}:")
print(f"Return code: {e.returncode}")
stdout_decoded = e.stdout.decode(CONSOLE_ENCODING, errors='replace').strip() if isinstance(e.stdout, bytes) else (e.stdout or "").strip()
stderr_decoded = e.stderr.decode(CONSOLE_ENCODING, errors='replace').strip() if isinstance(e.stderr, bytes) else (e.stderr or "").strip()
if stdout_decoded:
print("--- Stdout ---")
print(stdout_decoded)
if stderr_decoded:
print("--- Stderr ---")
print(stderr_decoded)
print("--------------")
return False
except Exception as e:
print(f"An unexpected error occurred while running {script_name}: {e}")
return False
# --- NUEVA FUNCIÓN PARA SELECCIONAR ARCHIVO ---
def select_xml_file():
"""Busca archivos .xml, los lista y pide al usuario que elija uno."""
print("No XML file specified. Searching for XML files in current directory...")
# Buscar archivos .xml en el directorio actual (.)
xml_files = sorted(glob.glob('*.xml')) # sorted para orden alfabético
if not xml_files:
print("Error: No .xml files found in the current directory.")
sys.exit(1)
print("\nAvailable XML files:")
for i, filename in enumerate(xml_files, start=1):
print(f" {i}: {filename}")
while True:
try:
choice = input(f"Enter the number of the file to process (1-{len(xml_files)}): ")
choice_num = int(choice)
if 1 <= choice_num <= len(xml_files):
selected_file = xml_files[choice_num - 1]
print(f"Selected: {selected_file}")
return selected_file
else:
print("Invalid choice. Please enter a number from the list.")
except ValueError:
print("Invalid input. Please enter a number.")
except EOFError: # Manejar si la entrada se cierra inesperadamente
print("\nSelection cancelled.")
sys.exit(1)
# --- FIN NUEVA FUNCIÓN ---
if __name__ == "__main__":
xml_filename = None
# Comprobar si se pasó un argumento de línea de comandos
# sys.argv[0] es el nombre del script, sys.argv[1] sería el primer argumento
if len(sys.argv) > 1:
# Si hay argumentos, usar argparse para parsearlo (permite -h, etc.)
parser = argparse.ArgumentParser(
description="Run the Simatic XML processing pipeline."
)
parser.add_argument(
"xml_file",
# Ya no necesitamos nargs='?' ni default aquí porque sabemos que hay un argumento
help="Path to the XML file to process.",
)
# Parsear solo los argumentos conocidos, ignorar extras si los hubiera
args, unknown = parser.parse_known_args()
xml_filename = args.xml_file
print(f"XML file specified via argument: {xml_filename}")
else:
# Si no hay argumentos, llamar a la función interactiva
xml_filename = select_xml_file()
# --- El resto del script continúa igual, usando xml_filename ---
# Verificar si el archivo XML de entrada (seleccionado o pasado) existe
if not os.path.exists(xml_filename):
print(f"Error: Selected or specified XML file not found: {xml_filename}")
sys.exit(1)
print(f"\nStarting pipeline for: {xml_filename}")
# Run scripts sequentially (asegúrate que los nombres son correctos)
script1 = "x1_to_json.py"
script2 = "x2_process.py"
script3 = "x3_generate_scl.py"
if run_script(script1, xml_filename):
if run_script(script2, xml_filename):
if run_script(script3, xml_filename):
print("\nPipeline completed successfully.")
else:
print("\nPipeline failed at script:", script3)
else:
print("\nPipeline failed at script:", script2)
else:
print("\nPipeline failed at script:", script1)