127 lines
7.0 KiB
Python
127 lines
7.0 KiB
Python
"""
|
||
Сигналы для видеоконференций.
|
||
"""
|
||
import logging
|
||
from django.db.models.signals import post_save
|
||
from django.dispatch import receiver
|
||
from django.utils import timezone
|
||
from apps.schedule.models import Lesson
|
||
from .models import VideoRoom
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
@receiver(post_save, sender=Lesson)
|
||
def create_video_room_for_lesson(sender, instance, created, **kwargs):
|
||
"""
|
||
Автоматическое создание видеокомнаты и ссылки на встречу при создании занятия.
|
||
"""
|
||
# Создаем комнату для всех занятий (не только confirmed)
|
||
if created or not hasattr(instance, 'video_room'):
|
||
try:
|
||
# Проверяем, есть ли уже комната
|
||
try:
|
||
video_room = instance.video_room
|
||
except VideoRoom.DoesNotExist:
|
||
video_room = None
|
||
|
||
if not video_room:
|
||
video_room = VideoRoom.objects.create(
|
||
lesson=instance,
|
||
mentor=instance.mentor,
|
||
client=instance.client,
|
||
is_recording=True, # По умолчанию включаем запись
|
||
max_participants=2
|
||
)
|
||
|
||
logger.info(f'Создана видеокомната {video_room.room_id} для занятия {instance.id}')
|
||
|
||
# Создаем или обновляем meeting_url на основе видеокомнаты (LiveKit)
|
||
from django.conf import settings
|
||
if not instance.meeting_url:
|
||
# Используем LiveKit вместо старого video room
|
||
# ВАЖНО: включаем lesson_id для синхронизации доски между пользователями
|
||
meeting_url = f'{settings.FRONTEND_URL}/livekit/{video_room.room_id}?lesson_id={instance.id}'
|
||
instance.meeting_url = meeting_url
|
||
# Сохраняем без вызова сигналов, чтобы избежать рекурсии
|
||
Lesson.objects.filter(id=instance.id).update(meeting_url=meeting_url)
|
||
logger.info(f'Создана ссылка на LiveKit встречу для занятия {instance.id}: {meeting_url}')
|
||
|
||
# Планируем автоматическое удаление видеокомнаты через 10 минут после окончания занятия
|
||
if instance.end_time:
|
||
from .tasks import schedule_video_room_deletion
|
||
schedule_video_room_deletion.delay(instance.id)
|
||
logger.info(f'Запланировано автоматическое удаление видеокомнаты для занятия {instance.id}')
|
||
|
||
# Отправляем уведомления о создании комнаты (только при создании)
|
||
if created:
|
||
from apps.notifications.services import NotificationService
|
||
|
||
meeting_link = f'/video/rooms/{video_room.room_id}/join/'
|
||
|
||
# Уведомление ментору
|
||
NotificationService.send_notification(
|
||
user=instance.mentor,
|
||
notification_type='video_room_created',
|
||
message=f'Создана видеокомната для занятия "{instance.title}"',
|
||
link=meeting_link
|
||
)
|
||
|
||
# Уведомление клиенту (если есть)
|
||
if instance.client:
|
||
try:
|
||
client_user = instance.client.user if hasattr(instance.client, 'user') else None
|
||
if client_user:
|
||
NotificationService.send_notification(
|
||
user=client_user,
|
||
notification_type='video_room_created',
|
||
message=f'Создана видеокомната для занятия "{instance.title}"',
|
||
link=meeting_link
|
||
)
|
||
except Exception as e:
|
||
logger.warning(f'Не удалось отправить уведомление клиенту для занятия {instance.id}: {str(e)}')
|
||
|
||
except Exception as e:
|
||
logger.error(f'Ошибка создания видеокомнаты для занятия {instance.id}: {str(e)}')
|
||
|
||
|
||
@receiver(post_save, sender=VideoRoom)
|
||
def handle_video_room_status_change(sender, instance, created, **kwargs):
|
||
"""
|
||
Обработка изменения статуса видеокомнаты.
|
||
"""
|
||
if not created:
|
||
# Если комната только что завершилась
|
||
if instance.status == 'ended' and instance.ended_at:
|
||
# Обновляем статус связанного занятия, если оно еще не завершено
|
||
try:
|
||
lesson = instance.lesson
|
||
if lesson.status in ['scheduled', 'in_progress']:
|
||
lesson.status = 'completed'
|
||
lesson.completed_at = timezone.now()
|
||
lesson.save(update_fields=['status', 'completed_at'])
|
||
logger.info(f'Статус занятия {lesson.id} обновлен на "completed" после завершения видеокомнаты')
|
||
except Exception as e:
|
||
logger.error(f'Ошибка обновления статуса занятия для видеокомнаты {instance.room_id}: {str(e)}')
|
||
|
||
# Генерируем лог звонка
|
||
from .tasks import generate_call_log
|
||
generate_call_log.delay(instance.id)
|
||
|
||
logger.info(f'Комната {instance.room_id} завершена, запущена генерация лога')
|
||
|
||
# Если есть запись, начинаем обработку
|
||
if instance.is_recording:
|
||
from .models import ScreenRecording
|
||
|
||
# Проверяем есть ли запись
|
||
try:
|
||
recording = ScreenRecording.objects.get(room=instance)
|
||
if recording.status == 'processing':
|
||
from .tasks import process_recording
|
||
process_recording.delay(recording.id)
|
||
logger.info(f'Запущена обработка записи {recording.id}')
|
||
except ScreenRecording.DoesNotExist:
|
||
logger.warning(f'Запись для комнаты {instance.room_id} не найдена')
|
||
|