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 sqlalchemy import desc chat = Blueprint('chat', __name__) SPAM_DETECTION_URL = "http://localhost:5000/test-spam" @chat.route('/course//users', methods=['POST']) def get_users_assigned_to_course(course_id: UUID): """ Fetch all users assigned to a specific course. :param course_id: ID of the course to fetch users for (UUID). :return: JSON response with users assigned to the course. """ try: # Query the course to ensure it exists course = Course.query.get(course_id) if not course: return jsonify({"error": "Course not found."}), 404 # Get the list of users assigned to the course users = User.query.filter(User.enrollments.any(course_id=course_id)).all() # Prepare the response data user_data = [ { "id": user.id, "email": user.email, "username": user.username, "firstName": user.firstName, "lastName": user.lastName, } for user in users ] return jsonify({"course": course.name, "users": user_data}), 200 except Exception as e: return jsonify({"error": f"An error occurred: {str(e)}"}), 500 @chat.route('/course//chat', methods=['POST']) def join_chat(course_id: UUID): """ Allow users to join the chat only if they are enrolled in the course. :param course_id: ID of the course (UUID). :return: JSON response indicating whether the user can join or not. """ try: # Get the user from the request (assume user_id is passed in the request body) user_id = request.json.get('user_id') if not user_id: return jsonify({"error": "User ID is required."}), 400 # Query the user and ensure they exist user = User.query.get(user_id) if not user: return jsonify({"error": "User not found."}), 404 # Check if the user is enrolled in the course enrollment = Enrollment.query.filter_by(userID=user_id, courseID=course_id).first() if not enrollment: return jsonify({"error": "User is not enrolled in this course."}), 403 # If enrolled, allow the user to join the chat return jsonify({"message": f"User {user.username} is enrolled in the course and can join the chat."}), 200 except Exception as e: return jsonify({"error": f"An error occurred: {str(e)}"}), 500 @chat.route("/send-message", methods=["POST"]) @auth_required() def create_chat(): """ Create a chat message for a specific course. """ current_user = g.current_user # Fetch the logged-in user data = request.get_json() # Validate the payload course_id = data.get("course_id") message = data.get("message") if not course_id or not message: return jsonify({"error": "Course ID and message are required."}), 400 try: # Call the spam detection service spam_response = requests.post(SPAM_DETECTION_URL, json={"test_message": message}) 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 > 6: return jsonify({"error": "This message contains suspicious links or is vulnerable."}), 400 # Verify the course exists course = db.session.query(Course).filter_by(id=course_id).first() if not course: return jsonify({"error": "Invalid course ID."}), 404 # Check if the user is enrolled in the course is_enrolled = db.session.query(Course).join(Enrollment).filter( Enrollment.userID == current_user.id, Enrollment.courseID == course_id ).first() if not is_enrolled: return jsonify({"error": "You are not enrolled in this course."}), 403 # Create and save the chat message new_chat = Chat( textContent=message, userID=current_user.id, courseID=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_chat_history(): """ Fetch chat history for a course. """ current_user = g.current_user # Logged-in user course_id = request.args.get("course_id") limit = int(request.args.get("limit", 20)) # Default to 20 messages offset = int(request.args.get("offset", 0)) # Default to no offset (latest chats) if not course_id: return jsonify({"error": "Course ID is required."}), 400 try: # Verify the course exists course = db.session.query(Course).filter_by(id=course_id).first() if not course: return jsonify({"error": "Invalid course ID."}), 404 # Check if the user is enrolled in the course is_enrolled = db.session.query(Course).join(Enrollment).filter( Enrollment.userID == current_user.id, Enrollment.courseID == course_id ).first() if not is_enrolled: return jsonify({"error": "You are not enrolled in this course."}), 403 # Fetch the latest chat messages with limit and offset chats = ( db.session.query(Chat) .filter_by(courseID=course_id) .order_by(desc(Chat.chatDate)) .offset(offset) .limit(limit) .all() ) # Format the chat messages chat_history = [ { "id": str(chat.id), "textContent": chat.textContent, "userID": str(chat.userID), "chatDate": chat.chatDate.isoformat(), "is_mine": chat.userID == current_user.id, } for chat in chats ] return jsonify({"chats": chat_history}), 200 except Exception as e: return jsonify({"error": f"An error occurred: {str(e)}"}), 500