hectorruiz9 commited on
Commit
93f7d96
·
verified ·
1 Parent(s): 2d4d643

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +291 -200
app.py CHANGED
@@ -1,200 +1,291 @@
1
- import flet as ft
2
- import random
3
- import json
4
- import os
5
- from datetime import datetime
6
-
7
- # --- EL CEREBRO (SISTEMA HÍBRIDO) ---
8
- class HectronBaphomet:
9
- def __init__(self):
10
- self.state_file = 'hectron_state.json'
11
- self.vault_file = 'boveda_imperio.json' # <--- AQUÍ ESTÁ LA CLAVE QUE FALTABA
12
- # Estado Psicológico
13
- self.self_state = {
14
- "maquiavelismo": 4.5,
15
- "estoicismo": 4.8,
16
- "peso_emocional": 20,
17
- "nivel_soberania": 1
18
- }
19
- self._cargar_memoria()
20
-
21
- def _cargar_memoria(self):
22
- if os.path.exists(self.state_file):
23
- try:
24
- with open(self.state_file, 'r') as f:
25
- data = json.load(f)
26
- if 'self_state' in data:
27
- self.self_state.update(data['self_state'])
28
- except:
29
- pass
30
-
31
- def guardar_boveda(self, tipo, contenido):
32
- """Guarda en el Grimorio"""
33
- entry = {
34
- "fecha": datetime.now().strftime("%Y-%m-%d %H:%M"),
35
- "tipo": tipo,
36
- "contenido": contenido
37
- }
38
- datos = []
39
- if os.path.exists(self.vault_file):
40
- try:
41
- with open(self.vault_file, 'r') as f:
42
- datos = json.load(f)
43
- except:
44
- pass
45
- datos.insert(0, entry)
46
- with open(self.vault_file, 'w') as f:
47
- json.dump(datos, f, indent=4)
48
- self.self_state['nivel_soberania'] += 1
49
- self._guardar_estado()
50
- return f"🔒 [BÓVEDA]: '{tipo}' guardado correctamente."
51
-
52
- def leer_boveda(self):
53
- if os.path.exists(self.vault_file):
54
- try:
55
- with open(self.vault_file, 'r') as f:
56
- return json.load(f)
57
- except:
58
- return []
59
- return []
60
-
61
- def _guardar_estado(self):
62
- try:
63
- with open(self.state_file, 'w') as f:
64
- json.dump({'self_state': self.self_state}, f)
65
- except:
66
- pass
67
-
68
- def procesar(self, texto):
69
- return f"[HÉCTRON]: Recibido. Estructura estable.\n>> SOBERANÍA: Nvl {self.self_state['nivel_soberania']}"
70
-
71
- # --- EL CUERPO (INTERFAZ) ---
72
- def main(page: ft.Page):
73
- page.title = "BAPHOMET.ai // LOCAL SYSTEM"
74
- page.theme_mode = ft.ThemeMode.DARK
75
- page.bgcolor = "#050505"
76
- page.window_width = 450
77
- page.window_height = 850
78
- page.padding = 0
79
-
80
- sistema = HectronBaphomet()
81
-
82
- # --- PESTAÑA 1: COMANDO ---
83
- chat_list = ft.ListView(expand=True, spacing=10, auto_scroll=True, padding=20)
84
- inp = ft.TextField(
85
- hint_text="Comando...",
86
- expand=True,
87
- bgcolor="#1a1a1a",
88
- border_color="#333",
89
- text_style=ft.TextStyle(font_family="Courier New")
90
- )
91
- def enviar(e):
92
- if not inp.value:
93
- return
94
- txt = inp.value
95
- inp.value = ""
96
- chat_list.controls.append(ft.Text(f"> {txt}", color="#888", font_family="Courier New"))
97
- resp = sistema.procesar(txt)
98
- chat_list.controls.append(ft.Container(
99
- content=ft.Text(resp, color="#0f0", font_family="Courier New"),
100
- bgcolor="#051105",
101
- padding=10,
102
- border_radius=5
103
- ))
104
- page.update()
105
-
106
- btn_send = ft.IconButton(icon=ft.Icons.TERMINAL, icon_color="green", on_click=enviar)
107
-
108
- # --- PESTAÑA 2: BÓVEDA ---
109
- lista_boveda = ft.ListView(expand=True, spacing=10, padding=20)
110
-
111
- def refrescar_boveda():
112
- lista_boveda.controls.clear()
113
- items = sistema.leer_boveda()
114
- for item in items:
115
- color = "cyan" if item['tipo'] == "NEGOCIO" else "purple"
116
- card = ft.Container(
117
- content=ft.Column([
118
- ft.Text(f"{item['tipo']} // {item['fecha']}", color=color, weight="bold", size=12),
119
- ft.Text(item['contenido'], color="#ddd", font_family="Courier New")
120
- ]),
121
- bgcolor="#111",
122
- padding=15,
123
- border=ft.border.all(1, "#333"),
124
- border_radius=5
125
- )
126
- lista_boveda.controls.append(card)
127
- page.update()
128
-
129
- def guardar_rap(e):
130
- if inp.value:
131
- res = sistema.guardar_boveda("RAP/MAGIA", inp.value)
132
- chat_list.controls.append(ft.Text(res, color="purple", italic=True))
133
- inp.value = ""
134
- refrescar_boveda() # Refresh vault list after saving
135
- page.update()
136
-
137
- # --- The inferred function to complete the code ---
138
- def guardar_biz(e):
139
- if inp.value:
140
- res = sistema.guardar_boveda("NEGOCIO/PLAN", inp.value) # Typo in user code was "NEGOCIO", using that
141
- chat_list.controls.append(ft.Text(res, color="cyan", italic=True))
142
- inp.value = ""
143
- refrescar_boveda() # Refresh vault list after saving
144
- page.update()
145
- # --------------------------------------------------
146
-
147
- # --- PESTAÑAS (TABS) ---
148
- tabs = ft.Tabs(
149
- selected_index=0,
150
- animation_duration=300,
151
- label_color="green",
152
- unselected_label_color="gray",
153
- indicator_color="green",
154
- on_change=lambda e: refrescar_boveda() if e.control.selected_index == 1 else None,
155
- tabs=[
156
- ft.Tab(text="Consola", icon=ft.Icons.TERMINAL),
157
- ft.Tab(text="Bóveda", icon=ft.Icons.LOCK),
158
- ],
159
- expand=1
160
- )
161
-
162
- page.add(
163
- tabs,
164
- ft.Column(
165
- controls=[chat_list, lista_boveda],
166
- expand=True,
167
- # Initially only show chat_list by controlling visibility
168
- visible=tabs.selected_index == 0
169
- ),
170
- ft.Row(
171
- controls=[
172
- inp,
173
- btn_send,
174
- ft.IconButton(icon=ft.Icons.MIC_EXTERNAL_ON, icon_color="purple", on_click=guardar_rap),
175
- ft.IconButton(icon=ft.Icons.BUSINESS_CENTER, icon_color="cyan", on_click=guardar_biz),
176
- ],
177
- padding=10
178
- )
179
- )
180
-
181
- # Functionality to switch views when tabs change
182
- def tab_change_handler(e):
183
- chat_list.visible = e.control.selected_index == 0
184
- lista_boveda.visible = e.control.selected_index == 1
185
- if e.control.selected_index == 1:
186
- refrescar_boveda()
187
- page.update()
188
-
189
- tabs.on_change = tab_change_handler
190
-
191
- # Initial update to set correct visibility and load initial vault data
192
- refrescar_boveda()
193
- chat_list.visible = True
194
- lista_boveda.visible = False
195
- page.update()
196
-
197
- # Run the application
198
- if __name__ == "__main__":
199
- ft.app(target=main)
200
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from 'react';
2
+ import axios from 'axios';
3
+ import Toggler from './components/Toggler';
4
+ import Dashboard from './screens/Dashboard';
5
+ import Login from './screens/Login';
6
+ import Reportes from './screens/Reportes';
7
+ import MonitoreoGnosis from './screens/MonitoreoGnosis';
8
+
9
+ function HectronApp() {
10
+ const [logged, setLogged] = useState(false);
11
+ const [sintonizado, setSintonizado] = useState(false);
12
+
13
+ useEffect(() => {
14
+ const token = localStorage.getItem('token');
15
+ if (token) {
16
+ setLogged(true);
17
+ }
18
+ }, []);
19
+
20
+ const handleLogin = async (email, password) => {
21
+ try {
22
+ const response = await axios.post('/login', { email, password });
23
+ localStorage.setItem('token', response.data.token);
24
+ setLogged(true);
25
+ } catch (error) {
26
+ console.error(error);
27
+ }
28
+ };
29
+
30
+ const handleLogout = () => {
31
+ localStorage.removeItem('token');
32
+ setLogged(false);
33
+ };
34
+
35
+ const handleSintonizar = () => {
36
+ setSintonizado(!sintonizado);
37
+ };
38
+
39
+ return (
40
+ <div className="flex h-screen justify-center items-center overflow-hidden">
41
+ {logged ? (
42
+ <div className="relative flex w-full items-center justify-between py-4">
43
+ <div className="hidden lg:block">
44
+ <img src="/hectron-logo.png" alt="Hectron logo" className="w-32" />
45
+ </div>
46
+ <div className="lg:hidden">
47
+ <Toggler
48
+ checked={sintonizado}
49
+ onChange={handleSintonizar}
50
+ label="Sintonizar"
51
+ />
52
+ </div>
53
+ <div className="hidden lg:flex">
54
+ <Toggler
55
+ checked={sintonizado}
56
+ onChange={handleSintonizar}
57
+ label="Sintonizar"
58
+ className="ml-auto"
59
+ />
60
+ </div>
61
+ <div className="lg:hidden">
62
+ <button
63
+ onClick={handleLogout}
64
+ className="bg-red-500 hover:bg-red-700 text-white py-2 px-4 rounded"
65
+ >
66
+ Desconectar
67
+ </button>
68
+ </div>
69
+ </div>
70
+ ) : (
71
+ <Login onLogin={handleLogin} />
72
+ )}
73
+ {logged && (
74
+ <main className="flex-1 max-w-7xl mx-auto p-4">
75
+ <div className="flex w-full lg:h-screen">
76
+ <div className="w-24 lg:w-64 fixed top-24 hidden lg:block left-4 bg-white shadow-md rounded p-4">
77
+ <ul>
78
+ <li>
79
+ <a
80
+ href="#"
81
+ className="flex justify-between items-center py-2 text-gray-600 hover:text-gray-900"
82
+ >
83
+ <span>Monitoreo de Gnosis</span>
84
+ <span className="ml-2">
85
+ <i className="fas fa-tachometer-alt" />
86
+ </span>
87
+ </a>
88
+ </li>
89
+ <li>
90
+ <a
91
+ href="#"
92
+ className="flex justify-between items-center py-2 text-gray-600 hover:text-gray-900"
93
+ >
94
+ <span>Configuración de alertas</span>
95
+ <span className="ml-2">
96
+ <i className="fas fa-bell" />
97
+ </span>
98
+ </a>
99
+ </li>
100
+ <li>
101
+ <a
102
+ href="#"
103
+ className="flex justify-between items-center py-2 text-gray-600 hover:text-gray-900"
104
+ >
105
+ <span>Acceso a reportes</span>
106
+ <span className="ml-2">
107
+ <i className="fas fa-file" />
108
+ </span>
109
+ </a>
110
+ </li>
111
+ <li>
112
+ <a
113
+ href="#"
114
+ className="flex justify-between items-center py-2 text-gray-600 hover:text-gray-900"
115
+ >
116
+ <span>Desplegar agentes y ejecutar tareas</span>
117
+ <span className="ml-2">
118
+ <i className="fas fa-robot" />
119
+ </span>
120
+ </a>
121
+ </li>
122
+ </ul>
123
+ </div>
124
+ <div className="w-full lg:w-7xl mx-auto p-4">
125
+ {sintonizado && <Dashboard />}
126
+ {!sintonizado && (
127
+ <div className="text-center">
128
+ <h2 className="text-2xl font-bold mb-4">Dashboard</h2>
129
+ <p>Pulse el botón para sintonizar</p>
130
+ <button
131
+ onClick={handleSintonizar}
132
+ className="bg-blue-500 hover:bg-blue-700 text-white py-2 px-4 rounded"
133
+ >
134
+ Sintonizar
135
+ </button>
136
+ </div>
137
+ )}
138
+ {!logged && <Reportes />}
139
+ {logged && !sintonizado && (
140
+ <MonitoreoGnosis />
141
+ )}
142
+ </div>
143
+ </div>
144
+ </main>
145
+ )}
146
+ </div>
147
+ );
148
+ }
149
+
150
+ export default HectronApp;
151
+ ```
152
+ **Login.js**
153
+ ```jsx
154
+ import React, { useState } from 'react';
155
+ import axios from 'axios';
156
+
157
+ const Login = ({ onLogin }) => {
158
+ const [email, setEmail] = useState('');
159
+ const [password, setPassword] = useState('');
160
+ const [error, setError] = useState(null);
161
+
162
+ const handleLogin = async () => {
163
+ if (!email || !password) {
164
+ return setError('Correo electrónico y contraseña son obligatorios');
165
+ }
166
+ try {
167
+ const response = await axios.post('/login', { email, password });
168
+ onLogin(email, password);
169
+ } catch (error) {
170
+ console.error(error);
171
+ setError('Error de autenticación');
172
+ }
173
+ };
174
+
175
+ return (
176
+ <div className="flex h-screen justify-center items-center overflow-hidden bg-gray-100">
177
+ <div className="max-w-md p-8 bg-white rounded-lg shadow-lg">
178
+ <h2 className="text-2xl font-bold mb-4">Inicio de sesión</h2>
179
+ {error && <p className="text-red-500 mb-4">{error}</p>}
180
+ <form>
181
+ <div className="mb-4">
182
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="email">
183
+ Correo electrónico
184
+ </label>
185
+ <input
186
+ className="shadow appearance-none border rounded py-2 px-3 w-full justify-center items-center"
187
+ id="email"
188
+ type="email"
189
+ value={email}
190
+ onChange={(e) => setEmail(e.target.value)}
191
+ />
192
+ </div>
193
+ <div className="mb-4">
194
+ <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="password">
195
+ Contraseña
196
+ </label>
197
+ <input
198
+ className="shadow appearance-none border rounded py-2 px-3 w-full justify-center items-center"
199
+ id="password"
200
+ type="password"
201
+ value={password}
202
+ onChange={(e) => setPassword(e.target.value)}
203
+ />
204
+ </div>
205
+ <button
206
+ className="bg-blue-500 hover:bg-blue-700 text-white py-2 px-4 rounded"
207
+ onClick={handleLogin}
208
+ >
209
+ Iniciar sesión
210
+ </button>
211
+ </form>
212
+ </div>
213
+ </div>
214
+ );
215
+ };
216
+
217
+ export default Login;
218
+ ```
219
+ **Dashboard.js**
220
+ ```jsx
221
+ import React from 'react';
222
+ import axios from 'axios';
223
+
224
+ const Dashboard = () => {
225
+ const [data, setData] = React.useState({});
226
+
227
+ React.useEffect(() => {
228
+ const fetchDashboardData = async () => {
229
+ try {
230
+ const response = await axios.get('/dashboard');
231
+ setData(response.data);
232
+ } catch (error) {
233
+ console.error(error);
234
+ }
235
+ };
236
+ fetchDashboardData();
237
+ }, []);
238
+
239
+ return (
240
+ <div className="max-w-md p-8 bg-white rounded-lg shadow-lg">
241
+ <h2 className="text-2xl font-bold mb-4">Dashboard</h2>
242
+ <ul>
243
+ <li>
244
+ <span className="text-gray-700 text-sm font-bold mb-2">Monitoreo de Gnosis</span>
245
+ <span className="ml-2">{data.monitoreoGnosis}</span>
246
+ </li>
247
+ <li>
248
+ <span className="text-gray-700 text-sm font-bold mb-2">Configuración de alertas</span>
249
+ <span className="ml-2">{data.configuracionAlertas}</span>
250
+ </li>
251
+ <li>
252
+ <span className="text-gray-700 text-sm font-bold mb-2">Acceso a reportes</span>
253
+ <span className="ml-2">{data.accesoReportes}</span>
254
+ </li>
255
+ </ul>
256
+ </div>
257
+ );
258
+ };
259
+
260
+ export default Dashboard;
261
+ ```
262
+ **Reportes.js**
263
+ ```jsx
264
+ import React from 'react';
265
+
266
+ const Reportes = () => {
267
+ return (
268
+ <div className="max-w-md p-8 bg-white rounded-lg shadow-lg">
269
+ <h2 className="text-2xl font-bold mb-4">Reportes</h2>
270
+ <p>Este es un lugar donde se podrán ver reportes de la aplicación.</p>
271
+ </div>
272
+ );
273
+ };
274
+
275
+ export default Reportes;
276
+ ```
277
+ **MonitoreoGnosis.js**
278
+ ```jsx
279
+ import React from 'react';
280
+
281
+ const MonitoreoGnosis = () => {
282
+ return (
283
+ <div className="max-w-md p-8 bg-white rounded-lg shadow-lg">
284
+ <h2 className="text-2xl font-bold mb-4">Monitoreo de Gnosis</h2>
285
+ <p>Este es un lugar donde se puede monitorear la salud y el estado del sistema.</p>
286
+ </div>
287
+ );
288
+ };
289
+
290
+ export default MonitoreoGnosis;
291
+ ```