| |
| import logging |
| from datetime import datetime, timezone |
| import base64 |
| from bson import Binary |
| from pymongo.errors import PyMongoError |
|
|
| |
| logger = logging.getLogger(__name__) |
| COLLECTION_NAME = 'student_semantic_live_analysis' |
|
|
| def store_student_semantic_live_result(username, text, analysis_result, lang_code='en'): |
| """ |
| Guarda el resultado del análisis semántico en vivo en MongoDB. |
| Versión mejorada con manejo robusto de errores y verificación de datos. |
| """ |
| try: |
| |
| if not username or not isinstance(username, str): |
| logger.error("Nombre de usuario inválido o vacío") |
| return False |
|
|
| if not text or not isinstance(text, str): |
| logger.error("Texto de análisis inválido o vacío") |
| return False |
|
|
| if not analysis_result or not isinstance(analysis_result, dict): |
| logger.error("Resultado de análisis inválido o vacío") |
| return False |
|
|
| |
| concept_graph_data = None |
| if 'concept_graph' in analysis_result and analysis_result['concept_graph'] is not None: |
| try: |
| graph_data = analysis_result['concept_graph'] |
| |
| if isinstance(graph_data, bytes): |
| |
| concept_graph_data = base64.b64encode(graph_data).decode('utf-8') |
| elif isinstance(graph_data, str): |
| |
| concept_graph_data = graph_data |
| elif isinstance(graph_data, Binary): |
| |
| concept_graph_data = base64.b64encode(graph_data).decode('utf-8') |
| else: |
| logger.warning(f"Formato de gráfico no soportado: {type(graph_data)}") |
| except Exception as e: |
| logger.error(f"Error al procesar gráfico conceptual: {str(e)}", exc_info=True) |
| |
|
|
| |
| analysis_document = { |
| 'username': username, |
| 'timestamp': datetime.now(timezone.utc), |
| 'text': text[:10000], |
| 'analysis_type': 'semantic_live', |
| 'language': lang_code, |
| 'metadata': { |
| 'version': '1.0', |
| 'source': 'live_interface' |
| } |
| } |
|
|
| |
| if 'key_concepts' in analysis_result and isinstance(analysis_result['key_concepts'], list): |
| analysis_document['key_concepts'] = analysis_result['key_concepts'][:50] |
|
|
| if 'concept_centrality' in analysis_result and isinstance(analysis_result['concept_centrality'], dict): |
| analysis_document['concept_centrality'] = analysis_result['concept_centrality'] |
|
|
| if concept_graph_data: |
| analysis_document['concept_graph'] = concept_graph_data |
|
|
| |
| try: |
| collection = get_collection(COLLECTION_NAME) |
| if not collection: |
| logger.error("No se pudo obtener la colección MongoDB") |
| return False |
|
|
| result = collection.insert_one(analysis_document) |
| |
| if result.inserted_id: |
| logger.info(f"Análisis guardado exitosamente para {username}. ID: {result.inserted_id}") |
| return True |
| |
| logger.error("La operación de inserción no devolvió un ID") |
| return False |
|
|
| except PyMongoError as mongo_error: |
| logger.error(f"Error de MongoDB al guardar análisis: {str(mongo_error)}", exc_info=True) |
| return False |
|
|
| except Exception as e: |
| logger.error(f"Error inesperado al guardar análisis: {str(e)}", exc_info=True) |
| return False |
|
|
| def get_student_semantic_live_analysis(username, limit=10): |
| """ |
| Recupera los análisis semánticos en vivo de un estudiante. |
| Versión mejorada con paginación y manejo de errores. |
| """ |
| try: |
| |
| if not username or not isinstance(username, str): |
| logger.error("Nombre de usuario inválido para recuperación") |
| return [] |
|
|
| if not isinstance(limit, int) or limit <= 0: |
| limit = 10 |
|
|
| |
| query = { |
| "username": username, |
| "analysis_type": "semantic_live" |
| } |
| |
| projection = { |
| "timestamp": 1, |
| "text": {"$substr": ["$text", 0, 200]}, |
| "key_concepts": {"$slice": ["$key_concepts", 10]}, |
| "concept_graph": 1, |
| "_id": 1, |
| "metadata": 1 |
| } |
| |
| |
| try: |
| collection = get_collection(COLLECTION_NAME) |
| if not collection: |
| logger.error("No se pudo obtener la colección MongoDB") |
| return [] |
|
|
| cursor = collection.find(query, projection).sort("timestamp", -1).limit(limit) |
| results = list(cursor) |
| |
| |
| for doc in results: |
| if 'concept_graph' in doc and isinstance(doc['concept_graph'], str): |
| try: |
| |
| doc['concept_graph'] = base64.b64decode(doc['concept_graph']) |
| except Exception as e: |
| logger.warning(f"Error al decodificar gráfico: {str(e)}") |
| doc.pop('concept_graph', None) |
| |
| logger.info(f"Recuperados {len(results)} análisis para {username}") |
| return results |
|
|
| except PyMongoError as mongo_error: |
| logger.error(f"Error de MongoDB al recuperar análisis: {str(mongo_error)}") |
| return [] |
|
|
| except Exception as e: |
| logger.error(f"Error inesperado al recuperar análisis: {str(e)}", exc_info=True) |
| return [] |
|
|
| __all__ = [ |
| 'store_student_semantic_live_result', |
| 'get_student_semantic_live_analysis' |
| ] |