From 8762fe64ef437252389a2eaf6ac156fafe7fffbe Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 2 May 2025 21:33:47 +0200 Subject: [PATCH] Primer intento de cambio a un archivo fijo json para las llamadas a x1. Correccion de las dobles lineas en el log --- __pycache__/config_manager.cpython-310.pyc | Bin 14724 -> 15068 bytes .../__pycache__/script_utils.cpython-310.pyc | Bin 0 -> 1452 bytes backend/script_groups/CSharpCodeMerger/x1.py | 8 +- backend/script_groups/EmailCrono/x1.py | 8 +- backend/script_groups/ImportHTML/x1.py | 8 +- .../example_group/script_config.json | 15 +++ backend/script_groups/example_group/x1.py | 27 +++-- backend/script_groups/example_group/x2.py | 9 +- backend/script_utils.py | 43 ++++++++ config_manager.py | 22 +++- data/log.txt | 34 +++--- services/llm/openai_api_key.py | 2 +- static/js/scripts.js | 101 +++++++++++++----- utils/config_loader.py | 0 14 files changed, 213 insertions(+), 64 deletions(-) create mode 100644 backend/__pycache__/script_utils.cpython-310.pyc create mode 100644 backend/script_groups/example_group/script_config.json create mode 100644 backend/script_utils.py create mode 100644 utils/config_loader.py diff --git a/__pycache__/config_manager.cpython-310.pyc b/__pycache__/config_manager.cpython-310.pyc index 669b29276528b30519781280b59f48b0c4bad866..fe745998f7dcb997c67b40cc363eddfc54611de7 100644 GIT binary patch delta 1341 zcmZuwOKcle6n*!3Jf4il<4#j3qH#Ji zQK1hA6LwBD5Mj-b`tT6?ellcs|q~V*i;@4hND;wVw}Tpx2d@PcxkN~@O&kurg60n z?s@KWp5;E~-vA&?WdWva(>cOPt&Kw+sv6haSCBJ@9PNP9cEr({UI*mrEQoB%HOFeM z47swwB3xskZKc}QJkies%&f1`s$LoKf?Q`|7Gcp%-y6|t&@)OQ-o}G0#@boOrUGQ1 zu((1Lvf%?_Yp00&<|uZ;-wtxq`5o0UxLI51suSt=@=w^(T}xt1 zn1{E(336WxSsxGAdg|oRMzbD6YsX|CcJ;FKC5qf6>$ica&F(=S7U|)5#@vD{vj=aW zyES<=(o~p6g#jKpRK>oCcy%}hgAG1>9M&o^x8PXIUanBKFIY<_N^aS9Qux1d`Xn5a z@B+el$3uLnk~-JqtvLCDRkn+6dTAx^usqAV>7t#k^gr)7W#^!1vvRs6dqh8zUg<)e z7j3Ix<#Au!9!b$55WkH)Ee1xN%d(E!_f99)%GHO4b;Zz6W;=S z)9{~si$YzzJGKBj;^Ek1@IWNTUxr;#8lM^cNc#I2;S+ESnI|RmNcarlZ@}+g!9*oV z5WkF{R(IsqfH1QuwII`*VtV2f+!D(ZDfmKMpGc@b%bpqW>BNwx`&7{PBmTw@6aApp zCI5^lk9TF~Wcs0m=6OdhTFd`>=%Yyc9J!Tg@m)GDo;j(AFSAjxIvK|yP)+PkKGiK} z_`mM7_;d2f{+qZvq&nS_l#_5vLi6_u$ZS{K?PwQPHUXVtJ^O2Xrndk_o1zLfOkccx`j5-MX_<$=!S? z=p`e()Pou9me~&#*go`P4@Nx*K}0Vhy#)2rOJNa2B%Nz170qxy&N=t{zI*P>eKUN{ zu@YXdF5&aF@@}-hZ^k;K0LhLiiyLw+?3x&@7|sXa7dOU6ot?}@o0*H`oCT1Go2W#Y zlzSy6r8Nc_NU2P9dXTdRIofZIXO-h2dIpf|AqKK#rqY4s$`n-`h9ssE@1&B_Mh>F~ zMGuR~SEXyRa7ya2QG?_%cNB$Km?DTx@{-=9D`q8g(>BvGKzt;B%tZ>u)Re~~F;6Tn z?aN3ho$1a5^Q7}L5?M10bRuprolfC47)(zWWF)c4i3_M$lP*Ms!3_Ec*D**TGtxyF z>F~-d*nW)dA|XLRF)2PG)2E~)4#bVJ=gbgi-Y@myW-FN@B}-0!0V!pIG*X=OGxIE@ zyy)~Eo&3zZ;*AboZr84Z(rjIA74T=9Yl~$+4hIjmEup6fNY_N0FZ85+dggZdR)ues_r2_6Dd;+|wGA8RK9t?%hAQq~I zDLx+B(tJ~pssyM4d;-D(mMtELO!zFA&L1D|l`!1RmqIm)-(|b9^^N6#!|iLT2;5rL zt`7Cf>hF83V3!d$SJ+d+jxI9wu5@jro&_k^3vr*O5#O-lqRBH*9#r}@i* kd_EU01P^~5ersn0=dyqq0T227wktUY%JTe;oNPb!6H(3jApigX diff --git a/backend/__pycache__/script_utils.cpython-310.pyc b/backend/__pycache__/script_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..951067f5361530c57bfe6c9af3cce58fba1cf587 GIT binary patch literal 1452 zcma)6UuzRV5Z}GMT&~f^SpN&k5`1W&7TUf@P-)S=h*mKV#ZU;>+f92l**$hQriqCN z^;P@;B3R%2O8e@Q-#~m&XYZnsHiWs(^G5Fg?(%Cy1=2pxK3oN2)b zEV^on%p2kN=!18FF-p)TY9JGiFe8r8Tk@_v_RP%3(#Si+o5({f@R5%W2+lm0pwd3z z-17|HO|Un>Zf5pQ4O$qD!EbmLaum(!5ji-LCjbNs#^e=gO!htoPqT~H^-OUYTvJ>I6D1-MJ4cgg+E2_b?eG`8qv_HDU0$FoG!l&VrFstTtv~Ve z@ay|gH|=oR)6ouhlyag|`KIajOaft(ZYq_b9Vm5D(4^Enq$8Qvsp*}+c+J=T)ROUB zngjvo32bqPoB3*PtS-=(<70^Be<7CthFJL*V&xcO>Z*=&nlj~G0%*0G(;Lp6Z1V8> zy`!^`z+DSzXj}FKt5b{Bu+TH@o40D%hFrvwL6bIy)pez$qG_b`i5}B71gX>EwcN+G z;e=0}*2>nC+WKi^c5M;5E}|~C#b{e+Ct<7Q!n9h}-;;^30pCxw(YBDPL>TMKlnXGy zoLb*yuxB1L9&g;|K#*s7Ezw5Vnf3jcr*6z^ezP>GACfgIc`NfISw`Hpn14p<68tH? zud@2q6D0@k67^Oi`#AL0lSoC~N0ES0RKL%*qxd-&Y- 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 {} diff --git a/config_manager.py b/config_manager.py index aedcc56..4c4a301 100644 --- a/config_manager.py +++ b/config_manager.py @@ -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) diff --git a/data/log.txt b/data/log.txt index 2e9c8ea..b5a0582 100644 --- a/data/log.txt +++ b/data/log.txt @@ -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 diff --git a/services/llm/openai_api_key.py b/services/llm/openai_api_key.py index 39f5b3a..8f78127 100644 --- a/services/llm/openai_api_key.py +++ b/services/llm/openai_api_key.py @@ -1,3 +1,3 @@ # Configura tu clave API de OpenAI def openai_api_key(): - return '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' \ No newline at end of file + return '' \ No newline at end of file diff --git a/static/js/scripts.js b/static/js/scripts.js index 35c9499..01f5641 100644 --- a/static/js/scripts.js +++ b/static/js/scripts.js @@ -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 } } diff --git a/utils/config_loader.py b/utils/config_loader.py new file mode 100644 index 0000000..e69de29