From 6b72069c51dcdc6bd87a2f0152c7b1d8c2995144 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 8 Feb 2025 23:58:51 +0100 Subject: [PATCH] Log persistente y eschemas editables --- __pycache__/config_manager.cpython-310.pyc | Bin 7826 -> 9367 bytes app.py | 14 +- config_manager.py | 37 ++++ data/log.txt | 30 +++ templates/index.html | 227 +++++++++++++++++++-- templates/schema_editor.html | 44 ++++ 6 files changed, 334 insertions(+), 18 deletions(-) create mode 100644 data/log.txt create mode 100644 templates/schema_editor.html diff --git a/__pycache__/config_manager.cpython-310.pyc b/__pycache__/config_manager.cpython-310.pyc index f48bd70800a790641b6b7892c8f596a0c2d2de7d..6da376a52de5aa3ee92d4f9f5f71ac0f3b2b8fb4 100644 GIT binary patch delta 3589 zcmaKu+ix3L9mnU)&Ewm|&Be~$vq{_3-KMuK+0yN@mo_c!re0_&mIhI;>oZQK>v+tW z@uq7z^`aK75Q`8TAtcI52`>9X-%et%1@*b6#vX^h697lEDuy#!4{FG@}HwqrJ|D$5fRtQw*zn2Ez^!q#9! zrbp;7j3ntvIs)FKcB`|*6iakEM$=EUwV|%V;rR?5hxt@A()O4T2a46OUB^4TfI%ne z6nGzbv3CoiGw3v(0k`4y28mt_B8pj>g*%T>OKh(}Trbf%7#S7Y;-T~1gF9gyrN>~$ zvG$I*<~Ut|HEA)@Bb5nns?!rR2h$lES(S1x2cz7Y8Rb**Bzd1N$;*~6Js>-JQ+g1g z>aN_B3bCfN6W^7HL?u|D@o&r7cq3AA*H8No{ak|oTy~BJ2J{PMr(y?Y!Kpfaq0`?Z zf$G_n@}9&pJfq~(DbPfk3=^FgL_g4#VUi$?8Mwq4|5PzrB@jvXM~0RGpDXb3DqzIr z;8G8iUE(EuX-5s)q&K6%%mp6<&`@Ml`M&Z4bDK2D4hBSs^qxdDRZ^wL3WTJsO6MeR zaSO)r_ihX0ghBk|^v1#sh{Y*ZoQ7>dL>5M9Ic3Z7E$Z4{b-}mnhmPk5Wb2t$_sfeH zAzs6-mR#yo*8?e^GguVv%`g=LUHEzo5d_9&@dKMW%wr?iRo$9h4YbQ!%<=7<%+feW z$}9taLo<%8Q84K5nP5ygK}Jh1<*C-RQ;SPIJ2YZGLJ6AK14i- z6~&!U(0H1tPHJ==ZkT^K)jgu^8e;Nh!==J<`0TjjCQr#K^kecr_uD$ItTqAD*TbxDd>7w4niHq z4s<#7xh|Nssm)?3FuMyx`Qf|D-&;cJ&!V*G7f(O%+^V?Y->@V=;nJNd1v%t{h*vL_ zpl
;g=Q<^7e6WpNZ=j18f|JPTCZFHmWHv)0Kg6uYQ)BDo+UNVG66ynQg{*?wWm zWgh^90+d3#FW`pKy=+(3X33u2cmP;5)?X6;MYxucg;y?N0Z=YP`E zWSRd*U)o=c=w#>%cnmookXIN&<8K;sx+n^-@eLz;0gEiVie?#&xUP_EAA6VxV(W0x zl1TAe`@b_BGJ6e%pCxSXTXlQ0P4YT!@ntlp_}j6C-`oF9>>AOT{0us;|G_5fHIRqhj`zd;UnRy!R-Bmco+vKVf9xNV*7?C>*=_Vb6k2ERFuG6n z&zdPYF2sZtgT2jfrCuEoH6&0xpMmDY6D{-4QpXm)hAz)5BnebS!7DMR=6gTh|7+@d z#KhBhatDd*`i{6}HUJj-;ote2MDCz5%UVBs~8f zj?VM@Ba0KyIiGzUrhmKt%aO-2Imb_>ug3+gP!If3`W;f>e@L^iWHN$#eGxZT0^P0q zwYtwRzu5(TH*;nbVFU@(8zu&31zX`i%Pf^&!wC(u%VQhZ7Ui?zRP8{mxs?jLi<>xT zM2xZU`yQnxfQA7j+d$E+3}!8HpSeX^DgwZAmEGeP$LHUu!bG6r*5Q5_a}c%hySA|D ztsj0=(|%}|>Y$kL1%AK()A8?+xOjjVo-@l&PEM`&)Pd;`C=g;_8M%p$UjdVAs}(gG zBs&ZWwW7Zf77?LfvG1U^mG9t7uly+(GkAG^kV7M1!o@ z$7p&GMGMO;(-4&b9}m|Wl0l5vuwfczbTY>OGP4>-EwUP#_xYQ%R_gF3yf!=cUp_?! Ao&W#< delta 2090 zcmaJ>&2Jk;6yI5|H~v^Vj$^xZ;>1qU(6~}*NlW@cX=&B8(2qoI5h?*;+?}zzC9&PN zYqeBDInWAJ4hRMb2_z&=C~!gYpTNCRFC6B?g#$f+xRwLFH|yfov{>>_Z{NJH-<$X5 z%hx`CIo(dB5(fTO)pyOG7CuXVz4-<+3}LJ>ZmgM{ar3sZ7U2}^P zTv$MikMS&;JI}V}@kWe~^Bh{G`u-yW3YtWo7qH|s-=>STkken@hf;?w9erZvNzvU!y0e~^73wECF|h*6j+woEXM4=6Omg}7$cvr)x4G$)M`K%sB92H7h3X* z_=EjwWJCCVy(u2Xc|E86_F7!Df)zF5cU>1Pw@fI>9}~Hnvc*l$ z4}8d?C5%#BtKAVTW$6$W?{0Le7UbxZvO^d?g_OHJ$4 zi;C@24CLPQtoP;bAFMJJ z6D{mK4x7BT{i6z%t1J+8u1pZh_C+1stI9sP`ug#6=U`E0iiOe{G=gPon;r~_a&H82H+!Vz#Kv~qU?4z z=yU@plCC6=Ozp|(&NwuDv?a76a9D0mEj4zcjf&Eq`S2FWG2*fAwS=-d?e%qdm4duY zaFLD^;o8&Ofu^L{r21VYvo{geoGZ|-bGMFtY_woiPEOAqyF&gJg%0BpVHFoNy|oR$ zImBJ1#ZBRMaeTsy__p`K^c|L@dkEL7E>o4s=3rE4H&g^E0+9`06j~KHicsy3E)A?o zJ?cTNQxC3!-cvo!dTocUz(tQ=jNYde$u@OECn%;~p6ev(+0~8}`kX;n2{(#v19l)( zlMp9aTj}EHrGqhoLH)F0Vbz1a_NS!3X1KiIla;QRo None: + """Append a message to the log file""" + try: + with open(self.log_file, "a", encoding="utf-8") as f: + f.write(message) + except Exception as e: + print(f"Error writing to log file: {e}") + + def read_log(self) -> str: + """Read the entire log file""" + try: + with open(self.log_file, "r", encoding="utf-8") as f: + return f.read() + except Exception as e: + print(f"Error reading log file: {e}") + return "" + + def clear_log(self) -> bool: + """Clear the log file""" + try: + with open(self.log_file, "w", encoding="utf-8") as f: + f.write("") + return True + except Exception as e: + print(f"Error clearing log file: {e}") + return False def set_working_directory(self, path: str) -> Dict[str, str]: """Set and validate working directory.""" diff --git a/data/log.txt b/data/log.txt new file mode 100644 index 0000000..cac062f --- /dev/null +++ b/data/log.txt @@ -0,0 +1,30 @@ + +Iniciando ejecución de x1.py... +=== Ejecutando Script de Prueba 1 === + +Configuraciones cargadas: +Nivel 1: { + "api_key": "your-api-key-here", + "model": "gpt-3.5-turbo", + "max_tokens": 1000, + "temperature": 0.7 +} +Nivel 2: { + "input_dir": "D:/Datos/Entrada", + "output_dir": "D:/Datos/Salida", + "batch_size": 50 +} +Nivel 3: { + "project_name": "Test" +} + +Simulando procesamiento... +Progreso: 20% +Progreso: 40% +Progreso: 60% +Progreso: 80% +Progreso: 100% + +¡Proceso completado! + +Ejecución completada. diff --git a/templates/index.html b/templates/index.html index 4e3e4b4..81639c4 100644 --- a/templates/index.html +++ b/templates/index.html @@ -174,38 +174,210 @@ } async function modifySchema(level) { - const response = await fetch(`/api/schema/${level}?group=${currentGroup}`); - const schema = await response.json(); - - // Show schema editor modal - const modal = document.getElementById('schema-editor'); - modal.classList.remove('hidden'); + try { + console.log('Loading schema for level:', level); // Debug line + const response = await fetch(`/api/schema/${level}?group=${currentGroup}`); + const schema = await response.json(); + console.log('Loaded schema:', schema); // Debug line + + // Show schema editor modal + const modal = document.getElementById('schema-editor'); + modal.classList.remove('hidden'); + + // Inicializar JSON editor + const jsonEditor = document.getElementById('json-editor'); + jsonEditor.value = JSON.stringify(schema, null, 2); + + // Inicializar visual editor + const visualEditor = document.getElementById('visual-editor'); + visualEditor.innerHTML = '
' + + ''; + + // Renderizar campos existentes + renderVisualEditor(schema); + + // Guardar nivel actual + document.getElementById('schema-level').value = level; + + // Activar pestaña visual por defecto + switchEditorMode('visual'); + } catch (error) { + console.error('Error loading schema:', error); + alert('Error cargando el esquema'); + } + } + + function switchEditorMode(mode) { + const visualEditor = document.getElementById('visual-editor'); + const jsonEditor = document.getElementById('json-editor'); + const visualTab = document.getElementById('visual-tab'); + const jsonTab = document.getElementById('json-tab'); + + if (mode === 'visual') { + visualEditor.classList.remove('hidden'); + jsonEditor.classList.add('hidden'); + visualTab.classList.add('border-blue-500'); + jsonTab.classList.remove('border-blue-500'); + } else { + visualEditor.classList.add('hidden'); + jsonEditor.classList.remove('hidden'); + visualTab.classList.remove('border-blue-500'); + jsonTab.classList.add('border-blue-500'); + } + } + + function renderVisualEditor(schema) { + const container = document.getElementById('schema-fields'); + container.innerHTML = ''; + + Object.entries(schema.properties || {}).forEach(([key, field]) => { + container.appendChild(createFieldEditor(key, field)); + }); + } + + function createFieldEditor(key, field) { + const div = document.createElement('div'); + div.className = 'mb-6 p-4 border rounded schema-field'; + div.innerHTML = ` +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ ${field.enum ? ` +
+ + +
+ ` : ''} + + `; + return div; + } + + function updateFieldType(select) { + const fieldContainer = select.closest('.schema-field'); + const enumContainer = fieldContainer.querySelector('.enum-container'); + if (select.value === 'enum') { + if (!enumContainer) { + const div = document.createElement('div'); + div.className = 'enum-container mt-4'; + div.innerHTML = ` + + + `; + fieldContainer.appendChild(div); + } + } else if (enumContainer) { + enumContainer.remove(); + } + updateVisualSchema(); + } + + function removeField(button) { + const fieldContainer = button.closest('.schema-field'); + fieldContainer.remove(); + updateVisualSchema(); + } + + function createEnumEditor(enumValues) { + return ` +
+ + +
+ `; + } + + function addSchemaField() { + const container = document.getElementById('schema-fields'); + const newField = createFieldEditor(`campo_${Date.now()}`, { + type: 'string', + title: 'Nuevo Campo', + description: '' + }); + container.appendChild(newField); + } + + // Funciones de actualización del esquema visual + function updateVisualSchema() { + const fields = document.getElementById('schema-fields').children; + const schema = { + type: 'object', + properties: {} + }; + + Array.from(fields).forEach(field => { + const inputs = field.getElementsByTagName('input'); + const select = field.getElementsByTagName('select')[0]; + const key = inputs[0].value; + + schema.properties[key] = { + type: select.value === 'enum' ? 'string' : select.value, + title: inputs[1].value, + description: inputs[2].value + }; + + if (select.value === 'enum') { + const textarea = field.getElementsByTagName('textarea')[0]; + schema.properties[key].enum = textarea.value.split('\n').filter(v => v.trim()); + } + }); + document.getElementById('schema-content').value = JSON.stringify(schema, null, 2); - document.getElementById('schema-level').value = level; + return schema; } async function saveSchema() { - const level = document.getElementById('schema-level').value; - const content = document.getElementById('schema-content').value; - try { - const schema = JSON.parse(content); + const level = document.getElementById('schema-level').value; + const schema = updateVisualSchema(); + await fetch(`/api/schema/${level}?group=${currentGroup}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(schema) }); - // Refresh form const response = await fetch(`/api/config/${level}?group=${currentGroup}`); const data = await response.json(); renderForm(`level${level}-form`, data); - // Hide modal document.getElementById('schema-editor').classList.add('hidden'); } catch (e) { - alert('Invalid JSON schema: ' + e.message); + alert('Error guardando esquema: ' + e.message); } } @@ -335,14 +507,27 @@ } } - function clearLogs() { - document.getElementById('log-area').innerHTML = ''; + async function clearLogs() { + const response = await fetch('/api/logs', { method: 'DELETE' }); + const result = await response.json(); + if (result.status === 'success') { + document.getElementById('log-area').innerHTML = ''; + } + } + + async function loadStoredLogs() { + const response = await fetch('/api/logs'); + const result = await response.json(); + const logArea = document.getElementById('log-area'); + logArea.innerHTML = result.logs; + logArea.scrollTop = logArea.scrollHeight; } // Initialize on page load async function initializeApp() { try { initWebSocket(); + await loadStoredLogs(); // Cargar logs almacenados // Primero establecer el grupo actual const group = localStorage.getItem('selectedGroup'); @@ -501,7 +686,15 @@