diff --git a/apps/course/views/live_session.py b/apps/course/views/live_session.py index 6aad5f0..52dfd68 100644 --- a/apps/course/views/live_session.py +++ b/apps/course/views/live_session.py @@ -53,89 +53,94 @@ class CourseLiveSessionRoomCreateAPIView(GenericAPIView): # 2. Setup ID and Metadata room_id = f"room-{course.id}-imamjavad" subject = f"{course.title} Live Session" - metadata = self._build_metadata(subject) - - # 3. Use your CLEAN PlugNMeetClient - try: - client = PlugNMeetClient() # Loads keys from settings automatically - - # This uses the keys internally to talk to the server - plugnmeet_response = client.create_room({ - 'room_id': room_id, - 'metadata': metadata, - }) - - # 4. Generate the JOIN TOKEN (The Entry Ticket) - # Users CANNOT enter without this. - token_payload = { - "room_id": room_id, - "user_info": { - "name": f"{request.user.first_name} {request.user.last_name}", - "user_id": str(request.user.id), - "is_admin": True, - "is_hidden": False - } - } - - # Check if your client has a method for this, otherwise use manual: - # access_token = client.get_join_token(token_payload) - # If not, we do it manually here using the SAME secret from settings: - - pnm_token = jwt.encode( - { - "iss": settings.PLUGNMEET_API_KEY, - "exp": int(time.time()) + 3600, - "sub": str(request.user.id), - **token_payload - }, - settings.PLUGNMEET_API_SECRET, - algorithm="HS256" - ) - - except Exception as exc: - logger.error(f"PlugNMeet Error: {exc}") - raise AppAPIException({'message': str(exc)}, status_code=500) - - # 5. Database Logic + + # 3. Database Logic - Check FIRST before calling PlugNMeet # Strategy: # 1. Try to find active session (ended_at is NULL) # 2. If not found, try to find ended session with same room_id and reactivate it # 3. If not found, create new session + session = None + needs_room_creation = False + try: # Try to get active session first session = CourseLiveSession.objects.get( course=course, room_id=room_id, ended_at__isnull=True ) - created = False - logger.info(f"[LiveSession Create] Reusing active session - session_id={session.id} room_id={room_id}") + needs_room_creation = False + logger.info(f"[LiveSession Create] Found active session - session_id={session.id} room_id={room_id}") except CourseLiveSession.DoesNotExist: # No active session, check if there's an old one with same room_id try: session = CourseLiveSession.objects.get( course=course, room_id=room_id ) - # Reactivate the old session + # Reactivate the old session and mark for room recreation session.ended_at = None session.started_at = timezone.now() session.subject = subject session.save(update_fields=['ended_at', 'started_at', 'subject', 'updated_at']) - created = False + needs_room_creation = True logger.info(f"[LiveSession Create] Reactivated ended session - session_id={session.id} room_id={room_id}") except CourseLiveSession.DoesNotExist: - # No session exists at all, create new one + # No session exists at all, create new one and mark for room creation session = CourseLiveSession.objects.create( course=course, room_id=room_id, subject=subject, started_at=timezone.now() ) - created = True + needs_room_creation = True logger.info(f"[LiveSession Create] Created new session - session_id={session.id} room_id={room_id}") + # 4. Create room in PlugNMeet ONLY if needed + if needs_room_creation: + metadata = self._build_metadata(subject) + try: + client = PlugNMeetClient() + plugnmeet_response = client.create_room({ + 'room_id': room_id, + 'metadata': metadata, + }) + logger.info(f"[LiveSession Create] Room created in PlugNMeet - room_id={room_id}") + except Exception as exc: + logger.error(f"[LiveSession Create] PlugNMeet Error: {exc}") + # If room creation fails, revert the session changes + if session.ended_at is None: + session.ended_at = timezone.now() + session.save(update_fields=['ended_at', 'updated_at']) + raise AppAPIException({'message': f'Failed to create room: {str(exc)}'}, status_code=500) + else: + logger.info(f"[LiveSession Create] Skipping room creation - room already exists - room_id={room_id}") + + # 5. Generate the JOIN TOKEN (The Entry Ticket) + token_payload = { + "room_id": room_id, + "user_info": { + "name": f"{request.user.first_name} {request.user.last_name}", + "user_id": str(request.user.id), + "is_admin": True, + "is_hidden": False + } + } + + pnm_token = jwt.encode( + { + "iss": settings.PLUGNMEET_API_KEY, + "exp": int(time.time()) + 3600, + "sub": str(request.user.id), + **token_payload + }, + settings.PLUGNMEET_API_SECRET, + algorithm="HS256" + ) + + logger.info(f"[LiveSession Create] Success - session_id={session.id} room_id={room_id} user_id={request.user.id}") + return Response({ 'success': True, 'session': {'id': session.id, 'room_id': session.room_id}, - 'access_token': pnm_token # <--- REQUIRED for frontend + 'access_token': pnm_token }, status=201)