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 dataclasses import dataclass
from typing import List, Dict, Optional, Tuple from typing import List, Dict, Optional, Tuple
import difflib 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 # Forzar UTF-8 en la salida estándar
sys.stdout.reconfigure(encoding="utf-8") sys.stdout.reconfigure(encoding="utf-8")
@ -257,7 +262,8 @@ class CSharpCodeMerger:
return ''.join(diff) return ''.join(diff)
def main(): 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", ".") working_directory = configs.get("working_directory", ".")
work_config = configs.get("level3", {}) 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.markdown_handler import cargar_cronologia_existente
from utils.beautify import BeautifyProcessor from utils.beautify import BeautifyProcessor
import json 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 # Forzar UTF-8 en la salida estándar
sys.stdout.reconfigure(encoding="utf-8") sys.stdout.reconfigure(encoding="utf-8")
@ -29,7 +34,8 @@ def generar_indice(mensajes):
def main(): def main():
# Cargar configuraciones del entorno # 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 # Obtener working directory
working_directory = configs.get("working_directory", ".") working_directory = configs.get("working_directory", ".")

View File

@ -8,6 +8,11 @@ from pathlib import Path
import json import json
from utils.html_parser import procesar_html from utils.html_parser import procesar_html
from utils.markdown_handler import escribir_archivo_markdown 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 # Verificar si la biblioteca mammoth está disponible para procesamiento DOCX
try: try:
@ -31,7 +36,8 @@ ERROR_SYMBOL = "[ERROR]"
def main(): def main():
# Cargar configuraciones del entorno # 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 # Obtener working directory
working_directory = configs.get("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,17 +5,27 @@ Este script demuestra cómo acceder a las configuraciones de los tres niveles.
import json import json
import os import os
import sys
import time 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(): def main():
# Cargar configuraciones desde variable de entorno # 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("=== Ejecutando Script de Prueba 1 ===")
print("\nConfiguraciones cargadas:") print("\nConfiguraciones cargadas:")
print("Nivel 1:", json.dumps(configs.get('level1', {}), indent=2)) print("Nivel 1:", json.dumps(configs.get("level1", {}), indent=2))
print("Nivel 2:", json.dumps(configs.get('level2', {}), indent=2)) print("Nivel 2:", json.dumps(configs.get("level2", {}), indent=2))
print("Nivel 3:", json.dumps(configs.get('level3', {}), indent=2)) print("Nivel 3:", json.dumps(configs.get("level3", {}), indent=2))
print("\nSimulando procesamiento...") print("\nSimulando procesamiento...")
for i in range(5): for i in range(5):
@ -24,5 +34,6 @@ def main():
print("\n¡Proceso completado!") print("\n¡Proceso completado!")
if __name__ == '__main__':
if __name__ == "__main__":
main() main()

View File

@ -6,10 +6,17 @@ Demuestra el manejo de errores y logging.
import json import json
import os import os
import time import time
import sys
import random 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(): 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("=== Ejecutando Script de Prueba 2 ===")
print("\nIniciando análisis de datos simulado...") 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 self.last_execution_time = current_time
script_path = os.path.join(self.script_groups_path, group, script_name) 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 not os.path.exists(script_path):
if broadcast_fn: if broadcast_fn:
@ -400,11 +401,22 @@ class ConfigurationManager:
"working_directory": working_dir, "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: try:
if broadcast_fn: if broadcast_fn:
broadcast_fn(f"Iniciando ejecución de {script_name}") 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( process = subprocess.Popen(
["python", script_path], ["python", script_path],
cwd=working_dir, cwd=working_dir,
@ -414,7 +426,7 @@ class ConfigurationManager:
bufsize=1, bufsize=1,
env=dict( env=dict(
os.environ, os.environ,
SCRIPT_CONFIGS=json.dumps(configs), # SCRIPT_CONFIGS=json.dumps(configs), # Commented out as we now use a file
PYTHONIOENCODING="utf-8", PYTHONIOENCODING="utf-8",
), ),
) )
@ -493,7 +505,9 @@ class ConfigurationManager:
data["history"] = [] data["history"] = []
# Eliminar la ruta del historial si ya existe (usando path normalizado) # 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 # Agregar la ruta al principio del historial
data["history"].insert(0, path) data["history"].insert(0, path)

View File

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

View File

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

View File

@ -1,18 +1,43 @@
let socket;
let currentGroup; let currentGroup;
// Initialize WebSocket connection // Initialize WebSocket connection
let socket = null; // Define socket en un alcance accesible (p.ej., globalmente o en el scope del módulo)
function initWebSocket() { function initWebSocket() {
socket = new WebSocket(`ws://${location.host}/ws`); // Comprobar si ya existe un socket y está abierto o conectándose
socket.onmessage = function(event) { if (socket && (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING)) {
addLogLine(event.data); 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...'); socket.onmessage = (event) => {
setTimeout(initWebSocket, 1000); // 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 // Execute a script
async function executeScript(scriptName) { 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`);
try {
const response = await fetch('/api/execute_script', { const response = await fetch('/api/execute_script', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ group: currentGroup, script: scriptName }) body: JSON.stringify({ group: currentGroup, script: scriptName })
}); });
const result = await response.json(); // Check for HTTP errors during the *request* itself
if (result.error) { if (!response.ok) {
addLogLine(`\nError: ${result.error}\n`); 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 // Función para agregar línea al log con timestamp
function addLogLine(message) { function addLogLine(message) {
const logArea = document.getElementById('log-area'); const logArea = document.getElementById('log-area');
const timestamp = getTimestamp();
// Filtrar líneas vacías y aplicar timestamp solo a líneas con contenido // Message from WebSocket should already have timestamp.
const lines = message.split('\n') // Trim any extra whitespace just in case.
.filter(line => line.trim()) // Eliminar líneas vacías const cleanMessage = String(message).trim();
.map(line => `[${timestamp}] ${line}`)
.join('\n');
if (lines) { if (cleanMessage) {
logArea.innerHTML += lines + '\n'; // Append the cleaned message + a newline for display separation.
logArea.scrollTop = logArea.scrollHeight; logArea.innerHTML += cleanMessage + '\n';
logArea.scrollTop = logArea.scrollHeight; // Ensure scroll to bottom
} }
} }

0
utils/config_loader.py Normal file
View File