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

125 lines
5.1 KiB

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.args
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)
)
)
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,
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)
# For after queries, reverse the order later
query = query.order_by(Chat.chatDate)
except ValueError:
return jsonify({'message': 'Invalid message ID format'}), 400
else:
# Default ordering
query = query.order_by(desc(Chat.chatDate))
# Apply limit and execute query
query = query.limit(limit)
messages = list(db.session.execute(query).scalars())
# Reverse the order for 'after' queries to maintain consistency
if after_id:
messages.reverse()
# Format messages
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),
'hasMore': len(chat_messages) == limit
}), 200
except Exception as e:
return jsonify({'message': f'An error occurred: {str(e)}'}), 500