You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
FreeBug/backend/blueprints/chat/__init__.py

183 lines
6.3 KiB

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/<uuid:course_id>/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/<uuid:course_id>/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