AIdeaText commited on
Commit
2ee7bf6
·
verified ·
1 Parent(s): 4ed3e92

Update modules/database/discourse_mongo_db.py

Browse files
Files changed (1) hide show
  1. modules/database/discourse_mongo_db.py +306 -172
modules/database/discourse_mongo_db.py CHANGED
@@ -1,173 +1,307 @@
1
- # modules/database/discourse_mongo_db.py
2
- # Importaciones estándar
3
- import io
4
- import base64
5
- from datetime import datetime, timezone
6
- import logging
7
-
8
- # Importaciones de terceros
9
- import matplotlib.pyplot as plt
10
-
11
- from .mongo_db import (
12
- get_collection,
13
- insert_document,
14
- find_documents,
15
- update_document,
16
- delete_document
17
- )
18
-
19
- # Configuración del logger
20
- logger = logging.getLogger(__name__)
21
- COLLECTION_NAME = 'student_discourse_analysis'
22
-
23
- ########################################################################
24
- def store_student_discourse_result(username, text1, text2, analysis_result):
25
- """
26
- Guarda el resultado del análisis de discurso comparativo en MongoDB.
27
- """
28
- try:
29
- # Los gráficos ya vienen en bytes, solo necesitamos codificar a base64
30
- graph1_data = None
31
- graph2_data = None
32
- combined_graph_data = None
33
-
34
- if 'graph1' in analysis_result and analysis_result['graph1'] is not None:
35
- try:
36
- graph1_data = base64.b64encode(analysis_result['graph1']).decode('utf-8')
37
- except Exception as e:
38
- logger.error(f"Error al codificar gráfico 1: {str(e)}")
39
-
40
- if 'graph2' in analysis_result and analysis_result['graph2'] is not None:
41
- try:
42
- graph2_data = base64.b64encode(analysis_result['graph2']).decode('utf-8')
43
- except Exception as e:
44
- logger.error(f"Error al codificar gráfico 2: {str(e)}")
45
-
46
- if 'combined_graph' in analysis_result and analysis_result['combined_graph'] is not None:
47
- try:
48
- combined_graph_data = base64.b64encode(analysis_result['combined_graph']).decode('utf-8')
49
- except Exception as e:
50
- logger.error(f"Error al codificar gráfico combinado: {str(e)}")
51
-
52
- # Crear documento para MongoDB
53
- analysis_document = {
54
- 'username': username,
55
- 'timestamp': datetime.now(timezone.utc).isoformat(),
56
- 'text1': text1,
57
- 'text2': text2,
58
- 'analysis_type': 'discourse',
59
- 'key_concepts1': analysis_result.get('key_concepts1', []),
60
- 'key_concepts2': analysis_result.get('key_concepts2', []),
61
- 'graph1': graph1_data,
62
- 'graph2': graph2_data,
63
- 'combined_graph': combined_graph_data
64
- }
65
-
66
- # Insertar en MongoDB
67
- result = insert_document(COLLECTION_NAME, analysis_document)
68
- if result:
69
- logger.info(f"Análisis del discurso guardado con ID: {result} para el usuario: {username}")
70
- return True
71
-
72
- logger.error("No se pudo insertar el documento en MongoDB")
73
- return False
74
-
75
- except Exception as e:
76
- logger.error(f"Error al guardar el análisis del discurso: {str(e)}")
77
- return False
78
-
79
-
80
-
81
- #################################################################################
82
- def get_student_discourse_analysis(username, limit=10):
83
- """
84
- Recupera los análisis del discurso de un estudiante.
85
- """
86
- try:
87
- # Obtener la colección
88
- collection = get_collection(COLLECTION_NAME)
89
- if collection is None: # Cambiado de if not collection a if collection is None
90
- logger.error("No se pudo obtener la colección discourse")
91
- return []
92
-
93
- # Consulta
94
- query = {
95
- "username": username,
96
- "analysis_type": "discourse"
97
- }
98
-
99
- # Campos a recuperar
100
- projection = {
101
- "timestamp": 1,
102
- "combined_graph": 1,
103
- "_id": 1
104
- }
105
-
106
- # Ejecutar consulta
107
- try:
108
- cursor = collection.find(query, projection).sort("timestamp", -1)
109
- if limit:
110
- cursor = cursor.limit(limit)
111
-
112
- # Convertir cursor a lista
113
- results = list(cursor)
114
- logger.info(f"Recuperados {len(results)} análisis del discurso para {username}")
115
- return results
116
-
117
- except Exception as db_error:
118
- logger.error(f"Error en la consulta a MongoDB: {str(db_error)}")
119
- return []
120
-
121
- except Exception as e:
122
- logger.error(f"Error recuperando análisis del discurso: {str(e)}")
123
- return []
124
- #####################################################################################
125
-
126
- def get_student_discourse_data(username):
127
- """
128
- Obtiene un resumen de los análisis del discurso de un estudiante.
129
- """
130
- try:
131
- analyses = get_student_discourse_analysis(username, limit=None)
132
- formatted_analyses = []
133
-
134
- for analysis in analyses:
135
- formatted_analysis = {
136
- 'timestamp': analysis['timestamp'],
137
- 'text1': analysis.get('text1', ''),
138
- 'text2': analysis.get('text2', ''),
139
- 'key_concepts1': analysis.get('key_concepts1', []),
140
- 'key_concepts2': analysis.get('key_concepts2', [])
141
- }
142
- formatted_analyses.append(formatted_analysis)
143
-
144
- return {'entries': formatted_analyses}
145
-
146
- except Exception as e:
147
- logger.error(f"Error al obtener datos del discurso: {str(e)}")
148
- return {'entries': []}
149
-
150
- ###########################################################################
151
- def update_student_discourse_analysis(analysis_id, update_data):
152
- """
153
- Actualiza un análisis del discurso existente.
154
- """
155
- try:
156
- query = {"_id": analysis_id}
157
- update = {"$set": update_data}
158
- return update_document(COLLECTION_NAME, query, update)
159
- except Exception as e:
160
- logger.error(f"Error al actualizar análisis del discurso: {str(e)}")
161
- return False
162
-
163
- ###########################################################################
164
- def delete_student_discourse_analysis(analysis_id):
165
- """
166
- Elimina un análisis del discurso.
167
- """
168
- try:
169
- query = {"_id": analysis_id}
170
- return delete_document(COLLECTION_NAME, query)
171
- except Exception as e:
172
- logger.error(f"Error al eliminar análisis del discurso: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  return False
 
1
+ # modules/database/discourse_mongo_db.py
2
+ # Importaciones estándar
3
+ import io
4
+ import base64
5
+ from datetime import datetime, timezone
6
+ import logging
7
+
8
+ # Importaciones de terceros
9
+ import matplotlib.pyplot as plt
10
+
11
+ from .mongo_db import (
12
+ get_collection,
13
+ insert_document,
14
+ find_documents,
15
+ update_document,
16
+ delete_document
17
+ )
18
+
19
+ # Configuración del logger
20
+ logger = logging.getLogger(__name__)
21
+ COLLECTION_NAME = 'student_discourse_analysis'
22
+
23
+ ########################################################################
24
+ def store_student_discourse_result(username, text1, text2, analysis_result):
25
+ """
26
+ Guarda el resultado del análisis de discurso comparativo en MongoDB.
27
+ """
28
+ try:
29
+ # Los gráficos ya vienen en bytes, solo necesitamos codificar a base64
30
+ graph1_data = None
31
+ graph2_data = None
32
+ combined_graph_data = None
33
+
34
+ if 'graph1' in analysis_result and analysis_result['graph1'] is not None:
35
+ try:
36
+ graph1_data = base64.b64encode(analysis_result['graph1']).decode('utf-8')
37
+ except Exception as e:
38
+ logger.error(f"Error al codificar gráfico 1: {str(e)}")
39
+
40
+ if 'graph2' in analysis_result and analysis_result['graph2'] is not None:
41
+ try:
42
+ graph2_data = base64.b64encode(analysis_result['graph2']).decode('utf-8')
43
+ except Exception as e:
44
+ logger.error(f"Error al codificar gráfico 2: {str(e)}")
45
+
46
+ if 'combined_graph' in analysis_result and analysis_result['combined_graph'] is not None:
47
+ try:
48
+ combined_graph_data = base64.b64encode(analysis_result['combined_graph']).decode('utf-8')
49
+ except Exception as e:
50
+ logger.error(f"Error al codificar gráfico combinado: {str(e)}")
51
+
52
+ # Crear documento para MongoDB
53
+ analysis_document = {
54
+ 'username': username,
55
+ 'timestamp': datetime.now(timezone.utc).isoformat(),
56
+ 'text1': text1,
57
+ 'text2': text2,
58
+ 'analysis_type': 'discourse',
59
+ 'key_concepts1': analysis_result.get('key_concepts1', []),
60
+ 'key_concepts2': analysis_result.get('key_concepts2', []),
61
+ 'graph1': graph1_data,
62
+ 'graph2': graph2_data,
63
+ 'combined_graph': combined_graph_data
64
+ }
65
+
66
+ # Insertar en MongoDB
67
+ result = insert_document(COLLECTION_NAME, analysis_document)
68
+ if result:
69
+ logger.info(f"Análisis del discurso guardado con ID: {result} para el usuario: {username}")
70
+ return True
71
+
72
+ logger.error("No se pudo insertar el documento en MongoDB")
73
+ return False
74
+
75
+ except Exception as e:
76
+ logger.error(f"Error al guardar el análisis del discurso: {str(e)}")
77
+ return False
78
+
79
+
80
+
81
+ #################################################################################
82
+
83
+ # Corrección 1: Actualizar get_student_discourse_analysis para recuperar todos los campos necesarios
84
+
85
+ def get_student_discourse_analysis(username, limit=10):
86
+ """
87
+ Recupera los análisis del discurso de un estudiante, incluyendo todos los gráficos y conceptos.
88
+ """
89
+ try:
90
+ # Obtener la colección
91
+ collection = get_collection(COLLECTION_NAME)
92
+ if collection is None:
93
+ logger.error("No se pudo obtener la colección discourse")
94
+ return []
95
+
96
+ # Consulta
97
+ query = {
98
+ "username": username,
99
+ "analysis_type": "discourse"
100
+ }
101
+
102
+ # Eliminar la proyección para recuperar todos los campos
103
+ # No usar projection para obtener TODOS los campos
104
+
105
+ # Ejecutar consulta
106
+ try:
107
+ cursor = collection.find(query).sort("timestamp", -1)
108
+ if limit:
109
+ cursor = cursor.limit(limit)
110
+
111
+ # Convertir cursor a lista
112
+ results = list(cursor)
113
+ logger.info(f"Recuperados {len(results)} análisis del discurso para {username}")
114
+
115
+ # Verificar qué campos contienen los resultados para depuración
116
+ if results:
117
+ for result in results:
118
+ logger.info(f"Campos disponibles: {list(result.keys())}")
119
+ if 'graph1' in result:
120
+ logger.info(f"Tipo de graph1: {type(result['graph1'])}")
121
+ if 'graph2' in result:
122
+ logger.info(f"Tipo de graph2: {type(result['graph2'])}")
123
+ if 'combined_graph' in result:
124
+ logger.info(f"Tipo de combined_graph: {type(result['combined_graph'])}")
125
+
126
+ return results
127
+
128
+ except Exception as db_error:
129
+ logger.error(f"Error en la consulta a MongoDB: {str(db_error)}")
130
+ return []
131
+
132
+ except Exception as e:
133
+ logger.error(f"Error recuperando análisis del discurso: {str(e)}")
134
+ return []
135
+
136
+ # Corrección 2: Mejorar store_student_discourse_result para manejar varios tipos de gráficos
137
+
138
+ def store_student_discourse_result(username, text1, text2, analysis_result):
139
+ """
140
+ Guarda el resultado del análisis de discurso comparativo en MongoDB.
141
+ """
142
+ try:
143
+ # Verificar qué tipo de objetos son los gráficos para depuración
144
+ if 'graph1' in analysis_result:
145
+ logger.info(f"Tipo de graph1 recibido: {type(analysis_result['graph1'])}")
146
+ if 'graph2' in analysis_result:
147
+ logger.info(f"Tipo de graph2 recibido: {type(analysis_result['graph2'])}")
148
+ if 'combined_graph' in analysis_result:
149
+ logger.info(f"Tipo de combined_graph recibido: {type(analysis_result['combined_graph'])}")
150
+
151
+ # Convertir gráficos a bytes o base64 según corresponda
152
+ graph1_data = None
153
+ graph2_data = None
154
+ combined_graph_data = None
155
+
156
+ if 'graph1' in analysis_result and analysis_result['graph1'] is not None:
157
+ try:
158
+ # Si es un objeto matplotlib Figure, convertirlo a bytes primero
159
+ if hasattr(analysis_result['graph1'], 'savefig'):
160
+ logger.info("Convirtiendo graph1 de matplotlib a bytes")
161
+ buf = io.BytesIO()
162
+ analysis_result['graph1'].savefig(buf, format='png', dpi=100)
163
+ buf.seek(0)
164
+ graph1_bytes = buf.getvalue()
165
+ graph1_data = base64.b64encode(graph1_bytes).decode('utf-8')
166
+ # Si ya es bytes, codificarlo directamente
167
+ elif isinstance(analysis_result['graph1'], bytes):
168
+ logger.info("Codificando graph1 (ya en bytes) a base64")
169
+ graph1_data = base64.b64encode(analysis_result['graph1']).decode('utf-8')
170
+ # Si ya es una cadena base64, usarla directamente
171
+ elif isinstance(analysis_result['graph1'], str):
172
+ logger.info("Usando graph1 (ya en string) directamente")
173
+ graph1_data = analysis_result['graph1']
174
+ # Otro tipo - convertir a string
175
+ else:
176
+ logger.warning(f"Tipo inesperado para graph1: {type(analysis_result['graph1'])}")
177
+ graph1_data = str(analysis_result['graph1'])
178
+ except Exception as e:
179
+ logger.error(f"Error al procesar gráfico 1: {str(e)}")
180
+
181
+ if 'graph2' in analysis_result and analysis_result['graph2'] is not None:
182
+ try:
183
+ # Si es un objeto matplotlib Figure, convertirlo a bytes primero
184
+ if hasattr(analysis_result['graph2'], 'savefig'):
185
+ logger.info("Convirtiendo graph2 de matplotlib a bytes")
186
+ buf = io.BytesIO()
187
+ analysis_result['graph2'].savefig(buf, format='png', dpi=100)
188
+ buf.seek(0)
189
+ graph2_bytes = buf.getvalue()
190
+ graph2_data = base64.b64encode(graph2_bytes).decode('utf-8')
191
+ # Si ya es bytes, codificarlo directamente
192
+ elif isinstance(analysis_result['graph2'], bytes):
193
+ logger.info("Codificando graph2 (ya en bytes) a base64")
194
+ graph2_data = base64.b64encode(analysis_result['graph2']).decode('utf-8')
195
+ # Si ya es una cadena base64, usarla directamente
196
+ elif isinstance(analysis_result['graph2'], str):
197
+ logger.info("Usando graph2 (ya en string) directamente")
198
+ graph2_data = analysis_result['graph2']
199
+ # Otro tipo - convertir a string
200
+ else:
201
+ logger.warning(f"Tipo inesperado para graph2: {type(analysis_result['graph2'])}")
202
+ graph2_data = str(analysis_result['graph2'])
203
+ except Exception as e:
204
+ logger.error(f"Error al procesar gráfico 2: {str(e)}")
205
+
206
+ if 'combined_graph' in analysis_result and analysis_result['combined_graph'] is not None:
207
+ try:
208
+ # Si es un objeto matplotlib Figure, convertirlo a bytes primero
209
+ if hasattr(analysis_result['combined_graph'], 'savefig'):
210
+ logger.info("Convirtiendo combined_graph de matplotlib a bytes")
211
+ buf = io.BytesIO()
212
+ analysis_result['combined_graph'].savefig(buf, format='png', dpi=100)
213
+ buf.seek(0)
214
+ combined_graph_bytes = buf.getvalue()
215
+ combined_graph_data = base64.b64encode(combined_graph_bytes).decode('utf-8')
216
+ # Si ya es bytes, codificarlo directamente
217
+ elif isinstance(analysis_result['combined_graph'], bytes):
218
+ logger.info("Codificando combined_graph (ya en bytes) a base64")
219
+ combined_graph_data = base64.b64encode(analysis_result['combined_graph']).decode('utf-8')
220
+ # Si ya es una cadena base64, usarla directamente
221
+ elif isinstance(analysis_result['combined_graph'], str):
222
+ logger.info("Usando combined_graph (ya en string) directamente")
223
+ combined_graph_data = analysis_result['combined_graph']
224
+ # Otro tipo - convertir a string
225
+ else:
226
+ logger.warning(f"Tipo inesperado para combined_graph: {type(analysis_result['combined_graph'])}")
227
+ combined_graph_data = str(analysis_result['combined_graph'])
228
+ except Exception as e:
229
+ logger.error(f"Error al procesar gráfico combinado: {str(e)}")
230
+
231
+ # Crear documento para MongoDB
232
+ analysis_document = {
233
+ 'username': username,
234
+ 'timestamp': datetime.now(timezone.utc).isoformat(),
235
+ 'text1': text1,
236
+ 'text2': text2,
237
+ 'analysis_type': 'discourse',
238
+ 'key_concepts1': analysis_result.get('key_concepts1', []),
239
+ 'key_concepts2': analysis_result.get('key_concepts2', []),
240
+ 'graph1': graph1_data,
241
+ 'graph2': graph2_data,
242
+ 'combined_graph': combined_graph_data
243
+ }
244
+
245
+ # Insertar en MongoDB
246
+ result = insert_document(COLLECTION_NAME, analysis_document)
247
+ if result:
248
+ logger.info(f"Análisis del discurso guardado con ID: {result} para el usuario: {username}")
249
+ return True
250
+
251
+ logger.error("No se pudo insertar el documento en MongoDB")
252
+ return False
253
+
254
+ except Exception as e:
255
+ logger.error(f"Error al guardar el análisis del discurso: {str(e)}")
256
+ return False
257
+
258
+ #####################################################################################
259
+
260
+ def get_student_discourse_data(username):
261
+ """
262
+ Obtiene un resumen de los análisis del discurso de un estudiante.
263
+ """
264
+ try:
265
+ analyses = get_student_discourse_analysis(username, limit=None)
266
+ formatted_analyses = []
267
+
268
+ for analysis in analyses:
269
+ formatted_analysis = {
270
+ 'timestamp': analysis['timestamp'],
271
+ 'text1': analysis.get('text1', ''),
272
+ 'text2': analysis.get('text2', ''),
273
+ 'key_concepts1': analysis.get('key_concepts1', []),
274
+ 'key_concepts2': analysis.get('key_concepts2', [])
275
+ }
276
+ formatted_analyses.append(formatted_analysis)
277
+
278
+ return {'entries': formatted_analyses}
279
+
280
+ except Exception as e:
281
+ logger.error(f"Error al obtener datos del discurso: {str(e)}")
282
+ return {'entries': []}
283
+
284
+ ###########################################################################
285
+ def update_student_discourse_analysis(analysis_id, update_data):
286
+ """
287
+ Actualiza un análisis del discurso existente.
288
+ """
289
+ try:
290
+ query = {"_id": analysis_id}
291
+ update = {"$set": update_data}
292
+ return update_document(COLLECTION_NAME, query, update)
293
+ except Exception as e:
294
+ logger.error(f"Error al actualizar análisis del discurso: {str(e)}")
295
+ return False
296
+
297
+ ###########################################################################
298
+ def delete_student_discourse_analysis(analysis_id):
299
+ """
300
+ Elimina un análisis del discurso.
301
+ """
302
+ try:
303
+ query = {"_id": analysis_id}
304
+ return delete_document(COLLECTION_NAME, query)
305
+ except Exception as e:
306
+ logger.error(f"Error al eliminar análisis del discurso: {str(e)}")
307
  return False