|
|
|
@ -15,9 +15,10 @@ from drf_yasg import openapi |
|
|
|
import time |
|
|
|
import jwt |
|
|
|
from apps.course.models import Course, CourseLiveSession, Participant, LiveSessionRecording, LiveSessionUser |
|
|
|
from apps.course.models.lesson import Lesson, CourseLesson |
|
|
|
from apps.course.serializers import LiveSessionRoomCreateSerializer, LiveSessionTokenSerializer, LiveSessionRecordedFileSerializer, LiveSessionRecordingSerializer |
|
|
|
from apps.course.services.plugnmeet import PlugNMeetClient, PlugNMeetError |
|
|
|
from apps.course.services.web_egress import WebEgressClient, WebEgressError |
|
|
|
from apps.course.services.web_egress import WebEgressClient, WebEgressError, stop_session_web_egress_if_active |
|
|
|
from utils.exceptions import AppAPIException |
|
|
|
from django.conf import settings |
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
@ -138,6 +139,38 @@ def build_web_egress_title(session: CourseLiveSession) -> str: |
|
|
|
return session.recording_title or f"{session.subject} - Recording" |
|
|
|
|
|
|
|
|
|
|
|
def sync_session_recording_titles(session: CourseLiveSession) -> None: |
|
|
|
base_title = session.recording_title or session.subject |
|
|
|
recordings = list( |
|
|
|
LiveSessionRecording.objects.filter(session=session).order_by( |
|
|
|
"created_at", |
|
|
|
"id", |
|
|
|
) |
|
|
|
) |
|
|
|
total = len(recordings) |
|
|
|
if not total: |
|
|
|
return |
|
|
|
|
|
|
|
for index, recording in enumerate(recordings, start=1): |
|
|
|
title = base_title if total == 1 else f"{base_title} part {index}" |
|
|
|
|
|
|
|
if recording.title != title: |
|
|
|
recording.title = title |
|
|
|
recording.save(update_fields=["title", "updated_at"]) |
|
|
|
|
|
|
|
if not recording.file: |
|
|
|
continue |
|
|
|
|
|
|
|
lesson = Lesson.objects.filter(content_file=recording.file.name).first() |
|
|
|
if lesson and lesson.title != title: |
|
|
|
lesson.title = title |
|
|
|
lesson.save(update_fields=["title", "updated_at"]) |
|
|
|
CourseLesson.objects.filter(lesson=lesson).update( |
|
|
|
title=title, |
|
|
|
updated_at=timezone.now(), |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
class CourseLiveSessionRoomCreateAPIView(GenericAPIView): |
|
|
|
permission_classes = [IsAuthenticated] |
|
|
|
authentication_classes = [TokenAuthentication] |
|
|
|
@ -647,6 +680,7 @@ class CourseLiveSessionTokenAPIView(GenericAPIView): |
|
|
|
else: |
|
|
|
logger.warning(f"[Room Verify] ✗ Room is NOT active - room_id={session.room_id} session_id={session.id} msg={response_msg}") |
|
|
|
# Auto-close the session since room is not active |
|
|
|
stop_session_web_egress_if_active(session) |
|
|
|
now = timezone.now() |
|
|
|
session.ended_at = now |
|
|
|
session.save(update_fields=['ended_at', 'updated_at']) |
|
|
|
@ -670,6 +704,7 @@ class CourseLiveSessionTokenAPIView(GenericAPIView): |
|
|
|
|
|
|
|
# If room not found, close the session |
|
|
|
if 'not found' in error_msg.lower() or 'does not exist' in error_msg.lower(): |
|
|
|
stop_session_web_egress_if_active(session) |
|
|
|
now = timezone.now() |
|
|
|
session.ended_at = now |
|
|
|
session.save(update_fields=['ended_at', 'updated_at']) |
|
|
|
@ -1272,6 +1307,7 @@ class CourseLiveSessionSetRecordingTitleAPIView(GenericAPIView): |
|
|
|
|
|
|
|
session.recording_title = title.strip() |
|
|
|
session.save(update_fields=['recording_title', 'updated_at']) |
|
|
|
sync_session_recording_titles(session) |
|
|
|
|
|
|
|
logger.info(f"[LiveSession Title] Set recording title for room_id={room_id} to '{title}'") |
|
|
|
return Response({'success': True, 'message': 'Recording title updated successfully.'}, status=status.HTTP_200_OK) |