|
|
|
import streamlit as st |
|
import logging |
|
from datetime import datetime, timezone |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
from .semantic_process import process_semantic_input |
|
from ..database.semantic_mongo_live_db import store_student_semantic_live_result |
|
|
|
def display_semantic_live_interface(lang_code, nlp_models, semantic_t): |
|
""" |
|
Interfaz para el análisis semántico en vivo con texto directo |
|
""" |
|
try: |
|
|
|
if 'semantic_live_state' not in st.session_state: |
|
st.session_state.semantic_live_state = { |
|
'analysis_count': 0, |
|
'current_text': '', |
|
'last_result': None, |
|
'text_changed': False |
|
} |
|
|
|
|
|
def on_text_change(): |
|
current_text = st.session_state.semantic_live_text |
|
st.session_state.semantic_live_state['current_text'] = current_text |
|
st.session_state.semantic_live_state['text_changed'] = True |
|
|
|
|
|
st.subheader(semantic_t.get('enter_text', 'Ingrese su texto')) |
|
|
|
text_input = st.text_area( |
|
semantic_t.get('text_input_label', 'Escriba o pegue su texto aquí'), |
|
height=300, |
|
key="semantic_live_text", |
|
value=st.session_state.semantic_live_state.get('current_text', ''), |
|
on_change=on_text_change, |
|
label_visibility="collapsed" |
|
) |
|
|
|
|
|
analyze_button = st.button( |
|
semantic_t.get('analyze_button', 'Analizar'), |
|
key="semantic_live_analyze", |
|
type="primary", |
|
disabled=not text_input, |
|
use_container_width=True |
|
) |
|
|
|
|
|
if analyze_button and text_input: |
|
with st.spinner(semantic_t.get('processing', 'Procesando...')): |
|
try: |
|
analysis_result = process_semantic_input( |
|
text_input, |
|
lang_code, |
|
nlp_models, |
|
semantic_t |
|
) |
|
|
|
if analysis_result['success']: |
|
|
|
st.session_state.semantic_live_state['last_result'] = analysis_result |
|
st.session_state.semantic_live_state['analysis_count'] += 1 |
|
st.session_state.semantic_live_state['text_changed'] = False |
|
|
|
|
|
store_result = store_student_semantic_live_result( |
|
st.session_state.username, |
|
text_input, |
|
analysis_result['analysis'], |
|
lang_code |
|
) |
|
|
|
if not store_result: |
|
st.error(semantic_t.get('error_saving', 'Error al guardar el análisis')) |
|
else: |
|
st.success(semantic_t.get('analysis_saved', 'Análisis guardado correctamente')) |
|
else: |
|
st.error(analysis_result.get('message', 'Error en el análisis')) |
|
|
|
except Exception as e: |
|
logger.error(f"Error en análisis: {str(e)}") |
|
st.error(semantic_t.get('error_processing', 'Error al procesar el texto')) |
|
|
|
|
|
if 'last_result' in st.session_state.semantic_live_state and \ |
|
st.session_state.semantic_live_state['last_result'] is not None: |
|
|
|
analysis = st.session_state.semantic_live_state['last_result']['analysis'] |
|
|
|
if 'key_concepts' in analysis and analysis['key_concepts'] and \ |
|
'concept_graph' in analysis and analysis['concept_graph'] is not None: |
|
|
|
|
|
st.subheader(semantic_t.get('key_concepts', 'Conceptos Clave')) |
|
concepts_html = """ |
|
<div style="display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px;"> |
|
""" + ''.join([ |
|
f'<div style="background-color: #f0f2f6; border-radius: 5px; padding: 6px 10px; display: inline-flex; align-items: center; gap: 6px;">' |
|
f'<span style="font-weight: bold;">{concept}</span>' |
|
f'<span style="color: #666; font-size: 0.9em;">({freq:.2f})</span></div>' |
|
for concept, freq in analysis['key_concepts'] |
|
]) + "</div>" |
|
st.markdown(concepts_html, unsafe_allow_html=True) |
|
|
|
|
|
st.subheader(semantic_t.get('concept_network', 'Red de Conceptos')) |
|
st.image( |
|
analysis['concept_graph'], |
|
use_container_width=True |
|
) |
|
|
|
|
|
if st.button("💬 Consultar con Asistente", key="semantic_live_chat_button"): |
|
if 'last_result' not in st.session_state.semantic_live_state: |
|
st.error("Primero complete el análisis semántico") |
|
return |
|
|
|
st.session_state.semantic_agent_data = { |
|
'text': st.session_state.semantic_live_state['current_text'], |
|
'metrics': st.session_state.semantic_live_state['last_result']['analysis'], |
|
'graph_data': st.session_state.semantic_live_state['last_result']['analysis'].get('concept_graph') |
|
} |
|
st.session_state.semantic_agent_active = True |
|
st.rerun() |
|
|
|
|
|
if st.session_state.get('semantic_agent_active', False): |
|
st.success(semantic_t.get('semantic_agent_ready_message', 'El agente virtual está listo. Abre el chat en la barra lateral.')) |
|
else: |
|
st.info(semantic_t.get('no_results', 'No hay resultados para mostrar')) |
|
|
|
except Exception as e: |
|
logger.error(f"Error general en interfaz semántica en vivo: {str(e)}") |
|
st.error(semantic_t.get('general_error', "Se produjo un error. Por favor, intente de nuevo.")) |