AIdeaText commited on
Commit
8e359f5
verified
1 Parent(s): 640abf8

Upload morphosyntax_interface.py

Browse files
modules/morphosyntax/morphosyntax_interface.py CHANGED
@@ -1,228 +1,241 @@
1
- # modules/morphosyntax/morphosyntax_interface.py
2
-
3
- import streamlit as st
4
- import re
5
- import logging
6
- from spacy import displacy
7
-
8
- # Funciones de an谩lisis y DB que ya tienes en tus m贸dulos
9
- from ..morphosyntax.morphosyntax_process import perform_advanced_morphosyntactic_analysis
10
- from ..database.morphosyntax_iterative_mongo_db import (
11
- store_student_morphosyntax_base,
12
- store_student_morphosyntax_iteration,
13
- )
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
- ###########################################################################
18
- def initialize_arc_analysis_state():
19
- """Inicializa el estado de an谩lisis de arcos (base e iteraciones) si no existe."""
20
- if "arc_analysis_state" not in st.session_state:
21
- st.session_state.arc_analysis_state = {
22
- "base_id": None,
23
- "base_text": "",
24
- "base_diagram": None,
25
- "iteration_text": "",
26
- "iteration_diagram": None,
27
- }
28
- logger.info("Estado de an谩lisis de arcos inicializado.")
29
-
30
- ###########################################################################
31
- def reset_arc_analysis_state():
32
- """Resetea completamente el estado de an谩lisis de arcos."""
33
- st.session_state.arc_analysis_state = {
34
- "base_id": None,
35
- "base_text": "",
36
- "base_diagram": None,
37
- "iteration_text": "",
38
- "iteration_diagram": None,
39
- }
40
- logger.info("Estado de arcos reseteado.")
41
-
42
- ###########################################################################
43
- def display_arc_diagram(doc):
44
- """
45
- Genera y retorna el HTML del diagrama de arco para un Doc de spaCy.
46
- No imprime directamente; retorna el HTML para usar con st.write(...).
47
- """
48
- try:
49
- diagram_html = ""
50
- for sent in doc.sents:
51
- svg_html = displacy.render(
52
- sent,
53
- style="dep",
54
- options={
55
- "distance": 100,
56
- "arrow_spacing": 20,
57
- "word_spacing": 30
58
- }
59
- )
60
- # Ajustar tama帽os
61
- svg_html = svg_html.replace('height="375"', 'height="200"')
62
- svg_html = re.sub(
63
- r'<svg[^>]*>',
64
- lambda m: m.group(0).replace('height="450"', 'height="300"'),
65
- svg_html
66
- )
67
- svg_html = re.sub(
68
- r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
69
- lambda m: f'<g transform="translate({m.group(1)},50)"',
70
- svg_html
71
- )
72
- # Envolver en contenedor
73
- diagram_html += f'<div class="arc-diagram-container">{svg_html}</div>'
74
- return diagram_html
75
-
76
- except Exception as e:
77
- logger.error(f"Error en display_arc_diagram: {str(e)}")
78
- return "<p style='color:red;'>Error generando diagrama</p>"
79
-
80
- ###########################################################################
81
- def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
82
- """
83
- Interfaz principal para la visualizaci贸n de diagramas de arco
84
- (Texto Base vs Iteraciones).
85
- """
86
- # CSS para layout vertical y estable
87
- st.markdown("""
88
- <style>
89
- .stTextArea textarea {
90
- font-size: 1rem;
91
- line-height: 1.5;
92
- min-height: 100px !important;
93
- height: 100px !important;
94
- }
95
- .arc-diagram-container {
96
- width: 100%;
97
- padding: 0.5rem;
98
- margin: 0.5rem 0;
99
- }
100
- .divider {
101
- height: 3px;
102
- border: none;
103
- background-color: #333;
104
- margin: 2rem 0;
105
- }
106
- </style>
107
- """, unsafe_allow_html=True)
108
-
109
- # 1) Inicializar estados
110
- initialize_arc_analysis_state()
111
- arc_state = st.session_state.arc_analysis_state
112
-
113
- # 2) Creamos pesta帽as: "Texto Base" y "Iteraciones"
114
- tabs = st.tabs(["Texto Base", "Iteraciones"])
115
-
116
- # =================== PESTA脩A 1: Texto Base ==========================
117
- with tabs[0]:
118
- st.subheader("An谩lisis de Texto Base")
119
-
120
- # Bot贸n para iniciar nuevo an谩lisis
121
- if st.button("Nuevo An谩lisis", key="btn_reset_base"):
122
- # Si requieres recargar la app por completo, podr铆as descomentar:
123
- # st.experimental_rerun()
124
- reset_arc_analysis_state()
125
-
126
- # Textarea de texto base
127
- arc_state["base_text"] = st.text_area(
128
- "Ingrese su texto inicial",
129
- value=arc_state["base_text"],
130
- key="base_text_input",
131
- height=150
132
- )
133
-
134
- # Bot贸n para analizar texto base
135
- if st.button("Analizar Texto Base", key="btn_analyze_base"):
136
- if not arc_state["base_text"].strip():
137
- st.warning("Ingrese un texto para analizar.")
138
- else:
139
- try:
140
- # Procesar con spaCy
141
- doc = nlp_models[lang_code](arc_state["base_text"])
142
- base_arc_html = display_arc_diagram(doc)
143
- arc_state["base_diagram"] = base_arc_html
144
-
145
- # Guardar en Mongo
146
- analysis = perform_advanced_morphosyntactic_analysis(
147
- arc_state["base_text"],
148
- nlp_models[lang_code]
149
- )
150
- base_id = store_student_morphosyntax_base(
151
- username=st.session_state.username,
152
- text=arc_state["base_text"],
153
- arc_diagrams=analysis["arc_diagrams"]
154
- )
155
- if base_id:
156
- arc_state["base_id"] = base_id
157
- st.success(f"An谩lisis base guardado. ID: {base_id}")
158
-
159
- except Exception as exc:
160
- st.error("Error procesando texto base")
161
- logger.error(f"Error en an谩lisis base: {str(exc)}")
162
-
163
- # Mostrar diagrama base
164
- if arc_state["base_diagram"]:
165
- st.markdown("<hr class='divider'>", unsafe_allow_html=True)
166
- st.markdown("#### Diagrama de Arco (Texto Base)")
167
- st.write(arc_state["base_diagram"], unsafe_allow_html=True)
168
-
169
- # ================== PESTA脩A 2: Iteraciones ==========================
170
- with tabs[1]:
171
- st.subheader("An谩lisis de Cambios / Iteraciones")
172
-
173
- # Verificar que exista un texto base
174
- if not arc_state["base_id"]:
175
- st.info("Primero analiza un texto base en la pesta帽a anterior.")
176
- return
177
-
178
- # --- 1) Mostrar SIEMPRE el diagrama base arriba ---
179
- st.markdown("#### Diagrama de Arco (Texto Base)")
180
- if arc_state["base_diagram"]:
181
- st.write(arc_state["base_diagram"], unsafe_allow_html=True)
182
- else:
183
- st.info("No hay diagrama base disponible.")
184
-
185
- # --- 2) Caja de texto para la iteraci贸n ---
186
- st.markdown("<hr class='divider'>", unsafe_allow_html=True)
187
- st.subheader("Texto de Iteraci贸n")
188
- arc_state["iteration_text"] = st.text_area(
189
- "Ingrese su nueva versi贸n / iteraci贸n",
190
- value=arc_state["iteration_text"],
191
- height=150
192
- )
193
-
194
- # Bot贸n para analizar iteraci贸n
195
- if st.button("Analizar Cambios", key="btn_analyze_iteration"):
196
- if not arc_state["iteration_text"].strip():
197
- st.warning("Ingrese texto de iteraci贸n.")
198
- else:
199
- try:
200
- # Procesar con spaCy
201
- doc_iter = nlp_models[lang_code](arc_state["iteration_text"])
202
- arc_html_iter = display_arc_diagram(doc_iter)
203
- arc_state["iteration_diagram"] = arc_html_iter
204
-
205
- # Guardar en Mongo
206
- analysis_iter = perform_advanced_morphosyntactic_analysis(
207
- arc_state["iteration_text"],
208
- nlp_models[lang_code]
209
- )
210
- iteration_id = store_student_morphosyntax_iteration(
211
- username=st.session_state.username,
212
- base_id=arc_state["base_id"],
213
- original_text=arc_state["base_text"],
214
- iteration_text=arc_state["iteration_text"],
215
- arc_diagrams=analysis_iter["arc_diagrams"]
216
- )
217
- if iteration_id:
218
- st.success(f"Iteraci贸n guardada. ID: {iteration_id}")
219
-
220
- except Exception as exc:
221
- st.error("Error procesando iteraci贸n")
222
- logger.error(f"Error en iteraci贸n: {str(exc)}")
223
-
224
- # --- 3) Mostrar diagrama de iteraci贸n debajo ---
225
- if arc_state["iteration_diagram"]:
226
- st.markdown("<hr class='divider'>", unsafe_allow_html=True)
227
- st.markdown("#### Diagrama de Arco (Iteraci贸n)")
228
- st.write(arc_state["iteration_diagram"], unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #morphosyntax_interface.py
2
+
3
+ import streamlit as st
4
+ import re
5
+ import logging
6
+ from spacy import displacy
7
+
8
+ # Funciones de an谩lisis y DB que ya tienes en tus m贸dulos
9
+ from ..morphosyntax.morphosyntax_process import perform_advanced_morphosyntactic_analysis
10
+ from ..database.morphosyntax_iterative_mongo_db import (
11
+ store_student_morphosyntax_base,
12
+ store_student_morphosyntax_iteration,
13
+ )
14
+
15
+ from translations import get_translations
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ ###########################################################################
20
+ def initialize_arc_analysis_state():
21
+ """Inicializa el estado de an谩lisis de arcos (base e iteraciones) si no existe."""
22
+ if "arc_analysis_state" not in st.session_state:
23
+ st.session_state.arc_analysis_state = {
24
+ "base_id": None,
25
+ "base_text": "",
26
+ "base_diagram": None,
27
+ "iteration_text": "",
28
+ "iteration_diagram": None,
29
+ }
30
+ logger.info("Estado de an谩lisis de arcos inicializado.")
31
+
32
+ ###########################################################################
33
+ def reset_arc_analysis_state():
34
+ """Resetea completamente el estado de an谩lisis de arcos."""
35
+ st.session_state.arc_analysis_state = {
36
+ "base_id": None,
37
+ "base_text": "",
38
+ "base_diagram": None,
39
+ "iteration_text": "",
40
+ "iteration_diagram": None,
41
+ }
42
+ logger.info("Estado de arcos reseteado.")
43
+
44
+ ###########################################################################
45
+ def display_arc_diagram(doc):
46
+ """
47
+ Genera y retorna el HTML del diagrama de arco para un Doc de spaCy.
48
+ No imprime directamente; retorna el HTML para usar con st.write(...).
49
+ """
50
+ try:
51
+ diagram_html = ""
52
+ for sent in doc.sents:
53
+ svg_html = displacy.render(
54
+ sent,
55
+ style="dep",
56
+ options={
57
+ "distance": 100,
58
+ "arrow_spacing": 20,
59
+ "word_spacing": 30
60
+ }
61
+ )
62
+ # Ajustar tama帽os en el SVG resultante
63
+ svg_html = svg_html.replace('height="375"', 'height="200"')
64
+ svg_html = re.sub(
65
+ r'<svg[^>]*>',
66
+ lambda m: m.group(0).replace('height="450"', 'height="300"'),
67
+ svg_html
68
+ )
69
+ svg_html = re.sub(
70
+ r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
71
+ lambda m: f'<g transform="translate({m.group(1)},50)"',
72
+ svg_html
73
+ )
74
+ # Envolver en contenedor
75
+ diagram_html += f'<div class="arc-diagram-container">{svg_html}</div>'
76
+ return diagram_html
77
+
78
+ except Exception as e:
79
+ logger.error(f"Error en display_arc_diagram: {str(e)}")
80
+ return "<p style='color:red;'>Error generando diagrama</p>"
81
+
82
+ ###########################################################################
83
+ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
84
+ """
85
+ Interfaz principal para la visualizaci贸n de diagramas de arco
86
+ (Texto Base vs Iteraciones), usando traducciones con morpho_t.
87
+ """
88
+ # CSS para layout y estilo
89
+ st.markdown("""
90
+ <style>
91
+ .stTextArea textarea {
92
+ font-size: 1rem;
93
+ line-height: 1.5;
94
+ min-height: 100px !important;
95
+ height: 100px !important;
96
+ }
97
+ .arc-diagram-container {
98
+ width: 100%;
99
+ padding: 0.5rem;
100
+ margin: 0.5rem 0;
101
+ }
102
+ .divider {
103
+ height: 3px;
104
+ border: none;
105
+ background-color: #333;
106
+ margin: 2rem 0;
107
+ }
108
+ </style>
109
+ """, unsafe_allow_html=True)
110
+
111
+ # 1) Inicializar estados
112
+ initialize_arc_analysis_state()
113
+ arc_state = st.session_state.arc_analysis_state
114
+
115
+ # 2) Crear pesta帽as con etiquetas traducidas
116
+ tab_text_base = morpho_t.get('tab_text_baseline', 'Ingresa la primera versi贸n de tu texto')
117
+ tab_iterations = morpho_t.get('tab_iterations', 'Produce nuevas versiones de tu primer texto')
118
+ tabs = st.tabs([tab_text_base, tab_iterations])
119
+
120
+ # =================== PESTA脩A 1: Texto Base ==========================
121
+ with tabs[0]:
122
+ # st.subheader(morpho_t.get('analysis_base_subheader', "An谩lisis de Texto Base"))
123
+
124
+ # Textarea de texto base
125
+ arc_state["base_text"] = st.text_area(
126
+ morpho_t.get('input_baseline_text', "Ingresa el primer texto para analizarlo"),
127
+ value=arc_state["base_text"],
128
+ key="base_text_input",
129
+ height=150
130
+ )
131
+
132
+ # Bot贸n para analizar texto base
133
+ if st.button(morpho_t.get('btn_analyze_baseline', "Analizar la primera versi贸n de tu texto"), key="btn_analyze_base"):
134
+ if not arc_state["base_text"].strip():
135
+ st.warning(morpho_t.get('warn_enter_text', "Ingrese un texto nuevo para analizarlo."))
136
+ else:
137
+ try:
138
+ # Procesar con spaCy
139
+ doc = nlp_models[lang_code](arc_state["base_text"])
140
+ base_arc_html = display_arc_diagram(doc)
141
+ arc_state["base_diagram"] = base_arc_html
142
+
143
+ # Guardar en Mongo
144
+ analysis = perform_advanced_morphosyntactic_analysis(
145
+ arc_state["base_text"],
146
+ nlp_models[lang_code]
147
+ )
148
+ base_id = store_student_morphosyntax_base(
149
+ username=st.session_state.username,
150
+ text=arc_state["base_text"],
151
+ arc_diagrams=analysis["arc_diagrams"]
152
+ )
153
+ if base_id:
154
+ arc_state["base_id"] = base_id
155
+ saved_msg = morpho_t.get('analysis_base_saved', "An谩lisis base guardado. ID: {base_id}")
156
+ st.success(saved_msg.format(base_id=base_id))
157
+
158
+ except Exception as exc:
159
+ st.error(morpho_t.get('error_processing_baseline', "Error al procesar el texto inicial"))
160
+ logger.error(f"Error en an谩lisis base: {str(exc)}")
161
+
162
+ # Bot贸n para iniciar nuevo an谩lisis
163
+ if st.button(morpho_t.get('btn_new_morpho_analysis', "Nuevo an谩lisis morfosint谩tico"), key="btn_reset_base"):
164
+ # Si fuera necesario recargar la app por completo:
165
+ # st.experimental_rerun()
166
+ reset_arc_analysis_state()
167
+
168
+ # Mostrar diagrama base
169
+ if arc_state["base_diagram"]:
170
+ st.markdown("<hr class='divider'>", unsafe_allow_html=True)
171
+ st.markdown(f"#### {morpho_t.get('arc_diagram_baseline_label', 'Diagrama de arco del texto inicial')}")
172
+ st.write(arc_state["base_diagram"], unsafe_allow_html=True)
173
+ else:
174
+ if arc_state["base_text"].strip():
175
+ # Solo mostrar si ya hay texto base pero no se ha procesado
176
+ st.info(morpho_t.get('baseline_diagram_not_available', "Diagrama de arco del texto inicial no disponible."))
177
+
178
+ # ================== PESTA脩A 2: Iteraciones ==========================
179
+ with tabs[1]:
180
+ #st.subheader(morpho_t.get('iteration_text_subheader', "Nueva versi贸n del texto inicial"))
181
+
182
+ # Verificar que exista un texto base
183
+ if not arc_state["base_id"]:
184
+ st.info(morpho_t.get('info_first_analyze_base',
185
+ "Verifica la existencia de un texto anterior."))
186
+ return
187
+
188
+ # --- 1) Mostrar SIEMPRE el diagrama base arriba ---
189
+ st.markdown(f"#### {morpho_t.get('arc_diagram_base_label', 'Diagrama de arco del texto inicial')}")
190
+ if arc_state["base_diagram"]:
191
+ st.write(arc_state["base_diagram"], unsafe_allow_html=True)
192
+ else:
193
+ st.info(morpho_t.get('baseline_diagram_not_available', "Diagrama de arco del texto inicial no disponible."))
194
+
195
+ # --- 2) Caja de texto para la iteraci贸n ---
196
+ st.markdown("<hr class='divider'>", unsafe_allow_html=True)
197
+ #st.subheader(morpho_t.get('iteration_text_subheader', "Ingresa una nueva versi贸n del texto inicial y compara los arcos de ambos textos"))
198
+
199
+ arc_state["iteration_text"] = st.text_area(
200
+ morpho_t.get('input_iteration_text', "Ingresa una nueva versi贸n del texto inicial y compara los arcos de ambos textos"),
201
+ value=arc_state["iteration_text"],
202
+ height=150
203
+ )
204
+
205
+ # Bot贸n para analizar iteraci贸n
206
+ if st.button(morpho_t.get('btn_analyze_iteration', "Analizar Cambios"), key="btn_analyze_iteration"):
207
+ if not arc_state["iteration_text"].strip():
208
+ st.warning(morpho_t.get('warn_enter_iteration_text', "Ingresa una nueva versi贸n del texto inicial y compara los arcos de ambos textos."))
209
+ else:
210
+ try:
211
+ # Procesar con spaCy
212
+ doc_iter = nlp_models[lang_code](arc_state["iteration_text"])
213
+ arc_html_iter = display_arc_diagram(doc_iter)
214
+ arc_state["iteration_diagram"] = arc_html_iter
215
+
216
+ # Guardar en Mongo
217
+ analysis_iter = perform_advanced_morphosyntactic_analysis(
218
+ arc_state["iteration_text"],
219
+ nlp_models[lang_code]
220
+ )
221
+ iteration_id = store_student_morphosyntax_iteration(
222
+ username=st.session_state.username,
223
+ base_id=arc_state["base_id"],
224
+ original_text=arc_state["base_text"],
225
+ iteration_text=arc_state["iteration_text"],
226
+ arc_diagrams=analysis_iter["arc_diagrams"]
227
+ )
228
+ if iteration_id:
229
+ saved_iter_msg = morpho_t.get('iteration_saved', "Cambios guardados correctamente. ID: {iteration_id}")
230
+ st.success(saved_iter_msg.format(iteration_id=iteration_id))
231
+
232
+ except Exception as exc:
233
+ st.error(morpho_t.get('error_iteration', "Error procesando los nuevos cambios"))
234
+ logger.error(f"Error en iteraci贸n: {str(exc)}")
235
+
236
+
237
+ # --- 3) Mostrar diagrama de iteraci贸n debajo ---
238
+ if arc_state["iteration_diagram"]:
239
+ st.markdown("<hr class='divider'>", unsafe_allow_html=True)
240
+ st.markdown(f"#### {morpho_t.get('arc_diagram_iteration_label', 'Diagrama de Arco (Iteraci贸n)')}")
241
+ st.write(arc_state["iteration_diagram"], unsafe_allow_html=True)