Browse Source

live sessions name changed

master
Mohsen Taba 1 month ago
parent
commit
f2c84e9cbf
  1. 25
      apps/course/management/commands/assign_professors.py
  2. 133
      apps/course/tests/test_live_session_subjects.py
  3. 23
      apps/course/views/course.py
  4. 33
      apps/course/views/live_session.py

25
apps/course/management/commands/assign_professors.py

@ -1,25 +0,0 @@
from django.core.management.base import BaseCommand
from apps.course.models import Course
from apps.account.models import ProfessorUser
import random
class Command(BaseCommand):
help = 'Assign at least one professor to every course (if missing)'
def handle(self, *args, **options):
# Gather all active professors
professors = list(ProfessorUser.objects.filter(is_active=True))
if not professors:
self.stdout.write(self.style.ERROR('No active professors found.'))
return
updated = 0
for course in Course.objects.all():
if course.professors.exists():
continue # already has a professor
professor = random.choice(professors)
course.professors.add(professor)
updated += 1
self.stdout.write(f'Added professor {professor.id} to course {course.id}')
self.stdout.write(self.style.SUCCESS(f'Finished. Updated {updated} course(s).'))

133
apps/course/tests/test_live_session_subjects.py

@ -0,0 +1,133 @@
import tempfile
from unittest import mock
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import override_settings
from django.urls import reverse
from django.utils import timezone
from dj_language.models import Language
from rest_framework import status
from rest_framework.test import APITestCase
from apps.account.models import ProfessorUser
from apps.course.models import Course, CourseCategory, CourseLiveSession
from apps.course.views.course import get_course_slug_value
@override_settings(
PLUGNMEET_SERVER_URL='https://meet.example.com',
PLUGNMEET_API_KEY='test-key',
PLUGNMEET_API_SECRET='test-secret',
MEDIA_ROOT=tempfile.gettempdir(),
ONLINE_CLASS_FRONTEND_DOMAIN='http://testserver',
)
class CourseLiveSessionSubjectTests(APITestCase):
def setUp(self):
Language.objects.update_or_create(
id=69,
defaults={
'code': 'en',
'name': 'English',
'status': True,
'countries': [],
},
)
self.professor = ProfessorUser.objects.create(
email='subject-prof@example.com',
fullname='Subject Professor',
experience_years=5,
)
self.category = CourseCategory.objects.create(name='Category', slug='category')
thumbnail = SimpleUploadedFile('thumb.jpg', b'filecontent', content_type='image/jpeg')
self.course = Course.objects.create(
title=[{'title': 'Sample Course', 'language_code': 'en'}],
slug=[{'title': 'sample-course', 'language_code': 'en'}],
category=self.category,
thumbnail=thumbnail,
video_type=Course.VedioTypeChoices.YOUTUBE_LINK,
video_link='https://example.com/video',
is_online=True,
online_link='https://example.com/live',
level=[{'title': 'beginner', 'language_code': 'en'}],
duration=10,
lessons_count=2,
description=[{'title': 'Description', 'language_code': 'en'}],
short_description=[{'title': 'Short', 'language_code': 'en'}],
status=[{'title': 'ongoing', 'language_code': 'en'}],
is_free=True,
)
self.course.professors.add(self.professor)
@mock.patch('apps.course.views.live_session.PlugNMeetClient')
def test_room_create_uses_incremental_subject(self, mock_client_cls):
mock_client_cls.return_value.create_room.return_value = {'status': 'success'}
CourseLiveSession.objects.create(
course=self.course,
room_id='room-old',
subject='Live Session 1',
started_at=timezone.now(),
ended_at=timezone.now(),
)
self.client.force_authenticate(user=self.professor)
url = reverse(
'course-live-session-room-create',
kwargs={'slug': get_course_slug_value(self.course)},
)
response = self.client.post(url, {}, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
session = CourseLiveSession.objects.filter(
course=self.course,
ended_at__isnull=True,
).latest('id')
self.assertEqual(session.subject, 'Live Session 2')
@mock.patch('apps.course.views.course.PlugNMeetClient')
def test_validate_professor_create_uses_incremental_subject(self, mock_client_cls):
mock_client = mock_client_cls.return_value
mock_client.create_room.return_value = {'status': 'success'}
mock_client.get_join_token.return_value = {'token': 'teacher-access-token'}
CourseLiveSession.objects.create(
course=self.course,
room_id='room-old',
subject='Live Session 1',
started_at=timezone.now(),
ended_at=timezone.now(),
)
self.client.force_authenticate(user=self.professor)
url = reverse(
'course-online-validate',
kwargs={'slug': get_course_slug_value(self.course)},
)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
session = CourseLiveSession.objects.filter(
course=self.course,
ended_at__isnull=True,
).latest('id')
self.assertEqual(session.subject, 'Live Session 2')
def test_set_recording_title_updates_session_subject(self):
session = CourseLiveSession.objects.create(
course=self.course,
room_id='room-active',
subject='Live Session 1',
started_at=timezone.now(),
)
response = self.client.post(
reverse('course-live-session-set-recording-title'),
{
'room_id': session.room_id,
'title': 'machine learning',
},
format='json',
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
session.refresh_from_db()
self.assertEqual(session.recording_title, 'machine learning')
self.assertEqual(session.subject, 'machine learning')

23
apps/course/views/course.py

@ -758,27 +758,8 @@ class CourseOnlineClassTokenValidateAPIView(GenericAPIView):
@staticmethod @staticmethod
def _get_live_session_subject(course: Course) -> str: def _get_live_session_subject(course: Course) -> str:
title = ""
course_title = course.title
if isinstance(course_title, list):
for tr in course_title:
if isinstance(tr, dict) and tr.get('language_code') == 'en':
val = tr.get('title') or tr.get('text') or tr.get('value') or tr.get('name')
if val:
title = str(val).strip()
break
if not title:
for tr in course_title:
if isinstance(tr, dict) and tr.get('language_code') == 'ru':
val = tr.get('title') or tr.get('text') or tr.get('value') or tr.get('name')
if val:
title = str(val).strip()
break
if not title:
title = extract_text_from_json(course_title)
if not title:
title = "Course"
return f"{title} Live Session"
next_session_number = course.live_sessions.count() + 1
return f"Live Session {next_session_number}"
def _build_live_room_metadata(self, subject: str) -> dict: def _build_live_room_metadata(self, subject: str) -> dict:
return { return {

33
apps/course/views/live_session.py

@ -25,28 +25,8 @@ logger = logging.getLogger(__name__)
def get_live_session_subject(course): def get_live_session_subject(course):
title = ""
course_title = course.title
if isinstance(course_title, list):
for tr in course_title:
if isinstance(tr, dict) and tr.get('language_code') == 'en':
val = tr.get('title') or tr.get('text') or tr.get('value') or tr.get('name')
if val:
title = str(val).strip()
break
if not title:
for tr in course_title:
if isinstance(tr, dict) and tr.get('language_code') == 'ru':
val = tr.get('title') or tr.get('text') or tr.get('value') or tr.get('name')
if val:
title = str(val).strip()
break
if not title:
from apps.course.models.course import extract_text_from_json
title = extract_text_from_json(course_title)
if not title:
title = "Course"
return f"{title} Live Session"
next_session_number = course.live_sessions.count() + 1
return f"Live Session {next_session_number}"
def get_plugnmeet_webhook_url() -> str: def get_plugnmeet_webhook_url() -> str:
@ -1300,13 +1280,18 @@ class CourseLiveSessionSetRecordingTitleAPIView(GenericAPIView):
if not room_id or not title: if not room_id or not title:
raise AppAPIException({'message': 'room_id and title are required.'}, status_code=status.HTTP_400_BAD_REQUEST) raise AppAPIException({'message': 'room_id and title are required.'}, status_code=status.HTTP_400_BAD_REQUEST)
title = title.strip()
if not title:
raise AppAPIException({'message': 'title cannot be empty.'}, status_code=status.HTTP_400_BAD_REQUEST)
try: try:
session = CourseLiveSession.objects.get(room_id=room_id, ended_at__isnull=True) session = CourseLiveSession.objects.get(room_id=room_id, ended_at__isnull=True)
except CourseLiveSession.DoesNotExist: except CourseLiveSession.DoesNotExist:
raise AppAPIException({'message': 'Active session not found.'}, status_code=status.HTTP_404_NOT_FOUND) raise AppAPIException({'message': 'Active session not found.'}, status_code=status.HTTP_404_NOT_FOUND)
session.recording_title = title.strip()
session.save(update_fields=['recording_title', 'updated_at'])
session.recording_title = title
session.subject = title
session.save(update_fields=['recording_title', 'subject', 'updated_at'])
sync_session_recording_titles(session) sync_session_recording_titles(session)
logger.info(f"[LiveSession Title] Set recording title for room_id={room_id} to '{title}'") logger.info(f"[LiveSession Title] Set recording title for room_id={room_id} to '{title}'")

Loading…
Cancel
Save