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