uchill/backend/apps/video/serializers.py

277 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Сериализаторы для видеоконференций.
"""
from rest_framework import serializers
from .models import VideoRoom, VideoParticipant, VideoCallLog, ScreenRecording
from apps.schedule.serializers import LessonSerializer
from apps.users.serializers import UserSerializer
class VideoParticipantSerializer(serializers.ModelSerializer):
"""Сериализатор участника видео."""
user = UserSerializer(read_only=True)
duration = serializers.SerializerMethodField()
class Meta:
model = VideoParticipant
fields = [
'id',
'user',
'is_connected',
'is_audio_enabled',
'is_video_enabled',
'is_screen_sharing',
'joined_at',
'left_at',
'duration',
'reconnection_count'
]
read_only_fields = [
'joined_at',
'left_at',
'reconnection_count'
]
def get_duration(self, obj):
"""Получить длительность в секундах."""
return obj.total_duration
class VideoRoomSerializer(serializers.ModelSerializer):
"""Сериализатор видеокомнаты."""
lesson = LessonSerializer(read_only=True)
mentor = UserSerializer(read_only=True)
client = UserSerializer(read_only=True)
participants = VideoParticipantSerializer(many=True, read_only=True)
actual_duration = serializers.IntegerField(read_only=True)
is_active = serializers.BooleanField(read_only=True)
class Meta:
model = VideoRoom
fields = [
'id',
'room_id',
'lesson',
'mentor',
'client',
'status',
'started_at',
'ended_at',
'duration',
'actual_duration',
'is_recording',
'recording_url',
'is_active',
'participants',
'quality_rating',
'quality_issues',
'created_at'
]
read_only_fields = [
'room_id',
'started_at',
'ended_at',
'duration',
'created_at'
]
class VideoRoomCreateSerializer(serializers.ModelSerializer):
"""Сериализатор создания видеокомнаты."""
lesson_id = serializers.IntegerField(write_only=True)
class Meta:
model = VideoRoom
fields = [
'lesson_id',
'is_recording',
'max_participants'
]
def validate_lesson_id(self, value):
"""Проверка занятия."""
from apps.schedule.models import Lesson
try:
lesson = Lesson.objects.get(id=value)
except Lesson.DoesNotExist:
raise serializers.ValidationError('Занятие не найдено')
# Проверяем что комната еще не создана
if hasattr(lesson, 'video_room'):
raise serializers.ValidationError('Видеокомната для этого занятия уже существует')
# Проверяем что занятие запланировано или в процессе (не отменено)
if lesson.status == 'cancelled':
raise serializers.ValidationError('Нельзя создать видеокомнату для отмененного занятия')
return value
def create(self, validated_data):
"""Создание видеокомнаты."""
from apps.schedule.models import Lesson
lesson_id = validated_data.pop('lesson_id')
lesson = Lesson.objects.get(id=lesson_id)
video_room = VideoRoom.objects.create(
lesson=lesson,
mentor=lesson.mentor,
client=lesson.client,
**validated_data
)
return video_room
class VideoRoomStartSerializer(serializers.Serializer):
"""Сериализатор начала видеозвонка."""
def validate(self, attrs):
"""Валидация."""
room = self.instance
if room.status != 'waiting':
raise serializers.ValidationError('Комната уже начата или завершена')
return attrs
def save(self):
"""Начать звонок."""
self.instance.start()
return self.instance
class VideoRoomEndSerializer(serializers.Serializer):
"""Сериализатор завершения видеозвонка."""
quality_rating = serializers.IntegerField(
min_value=1,
max_value=5,
required=False,
help_text='Оценка качества связи от 1 до 5'
)
quality_issues = serializers.CharField(
required=False,
allow_blank=True,
help_text='Описание проблем с качеством'
)
def validate(self, attrs):
"""Валидация."""
room = self.instance
if room.status != 'active':
raise serializers.ValidationError('Комната не активна')
return attrs
def save(self):
"""Завершить звонок."""
room = self.instance
room.end()
# Обновляем качество если указано
if 'quality_rating' in self.validated_data:
room.quality_rating = self.validated_data['quality_rating']
if 'quality_issues' in self.validated_data:
room.quality_issues = self.validated_data['quality_issues']
room.save()
return room
class VideoCallLogSerializer(serializers.ModelSerializer):
"""Сериализатор лога видеозвонка."""
room = VideoRoomSerializer(read_only=True)
class Meta:
model = VideoCallLog
fields = [
'id',
'room',
'total_participants',
'total_duration',
'average_bitrate',
'packet_loss_rate',
'average_jitter',
'connection_issues',
'audio_issues',
'video_issues',
'metadata',
'created_at'
]
read_only_fields = '__all__'
class ScreenRecordingSerializer(serializers.ModelSerializer):
"""Сериализатор записи видео."""
room_id = serializers.UUIDField(source='room.room_id', read_only=True)
lesson_title = serializers.CharField(source='room.lesson.title', read_only=True)
is_expired = serializers.BooleanField(read_only=True)
class Meta:
model = ScreenRecording
fields = [
'id',
'room_id',
'lesson_title',
'file_path',
'file_size',
'duration',
'url',
'status',
'is_public',
'is_expired',
'expires_at',
'created_at',
'processed_at'
]
read_only_fields = [
'file_path',
'file_size',
'duration',
'status',
'created_at',
'processed_at'
]
class ScreenRecordingCreateSerializer(serializers.Serializer):
"""Сериализатор создания записи."""
room_id = serializers.UUIDField()
def validate_room_id(self, value):
"""Проверка комнаты."""
try:
room = VideoRoom.objects.get(room_id=value)
except VideoRoom.DoesNotExist:
raise serializers.ValidationError('Комната не найдена')
# Проверяем что комната активна
if not room.is_active:
raise serializers.ValidationError('Комната не активна')
# Проверяем что запись включена
if not room.is_recording:
raise serializers.ValidationError('Запись не включена для этой комнаты')
return value
def create(self, validated_data):
"""Создание записи."""
room = VideoRoom.objects.get(room_id=validated_data['room_id'])
recording = ScreenRecording.objects.create(
room=room,
status='processing'
)
return recording