|
|
|
@ -1,4 +1,4 @@ |
|
|
|
from rest_framework import serializers |
|
|
|
from rest_framework import serializers |
|
|
|
from utils import FileFieldSerializer, get_thumbs |
|
|
|
from apps.course.models import ( |
|
|
|
Course, |
|
|
|
@ -12,7 +12,8 @@ from apps.course.models import ( |
|
|
|
Glossary, |
|
|
|
CourseLiveSession, |
|
|
|
LiveSessionUser, |
|
|
|
LiveSessionRecording |
|
|
|
LiveSessionRecording, |
|
|
|
Participant |
|
|
|
) |
|
|
|
from apps.account.models import ProfessorUser |
|
|
|
from apps.course.models.course import extract_text_from_json, get_localized_field |
|
|
|
@ -502,7 +503,7 @@ class AdminLiveSessionListSerializer(serializers.ModelSerializer): |
|
|
|
|
|
|
|
class AdminLiveSessionDetailSerializer(serializers.ModelSerializer): |
|
|
|
course_title = serializers.SerializerMethodField() |
|
|
|
user_sessions = AdminLiveSessionUserSerializer(many=True, read_only=True) |
|
|
|
user_sessions = serializers.SerializerMethodField() |
|
|
|
recordings = AdminLiveSessionRecordingSerializer(many=True, read_only=True) |
|
|
|
recorded_file = FileFieldSerializer(required=False, allow_null=True) |
|
|
|
|
|
|
|
@ -516,3 +517,66 @@ class AdminLiveSessionDetailSerializer(serializers.ModelSerializer): |
|
|
|
lang = get_request_lang(self) |
|
|
|
return get_localized_field(lang, obj.course.title) |
|
|
|
|
|
|
|
def get_user_sessions(self, obj): |
|
|
|
# 1. Get all active participants of this course |
|
|
|
participants = obj.course.participants.filter(is_active=True).select_related('student') |
|
|
|
|
|
|
|
# 2. Get all live session user records for this session |
|
|
|
attendance_map = { |
|
|
|
ls_user.user_id: ls_user |
|
|
|
for ls_user in obj.user_sessions.all().select_related('user') |
|
|
|
} |
|
|
|
|
|
|
|
# 3. Build the combined list |
|
|
|
data = [] |
|
|
|
for p in participants: |
|
|
|
student = p.student |
|
|
|
# Check if this student has an attendance record |
|
|
|
attendance = attendance_map.get(student.id) |
|
|
|
|
|
|
|
if attendance: |
|
|
|
data.append({ |
|
|
|
'id': attendance.id, |
|
|
|
'session': obj.id, |
|
|
|
'user': student.id, |
|
|
|
'user_name': student.fullname or student.username, |
|
|
|
'user_email': student.email, |
|
|
|
'role': attendance.role, |
|
|
|
'entered_at': attendance.entered_at.isoformat() if attendance.entered_at else None, |
|
|
|
'exited_at': attendance.exited_at.isoformat() if attendance.exited_at else None, |
|
|
|
'is_online': attendance.is_online, |
|
|
|
'has_attended': True |
|
|
|
}) |
|
|
|
else: |
|
|
|
data.append({ |
|
|
|
'id': None, |
|
|
|
'session': obj.id, |
|
|
|
'user': student.id, |
|
|
|
'user_name': student.fullname or student.username, |
|
|
|
'user_email': student.email, |
|
|
|
'role': 'participant', |
|
|
|
'entered_at': None, |
|
|
|
'exited_at': None, |
|
|
|
'is_online': False, |
|
|
|
'has_attended': False |
|
|
|
}) |
|
|
|
|
|
|
|
# Also append any attendees who are NOT in the participants list (e.g. professor/moderator/observer) |
|
|
|
participant_student_ids = {p.student_id for p in participants} |
|
|
|
for user_id, attendance in attendance_map.items(): |
|
|
|
if user_id not in participant_student_ids: |
|
|
|
data.append({ |
|
|
|
'id': attendance.id, |
|
|
|
'session': obj.id, |
|
|
|
'user': user_id, |
|
|
|
'user_name': attendance.user.fullname or attendance.user.username, |
|
|
|
'user_email': attendance.user.email, |
|
|
|
'role': attendance.role, |
|
|
|
'entered_at': attendance.entered_at.isoformat() if attendance.entered_at else None, |
|
|
|
'exited_at': attendance.exited_at.isoformat() if attendance.exited_at else None, |
|
|
|
'is_online': attendance.is_online, |
|
|
|
'has_attended': True |
|
|
|
}) |
|
|
|
|
|
|
|
return data |
|
|
|
|