gukgjzkgjhgjh
This commit is contained in:
105
backend/thirdparty/downloader/serializers.py
vendored
105
backend/thirdparty/downloader/serializers.py
vendored
@@ -1,9 +1,110 @@
|
||||
from rest_framework import serializers
|
||||
from django.db.models import Count, Avg, Sum, Q
|
||||
from django.db.models.functions import TruncDay, TruncHour
|
||||
|
||||
|
||||
class DownloaderRecordSerializer(serializers.Serializer):
|
||||
"""Single download history entry."""
|
||||
id = serializers.IntegerField()
|
||||
url = serializers.URLField()
|
||||
title = serializers.CharField()
|
||||
platform = serializers.CharField()
|
||||
format = serializers.CharField()
|
||||
video_quality = serializers.IntegerField(allow_null=True)
|
||||
is_audio_only = serializers.BooleanField()
|
||||
length_of_media = serializers.IntegerField(allow_null=True)
|
||||
file_size = serializers.IntegerField(allow_null=True)
|
||||
processing_time = serializers.FloatField(allow_null=True)
|
||||
success = serializers.BooleanField()
|
||||
error_message = serializers.CharField()
|
||||
download_time = serializers.DateTimeField()
|
||||
|
||||
|
||||
class PlatformCountSerializer(serializers.Serializer):
|
||||
platform = serializers.CharField()
|
||||
count = serializers.IntegerField()
|
||||
|
||||
|
||||
class QualityCountSerializer(serializers.Serializer):
|
||||
video_quality = serializers.IntegerField(allow_null=True)
|
||||
count = serializers.IntegerField()
|
||||
|
||||
|
||||
class TimeseriesPointSerializer(serializers.Serializer):
|
||||
period = serializers.DateTimeField()
|
||||
count = serializers.IntegerField()
|
||||
|
||||
|
||||
class TopUrlSerializer(serializers.Serializer):
|
||||
url = serializers.URLField()
|
||||
title = serializers.CharField()
|
||||
count = serializers.IntegerField()
|
||||
|
||||
|
||||
class DownloaderStatsSerializer(serializers.Serializer):
|
||||
# Totals
|
||||
total_downloads = serializers.IntegerField()
|
||||
successful_downloads = serializers.IntegerField()
|
||||
failed_downloads = serializers.IntegerField()
|
||||
success_rate = serializers.FloatField(help_text="Percentage 0-100")
|
||||
|
||||
# Media metrics
|
||||
avg_length_of_media = serializers.FloatField(allow_null=True)
|
||||
avg_file_size = serializers.FloatField(allow_null=True)
|
||||
total_length_of_media = serializers.IntegerField(allow_null=True)
|
||||
avg_file_size = serializers.FloatField(allow_null=True)
|
||||
total_file_size = serializers.IntegerField(allow_null=True)
|
||||
most_common_format = serializers.CharField(allow_null=True)
|
||||
avg_processing_time = serializers.FloatField(allow_null=True)
|
||||
|
||||
# Format / quality breakdown
|
||||
most_common_format = serializers.CharField(allow_null=True)
|
||||
audio_only_count = serializers.IntegerField()
|
||||
video_count = serializers.IntegerField()
|
||||
downloads_by_platform = PlatformCountSerializer(many=True)
|
||||
downloads_by_quality = QualityCountSerializer(many=True)
|
||||
|
||||
# Top content
|
||||
most_downloaded_urls = TopUrlSerializer(many=True)
|
||||
|
||||
# Timeseries
|
||||
downloads_per_day = TimeseriesPointSerializer(many=True)
|
||||
downloads_per_hour = TimeseriesPointSerializer(many=True)
|
||||
|
||||
def to_representation(self, qs):
|
||||
agg = qs.aggregate(
|
||||
total_downloads=Count('id'),
|
||||
successful_downloads=Count('id', filter=Q(success=True)),
|
||||
failed_downloads=Count('id', filter=Q(success=False)),
|
||||
avg_length_of_media=Avg('length_of_media'),
|
||||
total_length_of_media=Sum('length_of_media'),
|
||||
avg_file_size=Avg('file_size'),
|
||||
total_file_size=Sum('file_size'),
|
||||
avg_processing_time=Avg('processing_time'),
|
||||
audio_only_count=Count('id', filter=Q(is_audio_only=True)),
|
||||
video_count=Count('id', filter=Q(is_audio_only=False)),
|
||||
)
|
||||
|
||||
total = agg['total_downloads'] or 0
|
||||
agg['success_rate'] = round(agg['successful_downloads'] / total * 100, 2) if total else 0.0
|
||||
|
||||
most_common = qs.values('format').annotate(count=Count('id')).order_by('-count').first()
|
||||
agg['most_common_format'] = most_common['format'] if most_common else None
|
||||
|
||||
agg['downloads_by_platform'] = list(
|
||||
qs.values('platform').annotate(count=Count('id')).order_by('-count')
|
||||
)
|
||||
agg['downloads_by_quality'] = list(
|
||||
qs.values('video_quality').annotate(count=Count('id')).order_by('-count')
|
||||
)
|
||||
agg['most_downloaded_urls'] = list(
|
||||
qs.values('url', 'title').annotate(count=Count('id')).order_by('-count')[:10]
|
||||
)
|
||||
agg['downloads_per_day'] = list(
|
||||
qs.annotate(period=TruncDay('download_time'))
|
||||
.values('period').annotate(count=Count('id')).order_by('period')
|
||||
)
|
||||
agg['downloads_per_hour'] = list(
|
||||
qs.annotate(period=TruncHour('download_time'))
|
||||
.values('period').annotate(count=Count('id')).order_by('period')
|
||||
)
|
||||
|
||||
return super().to_representation(agg)
|
||||
|
||||
Reference in New Issue
Block a user