import uuid from flask import Blueprint, request, jsonify,g from uuid import UUID from db.model import db, User, Course, Enrollment,Chat from utils.auth import auth_required import requests from config import SPAM_SCORE_THRESHOLD, AI_SPAM_SERVICES_MICROSERVICE from sqlalchemy import desc, select, and_ chat = Blueprint('chat', __name__) @chat.route("/send", methods=["POST"]) @auth_required() def create_chat(): current_user: User = g.current_user # Fetch the logged-in user data = request.form if not data.get("course_id"): return jsonify({"error": "Unknown Course"}), 400 if not data.get("message", "").strip(): return jsonify({'message': 'Silently rejected blank message'}), 200 try: # Check if the user is enrolled in the course enrollment_record: Enrollment = db.session.execute( select(Enrollment).where(and_( Enrollment.courseID == data.get("course_id"), Enrollment.userID == current_user.id) ) ).scalar() if not enrollment_record: return jsonify({"error": "You are not enrolled in this course."}), 403 if enrollment_record.currentPage < enrollment_record.course.pageForCommunity: return jsonify({ 'message': 'You have not met the requirements to enter the chat.' }), 403 # Create and save the chat message spam_response = requests.post(AI_SPAM_SERVICES_MICROSERVICE, json={"test_message": data.get("message").strip()}) if spam_response.status_code != 200: return jsonify({"error": "Failed to check message for spam."}), 500 spam_score = int(spam_response.json().get("spam_score", 0)) if spam_score > SPAM_SCORE_THRESHOLD: return jsonify({"error": "This message contains suspicious links or is vulnerable."}), 400 new_chat = Chat( textContent=data.get("message").strip(), userID=current_user.id, user=g.current_user, course=enrollment_record.course, courseID=data.get("course_id"), ) db.session.add(new_chat) db.session.commit() return jsonify({"message": "Chat sent successfully.", "chat_id": str(new_chat.id)}), 201 except Exception as e: return jsonify({"error": f"An error occurred: {str(e)}"}), 500 @chat.route("/get", methods=["GET"]) @auth_required() def get_messages(): try: course_id: uuid.UUID = uuid.UUID(request.args.get('course_id')) current_user: User = g.current_user limit = int(request.args.get('limit', 10)) before_id = request.args.get('before') after_id = request.args.get('after') # Verify user's enrollment enrollment = db.session.execute( select(Enrollment).where( and_(Enrollment.courseID == course_id, Enrollment.userID == current_user.id) ) ).scalar() if not enrollment: return jsonify({"error": "You are not enrolled in this course."}), 403 query = select(Chat).where(Chat.courseID == course_id) if before_id: try: reference_message: Chat = db.session.execute( select(Chat).where(Chat.id == uuid.UUID(before_id)) ).scalar() if not reference_message: return jsonify({'message': 'Reference message not found'}), 404 query = query.order_by(Chat.chatDate.desc()).where(Chat.chatDate < reference_message.chatDate) except ValueError: return jsonify({'message': 'Invalid message ID format'}), 400 elif after_id: try: reference_message = db.session.execute( select(Chat).where(Chat.id == uuid.UUID(after_id)) ).scalar() if not reference_message: return jsonify({'message': 'Reference message not found'}), 404 query = query.order_by(Chat.chatDate.asc()).where(Chat.chatDate > reference_message.chatDate) except ValueError: return jsonify({'message': 'Invalid message ID format'}), 400 else: query = query.order_by(Chat.chatDate.desc()) query = query.limit(limit) messages = db.session.execute(query).scalars() chat_messages = [{ 'id': str(msg.id), 'text': msg.textContent, 'userId': str(msg.userID), 'username': msg.user.username, 'timestamp': msg.chatDate.isoformat() } for msg in messages] return jsonify({ 'messages': chat_messages, 'count': len(chat_messages), }), 200 except Exception as e: return jsonify({'message': f'An error occurred: {str(e)}'}), 500