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.
148 lines
5.1 KiB
148 lines
5.1 KiB
from flask import Blueprint, request, jsonify, g
|
|
from db.model import User, Enrollment, Chat, db
|
|
import uuid
|
|
from sqlalchemy import select, and_, desc
|
|
from datetime import datetime
|
|
|
|
chat = Blueprint('chat', __name__)
|
|
|
|
@chat.route('/<uuid:course_id>/messages', methods=['GET'])
|
|
def get_course_messages(course_id: uuid.UUID):
|
|
"""
|
|
Fetch chat messages for a specific course with optional pagination.
|
|
Only enrolled users can access the messages.
|
|
|
|
Query Parameters:
|
|
- before: UUID of the message to get older entries
|
|
- after: UUID of the message to get newer entries
|
|
- limit: Number of messages to return (default: 10)
|
|
"""
|
|
try:
|
|
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({'message': 'You are not enrolled in this course'}), 401
|
|
|
|
# Base query
|
|
query = select(Chat).where(Chat.courseID == course_id)
|
|
|
|
# Handle pagination
|
|
if before_id:
|
|
try:
|
|
reference_message = 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.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.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
|
|
|
|
@chat.route('/<uuid:course_id>/send', methods=['POST'])
|
|
def send_message(course_id: uuid.UUID):
|
|
"""
|
|
Send a new chat message in a course.
|
|
Only enrolled users can send messages.
|
|
"""
|
|
try:
|
|
current_user: User = g.current_user
|
|
message_text = request.json.get('message')
|
|
|
|
if not message_text or not message_text.strip():
|
|
return jsonify({'message': 'Message content is required'}), 400
|
|
|
|
# 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({'message': 'You are not enrolled in this course'}), 401
|
|
|
|
# Create new chat message
|
|
new_message = Chat(
|
|
textContent=message_text,
|
|
userID=current_user.id,
|
|
courseID=course_id,
|
|
chatDate=datetime.now()
|
|
)
|
|
|
|
db.session.add(new_message)
|
|
|
|
# Update last activity in enrollment
|
|
enrollment.lastActivity = datetime.now()
|
|
|
|
db.session.commit()
|
|
|
|
return jsonify({
|
|
'message': 'Message sent successfully',
|
|
'messageId': str(new_message.id),
|
|
'timestamp': new_message.chatDate.isoformat()
|
|
}), 201
|
|
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return jsonify({'message': f'An error occurred: {str(e)}'}), 500 |