Primer intento de cambio a un archivo fijo json para las llamadas a x1. Correccion de las dobles lineas en el log

This commit is contained in:
Miguel 2025-05-02 21:33:47 +02:00
parent c2c1c13729
commit 8762fe64ef
14 changed files with 213 additions and 64 deletions

Binary file not shown.

View File

@ -10,6 +10,11 @@ from pathlib import Path
from dataclasses import dataclass
from typing import List, Dict, Optional, Tuple
import difflib
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
# Forzar UTF-8 en la salida estándar
sys.stdout.reconfigure(encoding="utf-8")
@ -257,7 +262,8 @@ class CSharpCodeMerger:
return ''.join(diff)
def main():
configs = json.loads(os.environ.get("SCRIPT_CONFIGS", "{}"))
# configs = json.loads(os.environ.get("SCRIPT_CONFIGS", "{}"))
configs = load_configuration()
working_directory = configs.get("working_directory", ".")
work_config = configs.get("level3", {})

View File

@ -9,6 +9,11 @@ from utils.email_parser import procesar_eml
from utils.markdown_handler import cargar_cronologia_existente
from utils.beautify import BeautifyProcessor
import json
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
# Forzar UTF-8 en la salida estándar
sys.stdout.reconfigure(encoding="utf-8")
@ -29,7 +34,8 @@ def generar_indice(mensajes):
def main():
# Cargar configuraciones del entorno
configs = json.loads(os.environ.get("SCRIPT_CONFIGS", "{}"))
# configs = json.loads(os.environ.get("SCRIPT_CONFIGS", "{}"))
configs = load_configuration()
# Obtener working directory
working_directory = configs.get("working_directory", ".")

View File

@ -8,6 +8,11 @@ from pathlib import Path
import json
from utils.html_parser import procesar_html
from utils.markdown_handler import escribir_archivo_markdown
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
# Verificar si la biblioteca mammoth está disponible para procesamiento DOCX
try:
@ -31,7 +36,8 @@ ERROR_SYMBOL = "[ERROR]"
def main():
# Cargar configuraciones del entorno
configs = json.loads(os.environ.get("SCRIPT_CONFIGS", "{}"))
# configs = json.loads(os.environ.get("SCRIPT_CONFIGS", "{}"))
configs = load_configuration()
# Obtener working directory
working_directory = configs.get("working_directory", ".")

View File

@ -0,0 +1,15 @@
{
"level1": {
"api_key": "your-api-key-here",
"model": "gpt-3.5-turbo"
},
"level2": {
"input_dir": "D:/Datos/Entrada",
"output_dir": "D:/Datos/Salida",
"batch_size": 50
},
"level3": {
"in_dir": "ingesta"
},
"working_directory": "C:\\Estudio"
}

View File

@ -5,24 +5,35 @@ Este script demuestra cómo acceder a las configuraciones de los tres niveles.
import json
import os
import sys
import time
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
def main():
# Cargar configuraciones desde variable de entorno
configs = json.loads(os.environ.get('SCRIPT_CONFIGS', '{}'))
# configs = json.loads(os.environ.get('SCRIPT_CONFIGS', '{}'))
configs = load_configuration()
print("=== Ejecutando Script de Prueba 1 ===")
print("\nConfiguraciones cargadas:")
print("Nivel 1:", json.dumps(configs.get('level1', {}), indent=2))
print("Nivel 2:", json.dumps(configs.get('level2', {}), indent=2))
print("Nivel 3:", json.dumps(configs.get('level3', {}), indent=2))
print("Nivel 1:", json.dumps(configs.get("level1", {}), indent=2))
print("Nivel 2:", json.dumps(configs.get("level2", {}), indent=2))
print("Nivel 3:", json.dumps(configs.get("level3", {}), indent=2))
print("\nSimulando procesamiento...")
for i in range(5):
time.sleep(1)
print(f"Progreso: {(i+1)*20}%")
print("\n¡Proceso completado!")
if __name__ == '__main__':
if __name__ == "__main__":
main()

View File

@ -6,10 +6,17 @@ Demuestra el manejo de errores y logging.
import json
import os
import time
import sys
import random
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
def main():
configs = json.loads(os.environ.get('SCRIPT_CONFIGS', '{}'))
# configs = json.loads(os.environ.get('SCRIPT_CONFIGS', '{}'))
configs = load_configuration()
print("=== Ejecutando Script de Prueba 2 ===")
print("\nIniciando análisis de datos simulado...")

43
backend/script_utils.py Normal file
View File

@ -0,0 +1,43 @@
import os
import json
from typing import Dict, Any
def load_configuration() -> Dict[str, Any]:
"""
Load configuration from script_config.json in the current script directory.
Returns:
Dict containing configurations with levels 1, 2, 3 and working_directory
Example usage in scripts:
from script_utils import load_configuration
configs = load_configuration()
level1_config = configs.get("level1", {})
level2_config = configs.get("level2", {})
level3_config = configs.get("level3", {})
working_dir = configs.get("working_directory", "")
"""
try:
# Get directory of the calling script
script_dir = os.path.dirname(os.path.abspath(__file__))
# Path to the config file
config_file_path = os.path.join(script_dir, "script_config.json")
# Check if file exists
if not os.path.exists(config_file_path):
print(f"Configuration file not found: {config_file_path}")
return {}
# Load and parse the JSON file
with open(config_file_path, "r", encoding="utf-8") as f:
return json.load(f)
except json.JSONDecodeError as e:
print(f"Error parsing configuration file: {str(e)}")
return {}
except Exception as e:
print(f"Error loading configuration: {str(e)}")
return {}

View File

@ -379,6 +379,7 @@ class ConfigurationManager:
self.last_execution_time = current_time
script_path = os.path.join(self.script_groups_path, group, script_name)
script_dir = os.path.dirname(script_path)
if not os.path.exists(script_path):
if broadcast_fn:
@ -400,11 +401,22 @@ class ConfigurationManager:
"working_directory": working_dir,
}
# Save configurations to a JSON file in the script directory
config_file_path = os.path.join(script_dir, "script_config.json")
try:
with open(config_file_path, "w", encoding="utf-8") as f:
json.dump(configs, f, indent=2, ensure_ascii=False)
if broadcast_fn:
broadcast_fn(f"Configuraciones guardadas en {config_file_path}")
except Exception as e:
if broadcast_fn:
broadcast_fn(f"Error guardando configuraciones: {str(e)}")
try:
if broadcast_fn:
broadcast_fn(f"Iniciando ejecución de {script_name}")
# Execute script with configured environment
# Execute script with configured environment (removed SCRIPT_CONFIGS env var)
process = subprocess.Popen(
["python", script_path],
cwd=working_dir,
@ -414,7 +426,7 @@ class ConfigurationManager:
bufsize=1,
env=dict(
os.environ,
SCRIPT_CONFIGS=json.dumps(configs),
# SCRIPT_CONFIGS=json.dumps(configs), # Commented out as we now use a file
PYTHONIOENCODING="utf-8",
),
)
@ -468,7 +480,7 @@ class ConfigurationManager:
"""Set working directory path for a script group and update history."""
# Normalizar el path recibido
path = os.path.normpath(path)
if not os.path.exists(path):
return {"status": "error", "message": "Directory does not exist"}
@ -493,7 +505,9 @@ class ConfigurationManager:
data["history"] = []
# Eliminar la ruta del historial si ya existe (usando path normalizado)
data["history"] = [p for p in data["history"] if os.path.normpath(p) != path]
data["history"] = [
p for p in data["history"] if os.path.normpath(p) != path
]
# Agregar la ruta al principio del historial
data["history"].insert(0, path)

View File

@ -1,18 +1,16 @@
[13:09:20] Iniciando ejecución de x1.py
[13:09:21] Working directory: C:\Users\migue\Downloads\Nueva carpeta (7)
[13:09:21] Input directory: C:\Users\migue\Downloads\Nueva carpeta (7)
[13:09:21] Output directory: .
[13:09:21] Output file: .\contenidoImportado.md
[13:09:21] Attachments directory: .\adjuntos
[13:09:21] Found 0 HTML files
[13:09:21] Found 1 DOCX files
[13:09:21] Processing DOCX [1/1] C:\Users\migue\Downloads\Nueva carpeta (7)\TIA Portal Ethernet communication Rules V0.1.docx
[13:09:22] Error procesando DOCX C:\Users\migue\Downloads\Nueva carpeta (7)\TIA Portal Ethernet communication Rules V0.1.docx: convert_document_element_to_html() got an unexpected keyword argument 'options'
[13:09:22] [ERROR] Failed: Error al procesar: convert_document_element_to_html() got an unexpected keyword argument 'options'
[13:09:22] Summary:
[13:09:22] - Total files: 1
[13:09:22] - Successfully processed: 0
[13:09:22] - Failed: 1
[13:09:22] Writing 1 pages to .\contenidoImportado.md
[13:09:22] Markdown file created successfully.
[13:09:23] Ejecución completada
[21:32:28] Configuraciones guardadas en d:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\example_group\script_config.json
[21:32:28] Iniciando ejecución de x1.py
[21:32:33] Configuration file not found: d:\Proyectos\Scripts\ParamManagerScripts\backend\script_config.json
[21:32:33] === Ejecutando Script de Prueba 1 ===
[21:32:33] Configuraciones cargadas:
[21:32:33] Nivel 1: {}
[21:32:33] Nivel 2: {}
[21:32:33] Nivel 3: {}
[21:32:33] Simulando procesamiento...
[21:32:33] Progreso: 20%
[21:32:33] Progreso: 40%
[21:32:33] Progreso: 60%
[21:32:33] Progreso: 80%
[21:32:33] Progreso: 100%
[21:32:33] ¡Proceso completado!
[21:32:33] Ejecución completada

View File

@ -1,3 +1,3 @@
# Configura tu clave API de OpenAI
def openai_api_key():
return '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'
return ''

View File

@ -1,18 +1,43 @@
let socket;
let currentGroup;
// Initialize WebSocket connection
let socket = null; // Define socket en un alcance accesible (p.ej., globalmente o en el scope del módulo)
function initWebSocket() {
socket = new WebSocket(`ws://${location.host}/ws`);
socket.onmessage = function(event) {
addLogLine(event.data);
// Comprobar si ya existe un socket y está abierto o conectándose
if (socket && (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING)) {
console.log("WebSocket ya está abierto o conectándose.");
return; // No crear una nueva conexión
}
// Determinar URL del WebSocket (ws:// o wss://)
const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${wsProtocol}//${window.location.host}/ws`;
console.log("Inicializando conexión WebSocket a:", wsUrl);
socket = new WebSocket(wsUrl);
socket.onopen = () => {
console.log('Conexión WebSocket establecida');
};
socket.onclose = function() {
console.log('WebSocket cerrado, intentando reconexión...');
setTimeout(initWebSocket, 1000);
socket.onmessage = (event) => {
// console.log('Mensaje del servidor:', event.data); // Opcional: para depuración
addLogLine(event.data); // Llama a la función que ya tienes
};
socket.onerror = function(error) {
console.error('Error en WebSocket:', error);
socket.onerror = (error) => {
console.error('Error WebSocket:', error);
addLogLine('Error de conexión WebSocket.'); // Informar al usuario
};
socket.onclose = (event) => {
console.log('Conexión WebSocket cerrada:', event.code, event.reason);
// Opcional: intentar reconectar o informar al usuario
if (!event.wasClean) {
addLogLine('Conexión WebSocket perdida. Intente recargar la página.');
}
socket = null; // Restablecer la variable socket después de cerrar
};
}
@ -80,17 +105,37 @@ async function loadScripts(group) {
// Execute a script
async function executeScript(scriptName) {
addLogLine(`\nEjecutando script: ${scriptName}...\n`);
// REMOVE this line - let the backend log the start via WebSocket
// addLogLine(`\nEjecutando script: ${scriptName}...\n`);
const response = await fetch('/api/execute_script', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ group: currentGroup, script: scriptName })
});
try {
const response = await fetch('/api/execute_script', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ group: currentGroup, script: scriptName })
});
const result = await response.json();
if (result.error) {
addLogLine(`\nError: ${result.error}\n`);
// Check for HTTP errors during the *request* itself
if (!response.ok) {
const errorText = await response.text();
console.error(`Error initiating script execution request: ${response.status} ${response.statusText}`, errorText);
// Log only the request error, not script execution errors which come via WebSocket
addLogLine(`\nError al iniciar la petición del script: ${response.status} ${errorText}\n`);
return; // Stop if the request failed
}
// REMOVE logging the result/error here - let the backend log via WebSocket
// const result = await response.json(); // Still potentially need to read body if not done elsewhere
// if (result.error) {
// addLogLine(`\nError: ${result.error}\n`);
// }
// Script output and final status/errors will arrive via WebSocket messages
// handled by socket.onmessage -> addLogLine
} catch (error) {
console.error('Error in executeScript fetch:', error);
addLogLine(`\nError de red o JavaScript al intentar ejecutar el script: ${error.message}\n`);
}
}
@ -755,17 +800,15 @@ function getTimestamp() {
// Función para agregar línea al log con timestamp
function addLogLine(message) {
const logArea = document.getElementById('log-area');
const timestamp = getTimestamp();
// Filtrar líneas vacías y aplicar timestamp solo a líneas con contenido
const lines = message.split('\n')
.filter(line => line.trim()) // Eliminar líneas vacías
.map(line => `[${timestamp}] ${line}`)
.join('\n');
if (lines) {
logArea.innerHTML += lines + '\n';
logArea.scrollTop = logArea.scrollHeight;
// Message from WebSocket should already have timestamp.
// Trim any extra whitespace just in case.
const cleanMessage = String(message).trim();
if (cleanMessage) {
// Append the cleaned message + a newline for display separation.
logArea.innerHTML += cleanMessage + '\n';
logArea.scrollTop = logArea.scrollHeight; // Ensure scroll to bottom
}
}

0
utils/config_loader.py Normal file
View File