Dispatcharr/apps/vod/serializers.py
2025-08-22 16:59:00 -04:00

237 lines
8.5 KiB
Python

from rest_framework import serializers
from .models import (
Series, VODCategory, Movie, Episode,
M3USeriesRelation, M3UMovieRelation, M3UEpisodeRelation, M3UVODCategoryRelation
)
from apps.channels.serializers import LogoSerializer
from apps.m3u.serializers import M3UAccountSerializer
class M3UVODCategoryRelationSerializer(serializers.ModelSerializer):
category = serializers.IntegerField(source="category.id")
m3u_account = serializers.IntegerField(source="m3u_account.id")
class Meta:
model = M3UVODCategoryRelation
fields = ["category", "m3u_account", "enabled"]
class VODCategorySerializer(serializers.ModelSerializer):
category_type_display = serializers.CharField(source='get_category_type_display', read_only=True)
m3u_accounts = M3UVODCategoryRelationSerializer(many=True, source="m3u_relations", read_only=True)
class Meta:
model = VODCategory
fields = [
"id",
"name",
"category_type",
"category_type_display",
"m3u_accounts",
]
class SeriesSerializer(serializers.ModelSerializer):
logo = LogoSerializer(read_only=True)
episode_count = serializers.SerializerMethodField()
class Meta:
model = Series
fields = '__all__'
def get_episode_count(self, obj):
return obj.episodes.count()
class MovieSerializer(serializers.ModelSerializer):
logo = LogoSerializer(read_only=True)
class Meta:
model = Movie
fields = '__all__'
class EpisodeSerializer(serializers.ModelSerializer):
series = SeriesSerializer(read_only=True)
class Meta:
model = Episode
fields = '__all__'
class M3USeriesRelationSerializer(serializers.ModelSerializer):
series = SeriesSerializer(read_only=True)
category = VODCategorySerializer(read_only=True)
m3u_account = M3UAccountSerializer(read_only=True)
class Meta:
model = M3USeriesRelation
fields = '__all__'
class M3UMovieRelationSerializer(serializers.ModelSerializer):
movie = MovieSerializer(read_only=True)
category = VODCategorySerializer(read_only=True)
m3u_account = M3UAccountSerializer(read_only=True)
quality_info = serializers.SerializerMethodField()
class Meta:
model = M3UMovieRelation
fields = '__all__'
def get_quality_info(self, obj):
"""Extract quality information from various sources"""
quality_info = {}
# 1. Check custom_properties first
if obj.custom_properties:
if obj.custom_properties.get('quality'):
quality_info['quality'] = obj.custom_properties['quality']
return quality_info
elif obj.custom_properties.get('resolution'):
quality_info['resolution'] = obj.custom_properties['resolution']
return quality_info
# 2. Try to get detailed info from the movie if available
movie = obj.movie
if hasattr(movie, 'video') and movie.video:
video_data = movie.video
if isinstance(video_data, dict) and 'width' in video_data and 'height' in video_data:
width = video_data['width']
height = video_data['height']
quality_info['resolution'] = f"{width}x{height}"
# Convert to common quality names (prioritize width for ultrawide/cinematic content)
if width >= 3840:
quality_info['quality'] = '4K'
elif width >= 1920:
quality_info['quality'] = '1080p'
elif width >= 1280:
quality_info['quality'] = '720p'
elif width >= 854:
quality_info['quality'] = '480p'
else:
quality_info['quality'] = f"{width}x{height}"
return quality_info
# 3. Extract from movie name/title
if movie and movie.name:
name = movie.name
if '4K' in name or '2160p' in name:
quality_info['quality'] = '4K'
return quality_info
elif '1080p' in name or 'FHD' in name:
quality_info['quality'] = '1080p'
return quality_info
elif '720p' in name or 'HD' in name:
quality_info['quality'] = '720p'
return quality_info
elif '480p' in name:
quality_info['quality'] = '480p'
return quality_info
# 4. Try bitrate as last resort
if hasattr(movie, 'bitrate') and movie.bitrate and movie.bitrate > 0:
bitrate = movie.bitrate
if bitrate >= 6000:
quality_info['quality'] = '4K'
elif bitrate >= 3000:
quality_info['quality'] = '1080p'
elif bitrate >= 1500:
quality_info['quality'] = '720p'
else:
quality_info['bitrate'] = f"{round(bitrate/1000)}Mbps"
return quality_info
# 5. Fallback - no quality info available
return None
class M3UEpisodeRelationSerializer(serializers.ModelSerializer):
episode = EpisodeSerializer(read_only=True)
m3u_account = M3UAccountSerializer(read_only=True)
quality_info = serializers.SerializerMethodField()
class Meta:
model = M3UEpisodeRelation
fields = '__all__'
def get_quality_info(self, obj):
"""Extract quality information from various sources"""
quality_info = {}
# 1. Check custom_properties first
if obj.custom_properties:
if obj.custom_properties.get('quality'):
quality_info['quality'] = obj.custom_properties['quality']
return quality_info
elif obj.custom_properties.get('resolution'):
quality_info['resolution'] = obj.custom_properties['resolution']
return quality_info
# 2. Try to get detailed info from the episode if available
episode = obj.episode
if hasattr(episode, 'video') and episode.video:
video_data = episode.video
if isinstance(video_data, dict) and 'width' in video_data and 'height' in video_data:
width = video_data['width']
height = video_data['height']
quality_info['resolution'] = f"{width}x{height}"
# Convert to common quality names (prioritize width for ultrawide/cinematic content)
if width >= 3840:
quality_info['quality'] = '4K'
elif width >= 1920:
quality_info['quality'] = '1080p'
elif width >= 1280:
quality_info['quality'] = '720p'
elif width >= 854:
quality_info['quality'] = '480p'
else:
quality_info['quality'] = f"{width}x{height}"
return quality_info
# 3. Extract from episode name/title
if episode and episode.name:
name = episode.name
if '4K' in name or '2160p' in name:
quality_info['quality'] = '4K'
return quality_info
elif '1080p' in name or 'FHD' in name:
quality_info['quality'] = '1080p'
return quality_info
elif '720p' in name or 'HD' in name:
quality_info['quality'] = '720p'
return quality_info
elif '480p' in name:
quality_info['quality'] = '480p'
return quality_info
# 4. Try bitrate as last resort
if hasattr(episode, 'bitrate') and episode.bitrate and episode.bitrate > 0:
bitrate = episode.bitrate
if bitrate >= 6000:
quality_info['quality'] = '4K'
elif bitrate >= 3000:
quality_info['quality'] = '1080p'
elif bitrate >= 1500:
quality_info['quality'] = '720p'
else:
quality_info['bitrate'] = f"{round(bitrate/1000)}Mbps"
return quality_info
# 5. Fallback - no quality info available
return None
class EnhancedSeriesSerializer(serializers.ModelSerializer):
"""Enhanced serializer for series with provider information"""
logo = LogoSerializer(read_only=True)
providers = M3USeriesRelationSerializer(source='m3u_relations', many=True, read_only=True)
episode_count = serializers.SerializerMethodField()
class Meta:
model = Series
fields = '__all__'
def get_episode_count(self, obj):
return obj.episodes.count()