|
|
|
|
|
import streamlit as st |
|
import re |
|
import logging |
|
from spacy import displacy |
|
|
|
|
|
from ..morphosyntax.morphosyntax_process import perform_advanced_morphosyntactic_analysis |
|
from ..database.morphosyntax_iterative_mongo_db import ( |
|
store_student_morphosyntax_base, |
|
store_student_morphosyntax_iteration, |
|
) |
|
|
|
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 |
|
} |
|
) |
|
|
|
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 |
|
) |
|
|
|
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). |
|
""" |
|
|
|
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) |
|
|
|
|
|
initialize_arc_analysis_state() |
|
arc_state = st.session_state.arc_analysis_state |
|
|
|
|
|
tabs = st.tabs(["Texto Base", "Iteraciones"]) |
|
|
|
|
|
with tabs[0]: |
|
st.subheader("An谩lisis de Texto Base") |
|
|
|
|
|
if st.button("Nuevo An谩lisis", key="btn_reset_base"): |
|
|
|
|
|
reset_arc_analysis_state() |
|
|
|
|
|
arc_state["base_text"] = st.text_area( |
|
"Ingrese su texto inicial", |
|
value=arc_state["base_text"], |
|
key="base_text_input", |
|
height=150 |
|
) |
|
|
|
|
|
if st.button("Analizar Texto Base", key="btn_analyze_base"): |
|
if not arc_state["base_text"].strip(): |
|
st.warning("Ingrese un texto para analizar.") |
|
else: |
|
try: |
|
|
|
doc = nlp_models[lang_code](arc_state["base_text"]) |
|
base_arc_html = display_arc_diagram(doc) |
|
arc_state["base_diagram"] = base_arc_html |
|
|
|
|
|
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 |
|
st.success(f"An谩lisis base guardado. ID: {base_id}") |
|
|
|
except Exception as exc: |
|
st.error("Error procesando texto base") |
|
logger.error(f"Error en an谩lisis base: {str(exc)}") |
|
|
|
|
|
if arc_state["base_diagram"]: |
|
st.markdown("<hr class='divider'>", unsafe_allow_html=True) |
|
st.markdown("#### Diagrama de Arco (Texto Base)") |
|
st.write(arc_state["base_diagram"], unsafe_allow_html=True) |
|
|
|
|
|
with tabs[1]: |
|
st.subheader("An谩lisis de Cambios / Iteraciones") |
|
|
|
|
|
if not arc_state["base_id"]: |
|
st.info("Primero analiza un texto base en la pesta帽a anterior.") |
|
return |
|
|
|
|
|
st.markdown("#### Diagrama de Arco (Texto Base)") |
|
if arc_state["base_diagram"]: |
|
st.write(arc_state["base_diagram"], unsafe_allow_html=True) |
|
else: |
|
st.info("No hay diagrama base disponible.") |
|
|
|
|
|
st.markdown("<hr class='divider'>", unsafe_allow_html=True) |
|
st.subheader("Texto de Iteraci贸n") |
|
arc_state["iteration_text"] = st.text_area( |
|
"Ingrese su nueva versi贸n / iteraci贸n", |
|
value=arc_state["iteration_text"], |
|
height=150 |
|
) |
|
|
|
|
|
if st.button("Analizar Cambios", key="btn_analyze_iteration"): |
|
if not arc_state["iteration_text"].strip(): |
|
st.warning("Ingrese texto de iteraci贸n.") |
|
else: |
|
try: |
|
|
|
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 |
|
|
|
|
|
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: |
|
st.success(f"Iteraci贸n guardada. ID: {iteration_id}") |
|
|
|
except Exception as exc: |
|
st.error("Error procesando iteraci贸n") |
|
logger.error(f"Error en iteraci贸n: {str(exc)}") |
|
|
|
|
|
if arc_state["iteration_diagram"]: |
|
st.markdown("<hr class='divider'>", unsafe_allow_html=True) |
|
st.markdown("#### Diagrama de Arco (Iteraci贸n)") |
|
st.write(arc_state["iteration_diagram"], unsafe_allow_html=True) |