cfr #121 Co-authored-by: Christophe Siraut <d@tobald.eu.org> Co-authored-by: bkfox <thomas bkfox net> Co-authored-by: Thomas Kairos <thomas@bkfox.net> Reviewed-on: #131 Co-authored-by: Chris Tactic <ctactic@noreply.git.radiocampus.be> Co-committed-by: Chris Tactic <ctactic@noreply.git.radiocampus.be>
138 lines
4.1 KiB
Python
138 lines
4.1 KiB
Python
import os
|
|
|
|
from django.conf import settings as d_settings
|
|
from django.db import models
|
|
from django.utils.functional import cached_property
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from aircox.conf import settings
|
|
|
|
from .page import ChildPage
|
|
from .program import ProgramChildQuerySet
|
|
from .sound import Sound
|
|
|
|
__all__ = ("Episode",)
|
|
|
|
|
|
class EpisodeQuerySet(ProgramChildQuerySet):
|
|
def with_podcasts(self):
|
|
return self.filter(episodesound__sound__is_public=True).distinct()
|
|
|
|
|
|
class Episode(ChildPage):
|
|
objects = EpisodeQuerySet.as_manager()
|
|
detail_url_name = "episode-detail"
|
|
list_url_name = "episode-list"
|
|
edit_url_name = "episode-edit"
|
|
template_prefix = "episode"
|
|
|
|
@property
|
|
def program(self):
|
|
return self.parent_subclass
|
|
|
|
@program.setter
|
|
def program(self, value):
|
|
self.parent = value
|
|
|
|
@cached_property
|
|
def podcasts(self):
|
|
"""Return serialized data about podcasts."""
|
|
query = self.episodesound_set.all().public().order_by("-broadcast", "position")
|
|
return self._to_podcasts(query)
|
|
|
|
@cached_property
|
|
def sounds(self):
|
|
"""Return serialized data about all related sounds."""
|
|
query = self.episodesound_set.all().order_by("-broadcast", "position")
|
|
return self._to_podcasts(query)
|
|
|
|
def _to_podcasts(self, query):
|
|
from ..serializers import EpisodeSoundSerializer as serializer_class
|
|
|
|
query = query.select_related("sound")
|
|
podcasts = [serializer_class(s).data for s in query]
|
|
for index, podcast in enumerate(podcasts):
|
|
podcasts[index]["page_url"] = self.get_absolute_url()
|
|
podcasts[index]["page_title"] = self.title
|
|
return podcasts
|
|
|
|
class Meta:
|
|
verbose_name = _("Episode")
|
|
verbose_name_plural = _("Episodes")
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self.parent is None:
|
|
raise ValueError("missing parent program")
|
|
super().save(*args, **kwargs)
|
|
|
|
@classmethod
|
|
def get_default_title(cls, page, date):
|
|
return settings.EPISODE_TITLE.format(
|
|
program=page,
|
|
date=date.strftime(settings.EPISODE_TITLE_DATE_FORMAT),
|
|
)
|
|
|
|
@classmethod
|
|
def get_init_kwargs_from(cls, page, date=None, title=None, **kwargs):
|
|
"""Get default Episode's title."""
|
|
title = (
|
|
settings.EPISODE_TITLE.format(
|
|
program=page,
|
|
date=date.strftime(settings.EPISODE_TITLE_DATE_FORMAT),
|
|
)
|
|
if title is None
|
|
else title
|
|
)
|
|
return super().get_init_kwargs_from(page, title=title, program=page, **kwargs)
|
|
|
|
|
|
class EpisodeSoundQuerySet(models.QuerySet):
|
|
def episode(self, episode):
|
|
if isinstance(episode, int):
|
|
return self.filter(episode_id=episode)
|
|
return self.filter(episode=episode)
|
|
|
|
def available(self):
|
|
return self.filter(sound__is_removed=False)
|
|
|
|
def public(self):
|
|
return self.filter(sound__is_public=True)
|
|
|
|
def broadcast(self):
|
|
return self.available().filter(broadcast=True)
|
|
|
|
def playlist(self, order="position"):
|
|
# TODO: subquery expression
|
|
if order:
|
|
self = self.order_by(order)
|
|
query = self.filter(sound__file__isnull=False, sound__is_removed=False).values_list("sound__file", flat=True)
|
|
return [os.path.join(d_settings.MEDIA_ROOT, file) for file in query]
|
|
|
|
|
|
class EpisodeSound(models.Model):
|
|
"""Element of an episode playlist."""
|
|
|
|
episode = models.ForeignKey(Episode, on_delete=models.CASCADE)
|
|
sound = models.ForeignKey(Sound, on_delete=models.CASCADE)
|
|
position = models.PositiveSmallIntegerField(
|
|
_("order"),
|
|
default=0,
|
|
help_text=_("position in the playlist"),
|
|
)
|
|
broadcast = models.BooleanField(
|
|
_("Broadcast"),
|
|
blank=None,
|
|
help_text=_("The sound is broadcasted on air"),
|
|
)
|
|
|
|
objects = EpisodeSoundQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
verbose_name = _("Podcast")
|
|
verbose_name_plural = _("Podcasts")
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self.broadcast is None:
|
|
self.broadcast = self.sound.broadcast
|
|
super().save(*args, **kwargs)
|