AIdeaText commited on
Commit
a5fb792
·
verified ·
1 Parent(s): b58af47

Update modules/morphosyntax/morphosyntax_interface.py

Browse files
modules/morphosyntax/morphosyntax_interface.py CHANGED
@@ -23,6 +23,7 @@ from .morphosyntax_process import (
23
  )
24
 
25
  from ..utils.widget_utils import generate_unique_key
 
26
  from ..database.morphosyntax_iterative_mongo_db import (
27
  store_student_morphosyntax_base,
28
  store_student_morphosyntax_iteration,
@@ -37,12 +38,14 @@ logger = logging.getLogger(__name__)
37
 
38
  ###########################################################################
39
  def initialize_arc_analysis_state():
40
- """Inicializa el estado del análisis de arcos y el caché si no existen"""
41
  if 'arc_analysis_state' not in st.session_state:
42
  st.session_state.arc_analysis_state = {
43
- 'base_id': None,
44
- 'original_text': '',
45
- 'iteration_text': '',
 
 
46
  'analysis_count': 0
47
  }
48
  logger.info("Estado de análisis de arcos inicializado")
@@ -52,76 +55,88 @@ def initialize_arc_analysis_state():
52
  st.session_state.analysis_cache = {}
53
  logger.info("Caché de análisis inicializado")
54
 
55
- ###########################################################################
56
  def reset_morpho_state():
57
- """Resetea el estado del análisis morfosintáctico"""
58
  if 'arc_analysis_state' in st.session_state:
59
  st.session_state.arc_analysis_state = {
60
  'base_id': None,
61
  'original_text': '',
 
62
  'iteration_text': '',
 
63
  'analysis_count': 0
64
  }
65
 
66
- ###########################################################################
67
  def display_original_analysis(container, analysis, lang_code, morpho_t):
68
- """Muestra el análisis original en el contenedor especificado"""
69
  with container:
70
  st.subheader("Análisis Original")
71
  display_morphosyntax_results(analysis, lang_code, morpho_t)
72
 
 
73
  def display_iteration_analysis(container, analysis, lang_code, morpho_t):
74
- """Muestra el análisis de cambios en el contenedor especificado"""
75
  with container:
76
  st.subheader("Análisis de Cambios")
77
  display_morphosyntax_results(analysis, lang_code, morpho_t)
78
 
 
79
  def display_arc_diagram(doc, analysis):
80
- """Muestra un diagrama de arco sin título"""
81
  try:
82
  for sent in doc.sents:
83
- rendered = displacy.render(sent, style="dep", options={
84
- "distance": 100,
85
- "arrow_spacing": 20,
86
- "word_spacing": 30
87
- })
88
-
 
 
 
89
  # Ajustar tamaño y posición
90
- rendered = rendered.replace('height="375"', 'height="200"')
91
- rendered = re.sub(
92
  r'<svg[^>]*>',
93
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
94
- rendered
95
  )
96
- rendered = re.sub(
97
- r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
98
  lambda m: f'<g transform="translate({m.group(1)},50)"',
99
- rendered
100
  )
101
 
102
  # Envolver en contenedor con estilo
103
- rendered = f'<div class="arc-diagram-container">{rendered}</div>'
104
- st.write(rendered, unsafe_allow_html=True)
105
 
106
  except Exception as e:
107
  logger.error(f"Error en display_arc_diagram: {str(e)}")
108
 
109
- ###########################################################################
110
  def cache_analysis_results(key, result):
111
- """Almacena resultados de análisis en caché"""
112
  if 'analysis_cache' not in st.session_state:
113
- st.session_state.analysis_cache = {}
114
  st.session_state.analysis_cache[key] = result
115
  logger.info(f"Resultado almacenado en caché con clave: {key}")
116
 
 
117
  def get_cached_analysis(key):
118
- """Recupera resultados de análisis del caché"""
119
  if 'analysis_cache' not in st.session_state:
 
120
  return None
121
  return st.session_state.analysis_cache.get(key)
122
 
123
- ###########################################################################
124
  def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
 
 
 
125
  try:
126
  # CSS para layout estable
127
  st.markdown("""
@@ -149,46 +164,58 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
149
  # Inicializar estados si no existen
150
  initialize_arc_analysis_state()
151
 
152
- # -- Tabs: definimos 3 pestañas
153
  subtabs = st.tabs([
154
  "Análisis de Diagramas de Arco",
155
  "Análisis de Categorías",
156
  "Análisis Morfológico"
157
  ])
158
 
159
- # =========== Pestaña 1: Diagrama de Arco ===============
160
  with subtabs[0]:
161
- col1, col2, col3 = st.columns([2,1,2])
 
162
  with col1:
163
  if st.button("Nuevo Análisis", type="secondary", use_container_width=True):
164
  reset_morpho_state()
165
-
166
- # Contenedor de todo el proceso
167
- with st.container():
168
- # Input texto original
 
 
 
 
169
  text_input = st.text_area(
170
- "Ingrese su texto",
171
  value=st.session_state.arc_analysis_state.get('original_text', ''),
172
- key=f"original_text_{st.session_state.arc_analysis_state['analysis_count']}",
173
  height=100
174
  )
175
 
176
- analyze_button = st.button(
177
- "Analizar Texto",
178
- type="primary",
179
- use_container_width=True
180
- )
 
 
 
181
 
182
  # Procesar texto original
183
  if analyze_button and text_input.strip():
184
  try:
 
 
 
 
185
  doc = nlp_models[lang_code](text_input)
186
  analysis = perform_advanced_morphosyntactic_analysis(
187
  text_input,
188
  nlp_models[lang_code]
189
  )
190
 
191
- # Guardar en Mongo
192
  base_id = store_student_morphosyntax_base(
193
  st.session_state.username,
194
  text_input,
@@ -196,32 +223,47 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
196
  )
197
 
198
  if base_id:
199
- # Actualizar estado
200
- st.session_state.arc_analysis_state['base_id'] = base_id
201
- st.session_state.arc_analysis_state['original_text'] = text_input
202
- st.session_state.arc_analysis_state['analysis_count'] += 1
203
-
 
 
 
 
 
 
 
204
  display_arc_diagram(doc, analysis)
205
 
 
206
  st.markdown('<hr class="divider">', unsafe_allow_html=True)
207
 
208
- # Caja de texto para la iteración
209
- st.subheader("Iteración / Cambios:")
210
- iteration_text = st.text_area(
211
- "Ingrese cambios o versión modificada",
212
- value=st.session_state.arc_analysis_state.get('iteration_text', ''),
213
- key="iteration_text",
214
- height=100
215
- )
216
-
217
- # Botón para analizar iteración
218
- iteration_button = st.button(
219
- "Analizar Cambios",
220
- type="primary",
221
- use_container_width=True
222
- )
223
-
224
- if iteration_button and iteration_text.strip():
 
 
 
 
 
 
 
225
  try:
226
  doc_iter = nlp_models[lang_code](iteration_text)
227
  analysis_iter = perform_advanced_morphosyntactic_analysis(
@@ -231,15 +273,19 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
231
 
232
  iteration_id = store_student_morphosyntax_iteration(
233
  st.session_state.username,
234
- base_id,
235
- text_input,
236
- iteration_text,
237
  analysis_iter['arc_diagrams']
238
  )
239
 
240
  if iteration_id:
241
- # Guardamos el texto de iteración en session_state
242
- st.session_state.arc_analysis_state['iteration_text'] = iteration_text
 
 
 
 
243
  display_arc_diagram(doc_iter, analysis_iter)
244
 
245
  except Exception as e:
@@ -248,59 +294,63 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
248
 
249
  except Exception as e:
250
  st.error("Error procesando análisis base")
251
- logger.error(f"Error: {str(e)}")
252
 
253
- # =========== Pestaña 2: Categorías (placeholder) ============
254
  with subtabs[1]:
255
  st.info("Análisis de Categorías en desarrollo...")
256
 
257
- # =========== Pestaña 3: Análisis Morfológico (placeholder) ============
258
  with subtabs[2]:
259
  st.info("Análisis Morfológico en desarrollo...")
260
 
261
  except Exception as e:
262
- st.error("Error en la interfaz")
263
  logger.error(f"Error general en la interfaz: {str(e)}")
264
 
265
- ###########################################################################
266
  def display_morphosyntax_results(result, lang_code, morpho_t):
267
  """
268
  Muestra solo el diagrama de arco.
269
  Args:
270
  result: Diccionario con el documento procesado y su análisis
271
  lang_code: Código del idioma
272
- morpho_t: Diccionario de traducciones
273
  """
274
- if result is None:
275
  return
276
-
277
  try:
278
  doc = result['doc']
279
  sentences = list(doc.sents)
280
  for i, sent in enumerate(sentences):
281
  try:
282
  st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
283
- rendered = displacy.render(sent, style="dep", options={
284
- "distance": 100,
285
- "arrow_spacing": 20,
286
- "word_spacing": 30
287
- })
288
- rendered = rendered.replace('height="375"', 'height="200"')
289
- rendered = re.sub(
 
 
 
 
290
  r'<svg[^>]*>',
291
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
292
- rendered
293
  )
294
- rendered = re.sub(
295
  r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
296
  lambda m: f'<g transform="translate({m.group(1)},50)"',
297
- rendered
298
  )
299
- rendered = f'<div class="arc-diagram-container">{rendered}</div>'
300
- st.write(rendered, unsafe_allow_html=True)
301
- except Exception as e:
302
- logger.error(f"Error en diagrama {i}: {str(e)}")
303
  continue
304
  except Exception as e:
305
  logger.error(f"Error en display_morphosyntax_results: {str(e)}")
306
 
 
 
23
  )
24
 
25
  from ..utils.widget_utils import generate_unique_key
26
+
27
  from ..database.morphosyntax_iterative_mongo_db import (
28
  store_student_morphosyntax_base,
29
  store_student_morphosyntax_iteration,
 
38
 
39
  ###########################################################################
40
  def initialize_arc_analysis_state():
41
+ """Inicializa el estado del análisis de arcos y el caché si no existen."""
42
  if 'arc_analysis_state' not in st.session_state:
43
  st.session_state.arc_analysis_state = {
44
+ 'base_id': None, # ID del análisis base (ObjectId)
45
+ 'original_text': '', # Texto original
46
+ 'original_analysis': None, # Dict con resultados del análisis base
47
+ 'iteration_text': '', # Texto de iteración
48
+ 'iteration_analysis': None,# Dict con resultados de la iteración
49
  'analysis_count': 0
50
  }
51
  logger.info("Estado de análisis de arcos inicializado")
 
55
  st.session_state.analysis_cache = {}
56
  logger.info("Caché de análisis inicializado")
57
 
58
+
59
  def reset_morpho_state():
60
+ """Resetea el estado del análisis morfosintáctico en sesión."""
61
  if 'arc_analysis_state' in st.session_state:
62
  st.session_state.arc_analysis_state = {
63
  'base_id': None,
64
  'original_text': '',
65
+ 'original_analysis': None,
66
  'iteration_text': '',
67
+ 'iteration_analysis': None,
68
  'analysis_count': 0
69
  }
70
 
71
+
72
  def display_original_analysis(container, analysis, lang_code, morpho_t):
73
+ """Muestra el análisis original en el contenedor especificado."""
74
  with container:
75
  st.subheader("Análisis Original")
76
  display_morphosyntax_results(analysis, lang_code, morpho_t)
77
 
78
+
79
  def display_iteration_analysis(container, analysis, lang_code, morpho_t):
80
+ """Muestra el análisis de cambios en el contenedor especificado."""
81
  with container:
82
  st.subheader("Análisis de Cambios")
83
  display_morphosyntax_results(analysis, lang_code, morpho_t)
84
 
85
+
86
  def display_arc_diagram(doc, analysis):
87
+ """Muestra un diagrama de arco sin título."""
88
  try:
89
  for sent in doc.sents:
90
+ svg_html = displacy.render(
91
+ sent,
92
+ style="dep",
93
+ options={
94
+ "distance": 100,
95
+ "arrow_spacing": 20,
96
+ "word_spacing": 30
97
+ }
98
+ )
99
  # Ajustar tamaño y posición
100
+ svg_html = svg_html.replace('height="375"', 'height="200"')
101
+ svg_html = re.sub(
102
  r'<svg[^>]*>',
103
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
104
+ svg_html
105
  )
106
+ svg_html = re.sub(
107
+ r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
108
  lambda m: f'<g transform="translate({m.group(1)},50)"',
109
+ svg_html
110
  )
111
 
112
  # Envolver en contenedor con estilo
113
+ svg_html = f'<div class="arc-diagram-container">{svg_html}</div>'
114
+ st.write(svg_html, unsafe_allow_html=True)
115
 
116
  except Exception as e:
117
  logger.error(f"Error en display_arc_diagram: {str(e)}")
118
 
119
+
120
  def cache_analysis_results(key, result):
121
+ """Almacena resultados de análisis en caché."""
122
  if 'analysis_cache' not in st.session_state:
123
+ initialize_arc_analysis_state()
124
  st.session_state.analysis_cache[key] = result
125
  logger.info(f"Resultado almacenado en caché con clave: {key}")
126
 
127
+
128
  def get_cached_analysis(key):
129
+ """Recupera resultados de análisis del caché."""
130
  if 'analysis_cache' not in st.session_state:
131
+ initialize_arc_analysis_state()
132
  return None
133
  return st.session_state.analysis_cache.get(key)
134
 
135
+
136
  def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
137
+ """
138
+ Interfaz principal para el análisis morfosintáctico.
139
+ """
140
  try:
141
  # CSS para layout estable
142
  st.markdown("""
 
164
  # Inicializar estados si no existen
165
  initialize_arc_analysis_state()
166
 
167
+ # Crear subtabs
168
  subtabs = st.tabs([
169
  "Análisis de Diagramas de Arco",
170
  "Análisis de Categorías",
171
  "Análisis Morfológico"
172
  ])
173
 
174
+ # -------------------- Subtab 0: Diagramas de Arco --------------------
175
  with subtabs[0]:
176
+ # Botón de reset
177
+ col1, col2, col3 = st.columns([2, 1, 2])
178
  with col1:
179
  if st.button("Nuevo Análisis", type="secondary", use_container_width=True):
180
  reset_morpho_state()
181
+ # Forzar un refresco completo solo en este caso
182
+ st.experimental_rerun()
183
+
184
+ # Container principal para análisis base
185
+ analysis_container = st.container()
186
+ with analysis_container:
187
+ # Entrada de texto original
188
+ text_input_key = f"original_text_{st.session_state.arc_analysis_state['analysis_count']}"
189
  text_input = st.text_area(
190
+ "Texto original",
191
  value=st.session_state.arc_analysis_state.get('original_text', ''),
192
+ key=text_input_key,
193
  height=100
194
  )
195
 
196
+ # Botón de análisis
197
+ col1, col2, col3 = st.columns([2, 1, 2])
198
+ with col1:
199
+ analyze_button = st.button(
200
+ "Analizar Texto",
201
+ type="primary",
202
+ use_container_width=True
203
+ )
204
 
205
  # Procesar texto original
206
  if analyze_button and text_input.strip():
207
  try:
208
+ if not getattr(st.session_state, 'username', None):
209
+ st.error("No se detectó username en session_state. Verifica tu login.")
210
+ return
211
+
212
  doc = nlp_models[lang_code](text_input)
213
  analysis = perform_advanced_morphosyntactic_analysis(
214
  text_input,
215
  nlp_models[lang_code]
216
  )
217
 
218
+ # Guardar en BD (retornará ObjectId)
219
  base_id = store_student_morphosyntax_base(
220
  st.session_state.username,
221
  text_input,
 
223
  )
224
 
225
  if base_id:
226
+ # Actualizar el estado en session_state
227
+ st.session_state.arc_analysis_state.update({
228
+ 'base_id': base_id, # Guardamos el ObjectId
229
+ 'original_text': text_input,
230
+ 'original_analysis': analysis,
231
+ 'analysis_count': st.session_state.arc_analysis_state['analysis_count'] + 1,
232
+ # Reiniciamos la iteración
233
+ 'iteration_text': '',
234
+ 'iteration_analysis': None
235
+ })
236
+
237
+ # Mostrar diagrama base
238
  display_arc_diagram(doc, analysis)
239
 
240
+ # Línea divisora
241
  st.markdown('<hr class="divider">', unsafe_allow_html=True)
242
 
243
+ # Sección para la iteración
244
+ st.subheader("Iteración / Cambios")
245
+ with st.form("iteration_form"):
246
+ # key para la iteración
247
+ iteration_text_key = f"iteration_text_{st.session_state.arc_analysis_state['analysis_count']}"
248
+
249
+ # En lugar de default = text_input, ahora dejamos vacío por defecto
250
+ iteration_text = st.text_area(
251
+ "Texto de iteración",
252
+ value=st.session_state.arc_analysis_state.get('iteration_text', ''),
253
+ key=iteration_text_key,
254
+ height=100
255
+ )
256
+
257
+ # Botón de submit en el formulario
258
+ col1, col2, col3 = st.columns([2,1,2])
259
+ with col1:
260
+ submitted = st.form_submit_button(
261
+ "Analizar Cambios",
262
+ type="primary",
263
+ use_container_width=True
264
+ )
265
+
266
+ if submitted and iteration_text.strip():
267
  try:
268
  doc_iter = nlp_models[lang_code](iteration_text)
269
  analysis_iter = perform_advanced_morphosyntactic_analysis(
 
273
 
274
  iteration_id = store_student_morphosyntax_iteration(
275
  st.session_state.username,
276
+ base_id, # este es ObjectId
277
+ text_input, # Texto original
278
+ iteration_text, # Texto de iteración
279
  analysis_iter['arc_diagrams']
280
  )
281
 
282
  if iteration_id:
283
+ # Actualizamos el estado de la iteración
284
+ st.session_state.arc_analysis_state.update({
285
+ 'iteration_text': iteration_text,
286
+ 'iteration_analysis': analysis_iter
287
+ })
288
+ # Mostrar diagrama de iteración
289
  display_arc_diagram(doc_iter, analysis_iter)
290
 
291
  except Exception as e:
 
294
 
295
  except Exception as e:
296
  st.error("Error procesando análisis base")
297
+ logger.error(f"Error base: {str(e)}")
298
 
299
+ # -------------------- Subtab 1: Análisis de Categorías ----------------
300
  with subtabs[1]:
301
  st.info("Análisis de Categorías en desarrollo...")
302
 
303
+ # -------------------- Subtab 2: Análisis Morfológico ------------------
304
  with subtabs[2]:
305
  st.info("Análisis Morfológico en desarrollo...")
306
 
307
  except Exception as e:
308
+ st.error("Error en la interfaz de morfosintaxis")
309
  logger.error(f"Error general en la interfaz: {str(e)}")
310
 
311
+
312
  def display_morphosyntax_results(result, lang_code, morpho_t):
313
  """
314
  Muestra solo el diagrama de arco.
315
  Args:
316
  result: Diccionario con el documento procesado y su análisis
317
  lang_code: Código del idioma
318
+ morpho_t: Diccionario de traducciones (opcional)
319
  """
320
+ if not result:
321
  return
 
322
  try:
323
  doc = result['doc']
324
  sentences = list(doc.sents)
325
  for i, sent in enumerate(sentences):
326
  try:
327
  st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
328
+ svg_html = displacy.render(
329
+ sent,
330
+ style="dep",
331
+ options={
332
+ "distance": 100,
333
+ "arrow_spacing": 20,
334
+ "word_spacing": 30
335
+ }
336
+ )
337
+ svg_html = svg_html.replace('height="375"', 'height="200"')
338
+ svg_html = re.sub(
339
  r'<svg[^>]*>',
340
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
341
+ svg_html
342
  )
343
+ svg_html = re.sub(
344
  r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
345
  lambda m: f'<g transform="translate({m.group(1)},50)"',
346
+ svg_html
347
  )
348
+ svg_html = f'<div class="arc-diagram-container">{svg_html}</div>'
349
+ st.write(svg_html, unsafe_allow_html=True)
350
+ except Exception as exc:
351
+ logger.error(f"Error mostrando diagrama de la oración {i}: {str(exc)}")
352
  continue
353
  except Exception as e:
354
  logger.error(f"Error en display_morphosyntax_results: {str(e)}")
355
 
356
+