|
|
|
from flask import Blueprint, request, jsonify, current_app, g
|
|
|
|
from db.model import User, Course, Enrollment, Chat, db
|
|
|
|
import uuid
|
|
|
|
from sqlalchemy import select, and_
|
|
|
|
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.
|
|
|
|
Only enrolled users can access the messages.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
current_user: User = g.current_user
|
|
|
|
|
|
|
|
# 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
|
|
|
|
|
|
|
|
# Get chat messages for the course
|
|
|
|
messages = db.session.execute(
|
|
|
|
select(Chat)
|
|
|
|
.where(Chat.courseID == course_id)
|
|
|
|
.order_by(Chat.chatDate.desc())
|
|
|
|
).scalars()
|
|
|
|
|
|
|
|
# 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}), 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
|
|
|
|
|
|
|
|
@chat.route('/<uuid:course_id>/participants', methods=['GET'])
|
|
|
|
def get_chat_participants(course_id: uuid.UUID):
|
|
|
|
"""
|
|
|
|
Get list of active participants in a course chat.
|
|
|
|
Returns only enrolled users with recent activity.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
current_user: User = g.current_user
|
|
|
|
|
|
|
|
# Verify requesting user's enrollment
|
|
|
|
user_enrollment = db.session.execute(
|
|
|
|
select(Enrollment).where(
|
|
|
|
and_(
|
|
|
|
Enrollment.courseID == course_id,
|
|
|
|
Enrollment.userID == current_user.id
|
|
|
|
)
|
|
|
|
)
|
|
|
|
).scalar()
|
|
|
|
|
|
|
|
if not user_enrollment:
|
|
|
|
return jsonify({'message': 'You are not enrolled in this course'}), 401
|
|
|
|
|
|
|
|
# Get enrolled users
|
|
|
|
enrollments = db.session.execute(
|
|
|
|
select(Enrollment)
|
|
|
|
.where(Enrollment.courseID == course_id)
|
|
|
|
.join(User)
|
|
|
|
).scalars()
|
|
|
|
|
|
|
|
# Return participant information
|
|
|
|
participants = [{
|
|
|
|
'id': str(enrollment.userID),
|
|
|
|
'username': enrollment.user.username,
|
|
|
|
'lastActivity': enrollment.lastActivity.isoformat()
|
|
|
|
} for enrollment in enrollments]
|
|
|
|
|
|
|
|
return jsonify({'participants': participants}), 200
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
return jsonify({'message': f'An error occurred: {str(e)}'}), 500
|