Browse Source

small bug fixes

dynamic time formatting for podcasts

video file type validations
master
Mohsen Taba 1 month ago
parent
commit
e372aac94d
  1. 31
      apps/podcast/serializers.py
  2. 19
      apps/video/models.py

31
apps/podcast/serializers.py

@ -20,6 +20,7 @@ class PodcastListSerializer(serializers.ModelSerializer):
audio_file = serializers.SerializerMethodField() audio_file = serializers.SerializerMethodField()
in_user_playlist = serializers.SerializerMethodField() in_user_playlist = serializers.SerializerMethodField()
share_link = serializers.CharField(read_only=True) share_link = serializers.CharField(read_only=True)
audio_time = serializers.SerializerMethodField()
class Meta: class Meta:
model = Podcast model = Podcast
@ -37,6 +38,15 @@ class PodcastListSerializer(serializers.ModelSerializer):
return request.build_absolute_uri(obj.audio_file.url) return request.build_absolute_uri(obj.audio_file.url)
return obj.audio_file.url return obj.audio_file.url
return None return None
def get_audio_time(self, obj):
if not obj.audio_time:
return None
# obj.audio_time is a datetime.time object
if obj.audio_time.hour == 0:
return obj.audio_time.strftime('%M:%S') # Returns "44:00"
return obj.audio_time.strftime('%H:%M:%S') # Returns "01:44:00"
def get_in_user_playlist(self, obj): def get_in_user_playlist(self, obj):
""" """
@ -62,7 +72,7 @@ class PodcastDetailSerializer(serializers.ModelSerializer):
playlist_podcasts = serializers.SerializerMethodField() playlist_podcasts = serializers.SerializerMethodField()
in_user_playlist = serializers.SerializerMethodField() in_user_playlist = serializers.SerializerMethodField()
share_link = serializers.CharField(read_only=True) share_link = serializers.CharField(read_only=True)
audio_time = serializers.SerializerMethodField()
class Meta: class Meta:
model = Podcast model = Podcast
fields = ['id', 'title', 'slug', 'thumbnail', 'description', fields = ['id', 'title', 'slug', 'thumbnail', 'description',
@ -86,6 +96,14 @@ class PodcastDetailSerializer(serializers.ModelSerializer):
service='podcast' service='podcast'
) )
return book_mark.get('is_bookmarked', False) return book_mark.get('is_bookmarked', False)
def get_audio_time(self, obj):
if not obj.audio_time:
return None
if obj.audio_time.hour == 0:
return obj.audio_time.strftime('%M:%S')
return obj.audio_time.strftime('%H:%M:%S')
def get_user_rate(self, obj): def get_user_rate(self, obj):
""" """
@ -200,14 +218,19 @@ class PodcastPlaylistListSerializer(serializers.ModelSerializer):
return get_thumbs(obj.thumbnail, self.context.get('request')) return get_thumbs(obj.thumbnail, self.context.get('request'))
def get_total_time_formatted(self, obj): def get_total_time_formatted(self, obj):
"""Format total_time as HH:MM:SS string"""
"""Format total_time dynamically as MM:SS or HH:MM:SS"""
if obj.total_time: if obj.total_time:
total_seconds = int(obj.total_time.total_seconds()) total_seconds = int(obj.total_time.total_seconds())
hours = total_seconds // 3600 hours = total_seconds // 3600
minutes = (total_seconds % 3600) // 60 minutes = (total_seconds % 3600) // 60
seconds = total_seconds % 60 seconds = total_seconds % 60
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
return "00:00:00"
# Strip hours if the playlist is under 60 mins
if hours > 0:
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
return f"{minutes:02d}:{seconds:02d}"
return "00:00"
def get_episodes_count(self, obj): def get_episodes_count(self, obj):
"""Return the number of episodes (podcasts) in this playlist""" """Return the number of episodes (podcasts) in this playlist"""

19
apps/video/models.py

@ -3,6 +3,8 @@ from django.utils.translation import gettext_lazy as _
from django.conf import settings from django.conf import settings
from filer.fields.image import FilerImageField from filer.fields.image import FilerImageField
from utils import generate_slug_for_model from utils import generate_slug_for_model
from django.core.validators import FileExtensionValidator
from django.core.exceptions import ValidationError
class VideoCategory(models.Model): class VideoCategory(models.Model):
@ -90,7 +92,11 @@ class Video(models.Model):
description = models.TextField(null=True) description = models.TextField(null=True)
video_type = models.CharField(max_length=255, choices=VedioTypeChoices.choices) video_type = models.CharField(max_length=255, choices=VedioTypeChoices.choices)
video_file = models.FileField(upload_to='video/videos/', null=True, blank=True)
video_file = models.FileField(upload_to='video/videos/', null=True, blank=True ,validators=[
FileExtensionValidator(
allowed_extensions=['mp4', 'mov', 'avi', 'mkv', 'webm']
)
])
video_url = models.CharField(max_length=655, null=True, blank=True) video_url = models.CharField(max_length=655, null=True, blank=True)
video_time = models.TimeField() video_time = models.TimeField()
@ -116,6 +122,17 @@ class Video(models.Model):
self.save(update_fields=['view_count']) self.save(update_fields=['view_count'])
return self.view_count return self.view_count
def clean(self):
super().clean()
if self.video_type == self.VedioTypeChoices.YOUTUBE_LINK and not self.video_url:
raise ValidationError({
'video_url': _('This field is required when video type is Link.')
})
if self.video_type == self.VedioTypeChoices.VIDEO_FILE and not self.video_file:
raise ValidationError({
'video_file': _('This field is required when video type is File.')
})
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.slug: if not self.slug:
self.slug = generate_slug_for_model(Video, self.title) self.slug = generate_slug_for_model(Video, self.title)

Loading…
Cancel
Save