112 lines
4.9 KiB
Python
112 lines
4.9 KiB
Python
"""
|
||
Management команда для создания LiveKit комнат для существующих уроков.
|
||
"""
|
||
from django.core.management.base import BaseCommand
|
||
from django.utils import timezone
|
||
from datetime import timedelta
|
||
from apps.schedule.models import Lesson
|
||
from apps.video.livekit_service import LiveKitService
|
||
from apps.video.models import VideoRoom
|
||
|
||
|
||
class Command(BaseCommand):
|
||
help = 'Создаёт LiveKit комнаты для всех уроков, у которых их ещё нет'
|
||
|
||
def add_arguments(self, parser):
|
||
parser.add_argument(
|
||
'--all',
|
||
action='store_true',
|
||
help='Создать комнаты для всех уроков (включая прошедшие)',
|
||
)
|
||
parser.add_argument(
|
||
'--dry-run',
|
||
action='store_true',
|
||
help='Показать, что будет сделано, без фактического создания комнат',
|
||
)
|
||
|
||
def handle(self, *args, **options):
|
||
all_lessons = options['all']
|
||
dry_run = options['dry_run']
|
||
|
||
# Фильтруем уроки
|
||
queryset = Lesson.objects.filter(livekit_room_name='')
|
||
|
||
if not all_lessons:
|
||
# Только будущие уроки и уроки, которые закончились менее 15 минут назад
|
||
now = timezone.now()
|
||
cutoff_time = now - timedelta(minutes=15)
|
||
queryset = queryset.filter(end_time__gte=cutoff_time)
|
||
|
||
queryset = queryset.exclude(status='cancelled')
|
||
total = queryset.count()
|
||
|
||
if total == 0:
|
||
self.stdout.write(self.style.SUCCESS('Все уроки уже имеют LiveKit комнаты'))
|
||
return
|
||
|
||
self.stdout.write(f'Найдено {total} уроков без LiveKit комнат')
|
||
|
||
if dry_run:
|
||
self.stdout.write(self.style.WARNING('DRY RUN - комнаты не будут созданы'))
|
||
for lesson in queryset[:10]:
|
||
self.stdout.write(f' - Урок #{lesson.id}: {lesson.title} ({lesson.start_time})')
|
||
if total > 10:
|
||
self.stdout.write(f' ... и ещё {total - 10} уроков')
|
||
return
|
||
|
||
created_count = 0
|
||
error_count = 0
|
||
|
||
for lesson in queryset.iterator():
|
||
try:
|
||
# Генерируем уникальное название комнаты
|
||
room_name = LiveKitService.generate_room_name()
|
||
|
||
# Создаем VideoRoom запись
|
||
client_user = lesson.client.user if hasattr(lesson.client, 'user') else lesson.client
|
||
video_room, created = VideoRoom.objects.get_or_create(
|
||
lesson=lesson,
|
||
defaults={
|
||
'mentor': lesson.mentor,
|
||
'client': client_user,
|
||
'room_id': room_name,
|
||
'is_recording': True,
|
||
'max_participants': 10 if lesson.group else 2
|
||
}
|
||
)
|
||
|
||
if not created:
|
||
# VideoRoom уже существует, используем его room_id
|
||
room_name = str(video_room.room_id)
|
||
|
||
# Генерируем токен для ментора (действителен 24 часа)
|
||
mentor_token = LiveKitService.generate_access_token(
|
||
room_name=room_name,
|
||
participant_name=lesson.mentor.get_full_name(),
|
||
participant_identity=str(lesson.mentor.pk),
|
||
is_admin=True,
|
||
expires_in_minutes=1440 # 24 часа
|
||
)
|
||
|
||
# Сохраняем данные в урок
|
||
lesson.livekit_room_name = room_name
|
||
lesson.livekit_access_token = mentor_token
|
||
lesson.save(update_fields=['livekit_room_name', 'livekit_access_token'])
|
||
|
||
created_count += 1
|
||
|
||
if created_count % 10 == 0:
|
||
self.stdout.write(f'Создано комнат: {created_count}/{total}')
|
||
|
||
except Exception as e:
|
||
error_count += 1
|
||
self.stderr.write(
|
||
self.style.ERROR(f'Ошибка создания комнаты для урока #{lesson.id}: {str(e)}')
|
||
)
|
||
|
||
self.stdout.write(
|
||
self.style.SUCCESS(
|
||
f'Готово! Создано комнат: {created_count}, ошибок: {error_count}'
|
||
)
|
||
)
|