AIdeaText commited on
Commit
254eff8
1 Parent(s): dab631e

Upload 9 files

Browse files
Files changed (8) hide show
  1. 23-7-2024_app.py +62 -0
  2. Test_app.py +8 -0
  3. app.py +149 -155
  4. old_app.py +464 -0
  5. research_cosmos_database.py +38 -0
  6. session_state.py +28 -0
  7. setup_logging.py +29 -0
  8. update_cosmos_index.py +46 -0
23-7-2024_app.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## app.py
2
+ import sys
3
+ import os
4
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
5
+
6
+ import streamlit as st
7
+ from modules.database import initialize_mongodb_connection, get_student_data, store_analysis_result
8
+ from modules.auth import authenticate_user, get_user_role
9
+ from modules.ui import login_page, register_page, display_chat_interface, display_student_progress, display_text_analysis_interface
10
+ from modules.morpho_analysis import get_repeated_words_colors, highlight_repeated_words, POS_COLORS, POS_TRANSLATIONS
11
+ from modules.syntax_analysis import visualize_syntax
12
+ from modules.spacy_utils import load_spacy_models
13
+
14
+ st.set_page_config(page_title="AIdeaText", layout="wide", page_icon="random")
15
+
16
+ def main_app():
17
+ nlp_models = load_spacy_models()
18
+
19
+ languages = {'Español': 'es', 'English': 'en', 'Français': 'fr'}
20
+ selected_lang = st.sidebar.selectbox("Select Language / Seleccione el idioma / Choisissez la langue", list(languages.keys()))
21
+ lang_code = languages[selected_lang]
22
+
23
+ col1, col2 = st.columns([1, 2])
24
+
25
+ with col1:
26
+ display_chat_interface()
27
+
28
+ with col2:
29
+ st.markdown("### AIdeaText - Análisis morfológico y sintáctico")
30
+
31
+ if st.session_state.role == "Estudiante":
32
+ tabs = st.tabs(["Análisis de Texto", "Mi Progreso"])
33
+ with tabs[0]:
34
+ display_text_analysis_interface(nlp_models, lang_code)
35
+ with tabs[1]:
36
+ display_student_progress(st.session_state.username)
37
+ elif st.session_state.role == "Profesor":
38
+ st.write("Bienvenido, profesor. Aquí podrás ver el progreso de tus estudiantes.")
39
+ # Agregar lógica para mostrar el progreso de los estudiantes
40
+
41
+ def main():
42
+ if not initialize_mongodb_connection():
43
+ st.warning("La conexión a la base de datos MongoDB no está disponible. Algunas funciones pueden no estar operativas.")
44
+
45
+ if 'logged_in' not in st.session_state:
46
+ st.session_state.logged_in = False
47
+
48
+ if not st.session_state.logged_in:
49
+ menu = ["Iniciar Sesión", "Registrarse"]
50
+ choice = st.sidebar.selectbox("Menu", menu)
51
+ if choice == "Iniciar Sesión":
52
+ login_page()
53
+ elif choice == "Registrarse":
54
+ register_page()
55
+ else:
56
+ if st.sidebar.button("Cerrar Sesión"):
57
+ st.session_state.logged_in = False
58
+ st.rerun()
59
+ main_app()
60
+
61
+ if __name__ == "__main__":
62
+ main()
Test_app.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def main():
4
+ st.title("Test de Streamlit")
5
+ st.write("Si puedes ver esto, Streamlit está funcionando correctamente.")
6
+
7
+ if __name__ == "__main__":
8
+ main()
app.py CHANGED
@@ -1,156 +1,150 @@
1
- #app.py de v3
2
- #app.py
3
- import logging
4
- import streamlit as st
5
- import sys
6
- import os
7
- from dotenv import load_dotenv
8
- from datetime import datetime
9
-
10
- def setup_logging():
11
- log_dir = 'logs'
12
- if not os.path.exists(log_dir):
13
- os.makedirs(log_dir)
14
- current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
15
- log_filename = f'{log_dir}/app_log_{current_time}.txt'
16
- logging.basicConfig(
17
- level=logging.DEBUG,
18
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
19
- filename=log_filename,
20
- filemode='w'
21
- )
22
- console = logging.StreamHandler()
23
- console.setLevel(logging.INFO)
24
- formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
25
- console.setFormatter(formatter)
26
- logging.getLogger('').addHandler(console)
27
- logging.info(f"Logging iniciado. Archivo de log: {log_filename}")
28
-
29
- # Configuración de la página de Streamlit
30
- # st.set_page_config(page_title="AIdeaText", layout="wide", page_icon="random")
31
-
32
- # Agregar el directorio actual al path de Python
33
- current_dir = os.path.dirname(os.path.abspath(__file__))
34
- sys.path.append(current_dir)
35
-
36
- # Configurar logging
37
- setup_logging()
38
-
39
- # Cargar variables de entorno
40
- load_dotenv()
41
-
42
- #########IMPORTACIONES LOCALES#######################################
43
- from translations import get_translations
44
-
45
- # from session_state import initialize_session_state
46
-
47
- from modules.ui.ui import main as ui_main
48
-
49
- from modules.utils.spacy_utils import load_spacy_models
50
-
51
- from modules.morphosyntax.morphosyntax_interface import (
52
- display_morphosyntax_interface
53
- )
54
-
55
- ###Importaciones de la base de datos###
56
- from modules.database.database_init import (
57
- initialize_database_connections
58
- )
59
-
60
- from modules.database.sql_db import (
61
- create_student_user,
62
- get_student_user,
63
- update_student_user,
64
- delete_student_user,
65
- store_application_request,
66
- store_student_feedback
67
- )
68
-
69
-
70
- from modules.database.mongo_db import (
71
- get_collection,
72
- insert_document,
73
- find_documents,
74
- update_document,
75
- delete_document
76
- )
77
-
78
- from modules.database.morphosintax_mongo_db import (
79
- store_student_morphosyntax_result,
80
- get_student_morphosyntax_analysis
81
- )
82
-
83
- from modules.database.chat_db import (
84
- store_chat_history,
85
- get_chat_history
86
- )
87
-
88
- from modules.studentact.student_activities_v2 import (
89
- display_student_progress
90
- )
91
-
92
- from modules.auth.auth import (
93
- authenticate_student,
94
- register_student,
95
- update_student_info,
96
- delete_student
97
- )
98
-
99
- from modules.admin.admin_ui import admin_page
100
-
101
- from modules.chatbot.chatbot import (
102
- initialize_chatbot,
103
- process_chat_input
104
- )
105
-
106
- print("Configurando página")
107
- st.cache_data.clear()
108
- st.cache_resource.clear()
109
-
110
- logging.basicConfig(level=logging.INFO)
111
- logger = logging.getLogger(__name__)
112
-
113
- @st.cache_resource
114
- def initialize_nlp_models():
115
- logger.info("Cargando modelos de spaCy")
116
- models = load_spacy_models()
117
- logger.info("Modelos de spaCy cargados exitosamente")
118
- return models
119
-
120
- def app_main():
121
- try:
122
- logger.info("Entrando en app_main()")
123
-
124
- # Inicializar el estado de la sesión
125
- initialize_session_state()
126
-
127
- # Inicializar conexiones a bases de datos si no se ha hecho
128
- if 'db_initialized' not in st.session_state:
129
- st.session_state.db_initialized = initialize_database_connections()
130
-
131
- # Cargar modelos NLP si no se ha hecho
132
- if 'nlp_models' not in st.session_state:
133
- logger.info("Inicializando modelos NLP en la sesión")
134
- st.session_state.nlp_models = initialize_nlp_models()
135
- logger.info("Modelos NLP inicializados y almacenados en la sesión")
136
-
137
- # Configurar la página inicial si no está configurada
138
- if 'page' not in st.session_state:
139
- st.session_state.page = 'login'
140
-
141
- logger.info(f"Página actual: {st.session_state.page}")
142
- logger.info(f"Rol del usuario: {st.session_state.role}")
143
-
144
- # Dirigir el flujo a la interfaz de usuario principal
145
- logger.info(f"Llamando a ui_main() desde app_main()")
146
- ui_main()
147
-
148
- except Exception as e:
149
- logger.error(f"Error en app_main: {str(e)}", exc_info=True)
150
- st.error("Se ha producido un error en la aplicación. Por favor, inténtelo de nuevo más tarde.")
151
- if st.button("Reiniciar aplicación"):
152
- st.rerun()
153
-
154
- if __name__ == "__main__":
155
- print("Llamando a app_main()")
156
  app_main()
 
1
+ #app.py de v3
2
+ #app.py
3
+ import logging
4
+ import streamlit as st
5
+ import sys
6
+ import os
7
+ from dotenv import load_dotenv
8
+ from datetime import datetime
9
+
10
+ def setup_logging():
11
+ log_dir = 'logs'
12
+ if not os.path.exists(log_dir):
13
+ os.makedirs(log_dir)
14
+ current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
15
+ log_filename = f'{log_dir}/app_log_{current_time}.txt'
16
+ logging.basicConfig(
17
+ level=logging.DEBUG,
18
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
19
+ filename=log_filename,
20
+ filemode='w'
21
+ )
22
+ console = logging.StreamHandler()
23
+ console.setLevel(logging.INFO)
24
+ formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
25
+ console.setFormatter(formatter)
26
+ logging.getLogger('').addHandler(console)
27
+ logging.info(f"Logging iniciado. Archivo de log: {log_filename}")
28
+
29
+ setup_logging()
30
+ load_dotenv()
31
+
32
+ st.set_page_config(page_title="AIdeaText", layout="wide", page_icon="random")
33
+
34
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
35
+
36
+ #########IMPORTACIONES LOCALES#######################################
37
+ from translations import get_translations
38
+
39
+ from session_state import initialize_session_state
40
+
41
+ from modules.ui.ui import main as ui_main
42
+
43
+ from modules.utils.spacy_utils import load_spacy_models
44
+
45
+ from modules.morphosyntax.morphosyntax_interface import (
46
+ display_morphosyntax_interface
47
+ )
48
+
49
+ ###Importaciones de la base de datos###
50
+ from modules.database.database_init import (
51
+ initialize_database_connections
52
+ )
53
+
54
+ from modules.database.sql_db import (
55
+ create_student_user,
56
+ get_student_user,
57
+ update_student_user,
58
+ delete_student_user,
59
+ store_application_request,
60
+ store_student_feedback
61
+ )
62
+
63
+
64
+ from modules.database.mongo_db import (
65
+ get_collection,
66
+ insert_document,
67
+ find_documents,
68
+ update_document,
69
+ delete_document
70
+ )
71
+
72
+ from modules.database.morphosintax_mongo_db import (
73
+ store_student_morphosyntax_result,
74
+ get_student_morphosyntax_analysis
75
+ )
76
+
77
+ from modules.database.chat_db import (
78
+ store_chat_history,
79
+ get_chat_history
80
+ )
81
+
82
+ from modules.studentact.student_activities_v2 import (
83
+ display_student_progress
84
+ )
85
+
86
+ from modules.auth.auth import (
87
+ authenticate_student,
88
+ register_student,
89
+ update_student_info,
90
+ delete_student
91
+ )
92
+
93
+ from modules.admin.admin_ui import admin_page
94
+
95
+ from modules.chatbot.chatbot import (
96
+ initialize_chatbot,
97
+ process_chat_input
98
+ )
99
+
100
+ print("Configurando página")
101
+ st.cache_data.clear()
102
+ st.cache_resource.clear()
103
+
104
+ logging.basicConfig(level=logging.INFO)
105
+ logger = logging.getLogger(__name__)
106
+
107
+ @st.cache_resource
108
+ def initialize_nlp_models():
109
+ logger.info("Cargando modelos de spaCy")
110
+ models = load_spacy_models()
111
+ logger.info("Modelos de spaCy cargados exitosamente")
112
+ return models
113
+
114
+ def app_main():
115
+ try:
116
+ logger.info("Entrando en app_main()")
117
+
118
+ # Inicializar el estado de la sesión
119
+ initialize_session_state()
120
+
121
+ # Inicializar conexiones a bases de datos si no se ha hecho
122
+ if 'db_initialized' not in st.session_state:
123
+ st.session_state.db_initialized = initialize_database_connections()
124
+
125
+ # Cargar modelos NLP si no se ha hecho
126
+ if 'nlp_models' not in st.session_state:
127
+ logger.info("Inicializando modelos NLP en la sesión")
128
+ st.session_state.nlp_models = initialize_nlp_models()
129
+ logger.info("Modelos NLP inicializados y almacenados en la sesión")
130
+
131
+ # Configurar la página inicial si no está configurada
132
+ if 'page' not in st.session_state:
133
+ st.session_state.page = 'login'
134
+
135
+ logger.info(f"Página actual: {st.session_state.page}")
136
+ logger.info(f"Rol del usuario: {st.session_state.role}")
137
+
138
+ # Dirigir el flujo a la interfaz de usuario principal
139
+ logger.info(f"Llamando a ui_main() desde app_main()")
140
+ ui_main()
141
+
142
+ except Exception as e:
143
+ logger.error(f"Error en app_main: {str(e)}", exc_info=True)
144
+ st.error("Se ha producido un error en la aplicación. Por favor, inténtelo de nuevo más tarde.")
145
+ if st.button("Reiniciar aplicación"):
146
+ st.rerun()
147
+
148
+ if __name__ == "__main__":
149
+ print("Llamando a app_main()")
 
 
 
 
 
 
150
  app_main()
old_app.py ADDED
@@ -0,0 +1,464 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #old.app.py
2
+
3
+ import logging
4
+ import datetime
5
+ import io
6
+ import base64
7
+ import os
8
+ import streamlit as st
9
+ import spacy
10
+ from spacy import displacy
11
+ import re
12
+ import numpy as np
13
+ import certifi
14
+ #from transformers import BlenderbotTokenizer, BlenderbotForConditionalGeneration
15
+ from azure.cosmos import CosmosClient
16
+ from azure.cosmos.exceptions import CosmosHttpResponseError
17
+ from pymongo import MongoClient
18
+ from pymongo.server_api import ServerApi
19
+ from bson.objectid import ObjectId
20
+ from datetime import datetime
21
+
22
+ logging.basicConfig(level=logging.DEBUG)
23
+ logger = logging.getLogger(__name__)
24
+
25
+ from dotenv import load_dotenv
26
+ load_dotenv()
27
+
28
+ from modules.auth import (
29
+ clean_and_validate_key,
30
+ register_user,
31
+ authenticate_user,
32
+ get_user_role
33
+ )
34
+
35
+ from modules.morpho_analysis import get_repeated_words_colors, highlight_repeated_words, POS_COLORS, POS_TRANSLATIONS
36
+ from modules.syntax_analysis import visualize_syntax
37
+
38
+ # Azure Cosmos DB configuration
39
+ cosmos_endpoint = os.environ.get("COSMOS_ENDPOINT")
40
+ cosmos_key = os.environ.get("COSMOS_KEY")
41
+
42
+ if not cosmos_endpoint or not cosmos_key:
43
+ raise ValueError("Las variables de entorno COSMOS_ENDPOINT y COSMOS_KEY deben estar configuradas")
44
+
45
+ try:
46
+ cosmos_key = clean_and_validate_key(cosmos_key)
47
+ cosmos_client = CosmosClient(cosmos_endpoint, cosmos_key)
48
+
49
+ # SQL API database for user management
50
+ user_database = cosmos_client.get_database_client("user_database")
51
+ user_container = user_database.get_container_client("users")
52
+
53
+ print("Conexión a Cosmos DB SQL API exitosa")
54
+ except Exception as e:
55
+ print(f"Error al conectar con Cosmos DB SQL API: {str(e)}")
56
+ raise
57
+
58
+ # MongoDB API configuration for text analysis results
59
+ #mongo_connection_string = os.environ.get("MONGODB_CONNECTION_STRING")
60
+ cosmos_mongodb_connection_string = os.getenv("MONGODB_CONNECTION_STRING")
61
+ if not cosmos_mongodb_connection_string:
62
+ logger.error("La variable de entorno MONGODB_CONNECTION_STRING no está configurada")
63
+ else:
64
+ logger.info("La variable de entorno MONGODB_CONNECTION_STRING está configurada")
65
+
66
+ # Variable global para el cliente de MongoDB
67
+ mongo_client = None
68
+ db = None
69
+ analysis_collection = None
70
+ ####################################################################################################################
71
+ def initialize_mongodb_connection():
72
+ global mongo_client, db, analysis_collection
73
+ try:
74
+ # Crear el cliente de MongoDB con configuración TLS
75
+ mongo_client = MongoClient(cosmos_mongodb_connection_string,
76
+ tls=True,
77
+ tlsCAFile=certifi.where(),
78
+ retryWrites=False,
79
+ serverSelectionTimeoutMS=5000,
80
+ connectTimeoutMS=10000,
81
+ socketTimeoutMS=10000)
82
+
83
+ # Forzar una conexión para verificar
84
+ mongo_client.admin.command('ping')
85
+
86
+ # Seleccionar la base de datos y la colección
87
+ db = mongo_client['aideatext_db']
88
+ analysis_collection = db['text_analysis']
89
+
90
+ logger.info("Conexión a Cosmos DB MongoDB API exitosa")
91
+ return True
92
+ except Exception as e:
93
+ logger.error(f"Error al conectar con Cosmos DB MongoDB API: {str(e)}", exc_info=True)
94
+ return False
95
+
96
+ ##################################################################################################################3
97
+ def get_student_data(username):
98
+ if analysis_collection is None:
99
+ logger.error("La conexión a MongoDB no está inicializada")
100
+ return None
101
+
102
+ try:
103
+ # Buscar los datos del estudiante
104
+ student_data = analysis_collection.find({"username": username}).sort("timestamp", -1)
105
+
106
+ if not student_data:
107
+ return None
108
+
109
+ # Formatear los datos
110
+ formatted_data = {
111
+ "username": username,
112
+ "entries": [],
113
+ "entries_count": 0,
114
+ "word_count": {},
115
+ "arc_diagrams": [],
116
+ "network_diagrams": []
117
+ }
118
+
119
+ for entry in student_data:
120
+ formatted_data["entries"].append({
121
+ "timestamp": entry["timestamp"].isoformat(),
122
+ "text": entry["text"]
123
+ })
124
+ formatted_data["entries_count"] += 1
125
+
126
+ # Agregar conteo de palabras
127
+ for category, count in entry.get("word_count", {}).items():
128
+ if category in formatted_data["word_count"]:
129
+ formatted_data["word_count"][category] += count
130
+ else:
131
+ formatted_data["word_count"][category] = count
132
+
133
+ # Agregar diagramas
134
+ formatted_data["arc_diagrams"].extend(entry.get("arc_diagrams", []))
135
+ formatted_data["network_diagrams"].append(entry.get("network_diagram", ""))
136
+
137
+ return formatted_data
138
+ except Exception as e:
139
+ logger.error(f"Error al obtener datos del estudiante {username}: {str(e)}")
140
+ return None
141
+
142
+
143
+ ##################################################################################################################
144
+ # Función para insertar un documento
145
+ def insert_document(document):
146
+ try:
147
+ result = analysis_collection.insert_one(document)
148
+ logger.info(f"Documento insertado con ID: {result.inserted_id}")
149
+ return result.inserted_id
150
+ except Exception as e:
151
+ logger.error(f"Error al insertar documento: {str(e)}", exc_info=True)
152
+ return None
153
+
154
+ # Configure the page to use the full width
155
+ st.set_page_config(
156
+ page_title="AIdeaText",
157
+ layout="wide",
158
+ page_icon="random"
159
+ )
160
+ #####################################################################################################
161
+ @st.cache_resource
162
+ def load_chatbot_model():
163
+ try:
164
+ from transformers import BlenderbotTokenizer, BlenderbotForConditionalGeneration
165
+ tokenizer = BlenderbotTokenizer.from_pretrained("facebook/blenderbot-400M-distill")
166
+ model = BlenderbotForConditionalGeneration.from_pretrained("facebook/blenderbot-400M-distill")
167
+ return tokenizer, model
168
+ except Exception as e:
169
+ logger.error(f"Error al cargar el modelo del chatbot: {str(e)}")
170
+ return None, None
171
+
172
+ # Load the chatbot model
173
+ chatbot_tokenizer, chatbot_model = load_chatbot_model()
174
+
175
+ def get_chatbot_response(input_text):
176
+ if chatbot_tokenizer is None or chatbot_model is None:
177
+ return "Lo siento, el chatbot no está disponible en este momento."
178
+ try:
179
+ inputs = chatbot_tokenizer(input_text, return_tensors="pt")
180
+ reply_ids = chatbot_model.generate(**inputs)
181
+ return chatbot_tokenizer.batch_decode(reply_ids, skip_special_tokens=True)[0]
182
+ except Exception as e:
183
+ logger.error(f"Error al generar respuesta del chatbot: {str(e)}")
184
+ return "Lo siento, hubo un error al procesar tu mensaje."
185
+ ########################################################################################################
186
+ def load_spacy_models():
187
+ return {
188
+ 'es': spacy.load("es_core_news_lg"),
189
+ 'en': spacy.load("en_core_web_lg"),
190
+ 'fr': spacy.load("fr_core_news_lg")
191
+ }
192
+ #########################################################################################################
193
+ def store_analysis_result(username, text, repeated_words, arc_diagrams, network_diagram):
194
+ if analysis_collection is None:
195
+ logging.error("La conexión a MongoDB no está inicializada")
196
+ return False
197
+
198
+ try:
199
+ # Convertir el gráfico de matplotlib a base64
200
+ buffer = io.BytesIO()
201
+ network_diagram.savefig(buffer, format='png')
202
+ buffer.seek(0)
203
+ network_diagram_base64 = base64.b64encode(buffer.getvalue()).decode()
204
+
205
+ # Contar palabras repetidas por categoría gramatical
206
+ word_count = {}
207
+ for word, color in repeated_words.items():
208
+ category = POS_TRANSLATIONS.get(color, 'Otros')
209
+ word_count[category] = word_count.get(category, 0) + 1
210
+
211
+ # Crear el documento para MongoDB
212
+ analysis_document = {
213
+ 'username': username, # Este campo se usará como sharded key
214
+ 'timestamp': datetime.datetime.utcnow(),
215
+ 'text': text,
216
+ 'word_count': word_count,
217
+ 'arc_diagrams': arc_diagrams,
218
+ 'network_diagram': network_diagram_base64
219
+ }
220
+
221
+ # Insertar el documento en la colección
222
+ result = analysis_collection.insert_one(analysis_document)
223
+
224
+ logging.info(f"Análisis guardado con ID: {result.inserted_id} para el usuario: {username}")
225
+ return True
226
+ except Exception as e:
227
+ logging.error(f"Error al guardar el análisis para el usuario {username}: {str(e)}")
228
+ return False
229
+
230
+ #############################################################################################33
231
+ def login_page():
232
+ st.title("Iniciar Sesión")
233
+ username = st.text_input("Usuario")
234
+ password = st.text_input("Contraseña", type='password')
235
+ if st.button("Iniciar Sesión"):
236
+ if authenticate_user(username, password):
237
+ st.success(f"Bienvenido, {username}!")
238
+ st.session_state.logged_in = True
239
+ st.session_state.username = username
240
+ st.session_state.role = get_user_role(username)
241
+ st.experimental_rerun()
242
+ else:
243
+ st.error("Usuario o contraseña incorrectos")
244
+
245
+ #####################################################################################################3
246
+ def register_page():
247
+ st.title("Registrarse")
248
+ new_username = st.text_input("Nuevo Usuario")
249
+ new_password = st.text_input("Nueva Contraseña", type='password')
250
+ role = st.selectbox("Rol", ["Estudiante", "Profesor"])
251
+
252
+ additional_info = {}
253
+ if role == "Estudiante":
254
+ additional_info['carrera'] = st.text_input("Carrera")
255
+ elif role == "Profesor":
256
+ additional_info['departamento'] = st.text_input("Departamento")
257
+
258
+ if st.button("Registrarse"):
259
+ if register_user(new_username, new_password, role, additional_info):
260
+ st.success("Registro exitoso. Por favor, inicia sesión.")
261
+ else:
262
+ st.error("El usuario ya existe o ocurrió un error durante el registro")
263
+
264
+ ############################################################################################
265
+ def main_app():
266
+ # Load spaCy models
267
+ nlp_models = load_spacy_models()
268
+
269
+ # Language selection
270
+ languages = {
271
+ 'Español': 'es',
272
+ 'English': 'en',
273
+ 'Français': 'fr'
274
+ }
275
+ selected_lang = st.sidebar.selectbox("Select Language / Seleccione el idioma / Choisissez la langue", list(languages.keys()))
276
+ lang_code = languages[selected_lang]
277
+
278
+ # Translations
279
+ translations = {
280
+ 'es': {
281
+ 'title': "AIdeaText - Análisis morfológico y sintáctico",
282
+ 'input_label': "Ingrese un texto para analizar (máx. 5,000 palabras):",
283
+ 'input_placeholder': "El objetivo de esta aplicación es que mejore sus habilidades de redacción. Para ello, después de ingresar su texto y presionar el botón obtendrá tres vistas horizontales. La primera, le indicará las palabras que se repiten por categoría gramátical; la segunda, un diagrama de arco le indicara las conexiones sintácticas en cada oración; y la tercera, es un grafo en el cual visualizara la configuración de su texto.",
284
+ 'analyze_button': "Analizar texto",
285
+ 'repeated_words': "Palabras repetidas",
286
+ 'legend': "Leyenda: Categorías gramaticales",
287
+ 'arc_diagram': "Análisis sintáctico: Diagrama de arco",
288
+ 'network_diagram': "Análisis sintáctico: Diagrama de red",
289
+ 'sentence': "Oración"
290
+ },
291
+ 'en': {
292
+ 'title': "AIdeaText - Morphological and Syntactic Analysis",
293
+ 'input_label': "Enter a text to analyze (max 5,000 words):",
294
+ 'input_placeholder': "The goal of this app is for you to improve your writing skills. To do this, after entering your text and pressing the button you will get three horizontal views. The first will indicate the words that are repeated by grammatical category; second, an arc diagram will indicate the syntactic connections in each sentence; and the third is a graph in which you will visualize the configuration of your text.",
295
+ 'analyze_button': "Analyze text",
296
+ 'repeated_words': "Repeated words",
297
+ 'legend': "Legend: Grammatical categories",
298
+ 'arc_diagram': "Syntactic analysis: Arc diagram",
299
+ 'network_diagram': "Syntactic analysis: Network diagram",
300
+ 'sentence': "Sentence"
301
+ },
302
+ 'fr': {
303
+ 'title': "AIdeaText - Analyse morphologique et syntaxique",
304
+ 'input_label': "Entrez un texte à analyser (max 5 000 mots) :",
305
+ 'input_placeholder': "Le but de cette application est d'améliorer vos compétences en rédaction. Pour ce faire, après avoir saisi votre texte et appuyé sur le bouton vous obtiendrez trois vues horizontales. Le premier indiquera les mots répétés par catégorie grammaticale; deuxièmement, un diagramme en arcs indiquera les connexions syntaxiques dans chaque phrase; et le troisième est un graphique dans lequel vous visualiserez la configuration de votre texte.",
306
+ 'analyze_button': "Analyser le texte",
307
+ 'repeated_words': "Mots répétés",
308
+ 'legend': "Légende : Catégories grammaticales",
309
+ 'arc_diagram': "Analyse syntaxique : Diagramme en arc",
310
+ 'network_diagram': "Analyse syntaxique : Diagramme de réseau",
311
+ 'sentence': "Phrase"
312
+ }
313
+ }
314
+
315
+ # Use translations
316
+ t = translations[lang_code]
317
+
318
+ # Create two columns: one for chat and one for analysis
319
+ col1, col2 = st.columns([1, 2])
320
+
321
+ with col1:
322
+ st.markdown(f"### Chat con AIdeaText")
323
+
324
+ # Initialize chat history if it doesn't exist
325
+ if 'chat_history' not in st.session_state:
326
+ st.session_state.chat_history = []
327
+
328
+ # Display chat history
329
+ for i, (role, text) in enumerate(st.session_state.chat_history):
330
+ if role == "user":
331
+ st.text_area(f"Tú:", value=text, height=50, key=f"user_message_{i}", disabled=True)
332
+ else:
333
+ st.text_area(f"AIdeaText:", value=text, height=50, key=f"bot_message_{i}", disabled=True)
334
+
335
+ # User input field
336
+ user_input = st.text_input("Escribe tu mensaje aquí:")
337
+
338
+ if st.button("Enviar"):
339
+ if user_input:
340
+ # Add user message to history
341
+ st.session_state.chat_history.append(("user", user_input))
342
+
343
+ # Get chatbot response
344
+ response = get_chatbot_response(user_input)
345
+
346
+ # Add chatbot response to history
347
+ st.session_state.chat_history.append(("bot", response))
348
+
349
+ # Clear input field
350
+ st.experimental_rerun()
351
+
352
+ with col2:
353
+ st.markdown(f"### {t['title']}")
354
+
355
+ if st.session_state.role == "Estudiante":
356
+ # Agregar un botón para ver el progreso del estudiante
357
+ if st.button("Ver mi progreso"):
358
+ student_data = get_student_data(st.session_state.username)
359
+ if student_data:
360
+ st.success("Datos obtenidos exitosamente")
361
+
362
+ # Mostrar estadísticas generales
363
+ st.subheader("Estadísticas generales")
364
+ st.write(f"Total de entradas: {student_data['entries_count']}")
365
+
366
+ # Mostrar gráfico de conteo de palabras
367
+ st.subheader("Conteo de palabras por categoría")
368
+ st.bar_chart(student_data['word_count'])
369
+
370
+ # Mostrar entradas recientes
371
+ st.subheader("Entradas recientes")
372
+ for entry in student_data['entries'][:5]: # Mostrar las 5 entradas más recientes
373
+ st.text_area(f"Entrada del {entry['timestamp']}", entry['text'], height=100)
374
+
375
+ # Aquí puedes agregar más visualizaciones según necesites
376
+ else:
377
+ st.warning("No se encontraron datos para este estudiante")
378
+
379
+ if st.session_state.role == "Estudiante":
380
+ # Student interface code
381
+ if 'input_text' not in st.session_state:
382
+ st.session_state.input_text = ""
383
+
384
+ sentence_input = st.text_area(t['input_label'], height=150, placeholder=t['input_placeholder'], value=st.session_state.input_text)
385
+ st.session_state.input_text = sentence_input
386
+
387
+ if st.button(t['analyze_button']):
388
+ if sentence_input:
389
+ doc = nlp_models[lang_code](sentence_input)
390
+
391
+ # Highlighted Repeated Words
392
+ with st.expander(t['repeated_words'], expanded=True):
393
+ word_colors = get_repeated_words_colors(doc)
394
+ highlighted_text = highlight_repeated_words(doc, word_colors)
395
+ st.markdown(highlighted_text, unsafe_allow_html=True)
396
+
397
+ # Legend for grammatical categories
398
+ st.markdown(f"##### {t['legend']}")
399
+ legend_html = "<div style='display: flex; flex-wrap: wrap;'>"
400
+ for pos, color in POS_COLORS.items():
401
+ if pos in POS_TRANSLATIONS:
402
+ legend_html += f"<div style='margin-right: 10px;'><span style='background-color: {color}; padding: 2px 5px;'>{POS_TRANSLATIONS[pos]}</span></div>"
403
+ legend_html += "</div>"
404
+ st.markdown(legend_html, unsafe_allow_html=True)
405
+
406
+ # Arc Diagram
407
+ with st.expander(t['arc_diagram'], expanded=True):
408
+ sentences = list(doc.sents)
409
+ arc_diagrams = []
410
+ for i, sent in enumerate(sentences):
411
+ st.subheader(f"{t['sentence']} {i+1}")
412
+ html = displacy.render(sent, style="dep", options={"distance": 100})
413
+ html = html.replace('height="375"', 'height="200"')
414
+ html = re.sub(r'<svg[^>]*>', lambda m: m.group(0).replace('height="450"', 'height="300"'), html)
415
+ html = re.sub(r'<g [^>]*transform="translate\((\d+),(\d+)\)"', lambda m: f'<g transform="translate({m.group(1)},50)"', html)
416
+ st.write(html, unsafe_allow_html=True)
417
+ arc_diagrams.append(html)
418
+
419
+ # Network graph
420
+ with st.expander(t['network_diagram'], expanded=True):
421
+ fig = visualize_syntax(sentence_input, nlp_models[lang_code], lang_code)
422
+ st.pyplot(fig)
423
+
424
+ # Store analysis results
425
+ if store_analysis_result(
426
+ st.session_state.username,
427
+ sentence_input,
428
+ word_colors,
429
+ arc_diagrams,
430
+ fig
431
+ ):
432
+ st.success("Análisis guardado correctamente.")
433
+ else:
434
+ st.error("Hubo un problema al guardar el análisis. Por favor, inténtelo de nuevo.")
435
+ logger.error(f"Falló el guardado del análisis. Username: {st.session_state.username}")
436
+
437
+ elif st.session_state.role == "Profesor":
438
+ # Teacher interface code
439
+ st.write("Bienvenido, profesor. Aquí podrás ver el progreso de tus estudiantes.")
440
+ # Add logic to display student progress
441
+
442
+ #####################################################################################################
443
+ def main():
444
+ if not initialize_mongodb_connection():
445
+ st.warning("La conexión a la base de datos MongoDB no está disponible. Algunas funciones pueden no estar operativas.")
446
+
447
+ if 'logged_in' not in st.session_state:
448
+ st.session_state.logged_in = False
449
+
450
+ if not st.session_state.logged_in:
451
+ menu = ["Iniciar Sesión", "Registrarse"]
452
+ choice = st.sidebar.selectbox("Menu", menu)
453
+ if choice == "Iniciar Sesión":
454
+ login_page()
455
+ elif choice == "Registrarse":
456
+ register_page()
457
+ else:
458
+ if st.sidebar.button("Cerrar Sesión"):
459
+ st.session_state.logged_in = False
460
+ st.experimental_rerun()
461
+ main_app()
462
+
463
+ if __name__ == "__main__":
464
+ main()
research_cosmos_database.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from azure.cosmos import CosmosClient, exceptions
2
+ import os
3
+
4
+ def diagnose_cosmos_connection():
5
+ endpoint = os.environ.get("COSMOS_ENDPOINT")
6
+ key = os.environ.get("COSMOS_KEY")
7
+
8
+ if not all([endpoint, key]):
9
+ raise ValueError("Please ensure COSMOS_ENDPOINT and COSMOS_KEY are set.")
10
+
11
+ client = CosmosClient(endpoint, key)
12
+
13
+ print("Attempting to connect to Cosmos DB...")
14
+ try:
15
+ # List databases
16
+ print("Listing databases:")
17
+ databases = list(client.list_databases())
18
+ for db in databases:
19
+ print(f"- {db['id']}")
20
+
21
+ # Try to list containers for each database
22
+ try:
23
+ containers = list(client.get_database_client(db['id']).list_containers())
24
+ print(f" Containers in {db['id']}:")
25
+ for container in containers:
26
+ print(f" - {container['id']}")
27
+ except exceptions.CosmosResourceNotFoundError:
28
+ print(f" Unable to list containers in {db['id']}")
29
+ except Exception as e:
30
+ print(f" Error listing containers in {db['id']}: {str(e)}")
31
+
32
+ print() # Add a blank line for readability
33
+
34
+ except Exception as e:
35
+ print(f"Error: {str(e)}")
36
+
37
+ if __name__ == "__main__":
38
+ diagnose_cosmos_connection()
session_state.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def initialize_session_state():
4
+ if 'initialized' not in st.session_state:
5
+ st.session_state.clear()
6
+ st.session_state.initialized = True
7
+ st.session_state.logged_in = False
8
+ st.session_state.page = 'login'
9
+ st.session_state.username = None
10
+ st.session_state.role = None
11
+ st.session_state.lang_code = 'es'
12
+
13
+ # Inicializar la estructura para el chat morfosintáctico
14
+ if 'morphosyntax' not in st.session_state:
15
+ st.session_state.morphosyntax = {
16
+ 'chat': {
17
+ 'input': 'chatbot'
18
+ }
19
+ }
20
+
21
+ def logout():
22
+ for key in list(st.session_state.keys()):
23
+ del st.session_state[key]
24
+ initialize_session_state()
25
+ st.session_state.logged_out = True # Añadimos esta bandera
26
+
27
+ # Exportar las funciones
28
+ __all__ = ['initialize_session_state', 'logout']
setup_logging.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from datetime import datetime
3
+ import os
4
+
5
+ def setup_logging():
6
+ log_dir = 'logs'
7
+ if not os.path.exists(log_dir):
8
+ os.makedirs(log_dir)
9
+
10
+ current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
11
+ log_filename = f'{log_dir}/app_log_{current_time}.txt'
12
+
13
+ logging.basicConfig(
14
+ level=logging.DEBUG,
15
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
16
+ filename=log_filename,
17
+ filemode='w'
18
+ )
19
+
20
+ console = logging.StreamHandler()
21
+ console.setLevel(logging.INFO)
22
+ formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
23
+ console.setFormatter(formatter)
24
+ logging.getLogger('').addHandler(console)
25
+
26
+ logging.info(f"Logging iniciado. Archivo de log: {log_filename}")
27
+
28
+ if __name__ == "__main__":
29
+ setup_logging()
update_cosmos_index.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from azure.cosmos import CosmosClient, PartitionKey, exceptions
2
+ import os
3
+
4
+ def update_cosmos_indexing():
5
+ endpoint = os.environ.get("COSMOS_ENDPOINT")
6
+ key = os.environ.get("COSMOS_KEY")
7
+ database_name = "user_database" # Cambiado de "sqllink" a "user_database"
8
+ container_name = "users"
9
+
10
+ if not all([endpoint, key, database_name, container_name]):
11
+ raise ValueError("Please ensure all required parameters are set.")
12
+
13
+ client = CosmosClient(endpoint, key)
14
+ database = client.get_database_client(database_name)
15
+ container = database.get_container_client(container_name)
16
+
17
+ print(f"Updating indexing policy for container {container_name}...")
18
+
19
+ indexing_policy = {
20
+ "indexingMode": "consistent",
21
+ "automatic": True,
22
+ "includedPaths": [
23
+ {"path": "/*"}
24
+ ],
25
+ "excludedPaths": [
26
+ {"path": "/_etag/?"}
27
+ ]
28
+ }
29
+
30
+ try:
31
+ container_def = container.read()
32
+ container_def['indexingPolicy'] = indexing_policy
33
+ partition_key_path = container_def['partitionKey']['paths'][0]
34
+
35
+ database.replace_container(
36
+ container_def,
37
+ partition_key=PartitionKey(path=partition_key_path)
38
+ )
39
+ print("Indexing policy updated successfully")
40
+ except exceptions.CosmosResourceNotFoundError as e:
41
+ print(f"Error: Container not found. {str(e)}")
42
+ except Exception as e:
43
+ print(f"An error occurred: {str(e)}")
44
+
45
+ if __name__ == "__main__":
46
+ update_cosmos_indexing()