Browse Source

media file urls enhancements

master
Mohsen Taba 2 months ago
parent
commit
4125cf4974
  1. 70
      apps/course/serializers/admin.py
  2. 31
      utils/__init__.py

70
apps/course/serializers/admin.py

@ -1,4 +1,4 @@
from rest_framework import serializers
from rest_framework import serializers
from utils import FileFieldSerializer, get_thumbs from utils import FileFieldSerializer, get_thumbs
from apps.course.models import ( from apps.course.models import (
Course, Course,
@ -12,7 +12,8 @@ from apps.course.models import (
Glossary, Glossary,
CourseLiveSession, CourseLiveSession,
LiveSessionUser, LiveSessionUser,
LiveSessionRecording
LiveSessionRecording,
Participant
) )
from apps.account.models import ProfessorUser from apps.account.models import ProfessorUser
from apps.course.models.course import extract_text_from_json, get_localized_field 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): class AdminLiveSessionDetailSerializer(serializers.ModelSerializer):
course_title = serializers.SerializerMethodField() course_title = serializers.SerializerMethodField()
user_sessions = AdminLiveSessionUserSerializer(many=True, read_only=True)
user_sessions = serializers.SerializerMethodField()
recordings = AdminLiveSessionRecordingSerializer(many=True, read_only=True) recordings = AdminLiveSessionRecordingSerializer(many=True, read_only=True)
recorded_file = FileFieldSerializer(required=False, allow_null=True) recorded_file = FileFieldSerializer(required=False, allow_null=True)
@ -516,3 +517,66 @@ class AdminLiveSessionDetailSerializer(serializers.ModelSerializer):
lang = get_request_lang(self) lang = get_request_lang(self)
return get_localized_field(lang, obj.course.title) 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

31
utils/__init__.py

@ -317,8 +317,35 @@ class FileFieldSerializer(serializers.CharField):
""" """
def get_rpath(self, p): def get_rpath(self, p):
# extract relative path of doc
return p[p.find('/static/') + 7:]
if not p:
return p
if not isinstance(p, str):
return p
# If /media/ is in the path, extract the relative path after the last /media/
if "/media/" in p:
idx = p.rfind("/media/")
return p[idx + 7:].lstrip('/')
# If /static/ is in the path, extract the relative path after the last /static/
if "/static/" in p:
idx = p.rfind("/static/")
return p[idx + 8:].lstrip('/')
# If it's a URL but doesn't contain /media/ or /static/
if "://" in p:
try:
parsed = urlparse(p)
path = parsed.path
if path.startswith('/media/'):
return path[7:].lstrip('/')
elif path.startswith('/static/'):
return path[8:].lstrip('/')
return path.lstrip('/')
except Exception:
pass
return p.lstrip('/')
def to_representation(self, value): def to_representation(self, value):
request = self.context.get('request', None) request = self.context.get('request', None)

Loading…
Cancel
Save