Spaces:
Sleeping
Sleeping
| from flask import Blueprint, request, jsonify, session | |
| from bson import ObjectId | |
| import logging | |
| from utils.extensions import ext | |
| conversations_bp = Blueprint('conversations', __name__) | |
| def get_conversations(): | |
| if 'user_id' not in session: | |
| return jsonify({'error': 'Vui lòng đăng nhập'}), 401 | |
| user_id = session['user_id'] | |
| try: | |
| conversations = ext.db.conversations.find({'user_id': user_id}).sort('timestamp', -1).limit(50) | |
| conversations_list = [] | |
| for conv in conversations: | |
| message_count = ext.db.messages.count_documents({'conversation_id': str(conv['_id'])}) | |
| conversations_list.append({ | |
| 'id': str(conv['_id']), | |
| 'title': conv.get('title', 'Cuộc trò chuyện'), | |
| 'timestamp': conv['timestamp'].isoformat() if 'timestamp' in conv else None, | |
| 'message_count': message_count, | |
| 'last_message': get_last_message(str(conv['_id'])) | |
| }) | |
| return jsonify(conversations_list), 200 | |
| except Exception as e: | |
| logging.error(f"Error getting conversations: {e}") | |
| return jsonify({'error': 'Lỗi hệ thống'}), 500 | |
| def get_conversation(conversation_id): | |
| if 'user_id' not in session: | |
| return jsonify({'error': 'Vui lòng đăng nhập'}), 401 | |
| user_id = session['user_id'] | |
| try: | |
| # Validate conversation_id format | |
| if not ObjectId.is_valid(conversation_id): | |
| return jsonify({'error': 'ID hội thoại không hợp lệ'}), 400 | |
| conversation = ext.db.conversations.find_one({ | |
| '_id': ObjectId(conversation_id), | |
| 'user_id': user_id | |
| }) | |
| if not conversation: | |
| return jsonify({'error': 'Hội thoại không tồn tại hoặc bạn không có quyền truy cập'}), 404 | |
| # Get messages with pagination | |
| page = request.args.get('page', 1, type=int) | |
| limit = request.args.get('limit', 50, type=int) | |
| skip = (page - 1) * limit | |
| messages_cursor = ext.db.messages.find({'conversation_id': conversation_id}) \ | |
| .sort('timestamp', 1) \ | |
| .skip(skip) \ | |
| .limit(limit) | |
| messages_list = [] | |
| for msg in messages_cursor: | |
| message_data = { | |
| 'id': str(msg['_id']), | |
| 'type': msg['type'], | |
| 'content': msg['content'], | |
| 'timestamp': msg['timestamp'].isoformat() if 'timestamp' in msg else None, | |
| } | |
| # Add optional fields if they exist | |
| if 'sources' in msg: | |
| message_data['sources'] = msg['sources'] | |
| if 'related_questions' in msg: | |
| message_data['related_questions'] = msg['related_questions'] | |
| messages_list.append(message_data) | |
| # Get total message count for pagination | |
| total_messages = ext.db.messages.count_documents({'conversation_id': conversation_id}) | |
| return jsonify({ | |
| 'id': str(conversation['_id']), | |
| 'title': conversation.get('title', 'Cuộc trò chuyện'), | |
| 'timestamp': conversation['timestamp'].isoformat() if 'timestamp' in conversation else None, | |
| 'messages': messages_list, | |
| 'pagination': { | |
| 'page': page, | |
| 'limit': limit, | |
| 'total': total_messages, | |
| 'pages': (total_messages + limit - 1) // limit | |
| } | |
| }), 200 | |
| except Exception as e: | |
| logging.error(f"Error getting conversation: {e}") | |
| return jsonify({'error': 'Lỗi hệ thống'}), 500 | |
| def delete_conversation(conversation_id): | |
| if 'user_id' not in session: | |
| return jsonify({'error': 'Vui lòng đăng nhập'}), 401 | |
| user_id = session['user_id'] | |
| try: | |
| # Validate conversation_id format | |
| if not ObjectId.is_valid(conversation_id): | |
| return jsonify({'error': 'ID hội thoại không hợp lệ'}), 400 | |
| result = ext.db.conversations.delete_one({ | |
| '_id': ObjectId(conversation_id), | |
| 'user_id': user_id | |
| }) | |
| if result.deleted_count == 0: | |
| return jsonify({'error': 'Hội thoại không tồn tại hoặc bạn không có quyền xóa'}), 404 | |
| # Also delete all messages in this conversation | |
| ext.db.messages.delete_many({'conversation_id': conversation_id}) | |
| logging.info(f"User {user_id} deleted conversation {conversation_id}") | |
| return jsonify({'message': 'Xóa hội thoại thành công'}), 200 | |
| except Exception as e: | |
| logging.error(f"Error deleting conversation: {e}") | |
| return jsonify({'error': 'Lỗi hệ thống'}), 500 | |
| def rename_conversation(conversation_id): | |
| if 'user_id' not in session: | |
| return jsonify({'error': 'Vui lòng đăng nhập'}), 401 | |
| user_id = session['user_id'] | |
| data = request.get_json(silent=True) or {} | |
| new_title = data.get('title', '').strip() | |
| if not new_title: | |
| return jsonify({'error': 'Tiêu đề không được để trống'}), 400 | |
| if len(new_title) > 100: | |
| return jsonify({'error': 'Tiêu đề quá dài (tối đa 100 ký tự)'}), 400 | |
| try: | |
| # Validate conversation_id format | |
| if not ObjectId.is_valid(conversation_id): | |
| return jsonify({'error': 'ID hội thoại không hợp lệ'}), 400 | |
| result = ext.db.conversations.update_one( | |
| { | |
| '_id': ObjectId(conversation_id), | |
| 'user_id': user_id | |
| }, | |
| {'$set': {'title': new_title}} | |
| ) | |
| if result.matched_count == 0: | |
| return jsonify({'error': 'Hội thoại không tồn tại hoặc bạn không có quyền chỉnh sửa'}), 404 | |
| return jsonify({'message': 'Đổi tên hội thoại thành công', 'new_title': new_title}), 200 | |
| except Exception as e: | |
| logging.error(f"Error renaming conversation: {e}") | |
| return jsonify({'error': 'Lỗi hệ thống'}), 500 | |
| def bulk_delete_conversations(): | |
| if 'user_id' not in session: | |
| return jsonify({'error': 'Vui lòng đăng nhập'}), 401 | |
| user_id = session['user_id'] | |
| data = request.get_json(silent=True) or {} | |
| conversation_ids = data.get('conversation_ids', []) | |
| if not conversation_ids or not isinstance(conversation_ids, list): | |
| return jsonify({'error': 'Danh sách ID hội thoại không hợp lệ'}), 400 | |
| try: | |
| # Convert string IDs to ObjectId and validate | |
| object_ids = [] | |
| for conv_id in conversation_ids: | |
| if ObjectId.is_valid(conv_id): | |
| object_ids.append(ObjectId(conv_id)) | |
| if not object_ids: | |
| return jsonify({'error': 'Không có ID hội thoại hợp lệ'}), 400 | |
| # Delete conversations belonging to the user | |
| result = ext.db.conversations.delete_many({ | |
| '_id': {'$in': object_ids}, | |
| 'user_id': user_id | |
| }) | |
| # Also delete messages in these conversations | |
| for conv_id in conversation_ids: | |
| ext.db.messages.delete_many({'conversation_id': conv_id}) | |
| logging.info(f"User {user_id} deleted {result.deleted_count} conversations") | |
| return jsonify({ | |
| 'message': f'Đã xóa {result.deleted_count} hội thoại thành công', | |
| 'deleted_count': result.deleted_count | |
| }), 200 | |
| except Exception as e: | |
| logging.error(f"Error bulk deleting conversations: {e}") | |
| return jsonify({'error': 'Lỗi hệ thống'}), 500 | |
| def get_last_message(conversation_id): | |
| """Helper function to get the last message in a conversation""" | |
| try: | |
| last_message = ext.db.messages.find_one( | |
| {'conversation_id': conversation_id}, | |
| sort=[('timestamp', -1)] | |
| ) | |
| if last_message: | |
| return { | |
| 'content': last_message['content'][:100] + '...' if len(last_message['content']) > 100 else last_message['content'], | |
| 'type': last_message['type'], | |
| 'timestamp': last_message['timestamp'].isoformat() if 'timestamp' in last_message else None | |
| } | |
| return None | |
| except Exception as e: | |
| logging.error(f"Error getting last message: {e}") | |
| return None |