from django.contrib.auth.mixins import UserPassesTestMixin from django.urls import reverse from aircox.models import Episode, Program, StaticPage, Track from aircox import forms, filters, permissions from .mixins import VueFormDataMixin from .page import attach, PageDetailView, PageListView, PageUpdateView __all__ = ( "EpisodeDetailView", "EpisodeListView", "PodcastListView", "EpisodeUpdateView", ) class EpisodeDetailView(PageDetailView): model = Episode def can_edit(self, obj): return permissions.program.can(self.request.user, "update", obj) def get_context_data(self, **kwargs): if "tracks" not in kwargs: kwargs["tracks"] = self.object.track_set.order_by("position") return super().get_context_data(**kwargs) def get_related_queryset(self): return ( self.get_queryset().parent(self.object.parent).exclude(pk=self.object.pk).published().order_by("-pub_date") ) def get_related_url(self): return reverse("episode-list", kwargs={"parent_slug": self.object.parent.slug}) @attach class EpisodeListView(PageListView): model = Episode filterset_class = filters.EpisodeFilters parent_model = Program attach_to_value = StaticPage.Target.EPISODES @attach class PodcastListView(EpisodeListView): attach_to_value = StaticPage.Target.PODCASTS queryset = Episode.objects.published().with_podcasts().order_by("-pub_date") class EpisodeUpdateView(UserPassesTestMixin, VueFormDataMixin, PageUpdateView): model = Episode form_class = forms.EpisodeForm template_name = "aircox/episode_form.html" def can_edit(self, obj): return self.test_func() def test_func(self): obj = self.get_object() return permissions.program.can(self.request.user, "update", obj) def get_tracklist_queryset(self, episode): return Track.objects.filter(episode=episode).order_by("position") def get_tracklist_formset(self, episode, **kwargs): kwargs.update( { "prefix": "tracks", "queryset": self.get_tracklist_queryset(episode), "initial": [ { "episode": episode.id, } ], } ) return forms.TrackFormSet(**kwargs) def get_soundlist_queryset(self, episode): return episode.episodesound_set.all().select_related("sound").order_by("position") def get_soundlist_formset(self, episode, **kwargs): kwargs.update( { "prefix": "sounds", "queryset": self.get_soundlist_queryset(episode), "initial": [ { "episode": episode.id, } ], } ) return forms.EpisodeSoundFormSet(**kwargs) def get_sound_form(self, episode, **kwargs): kwargs.update( { "initial": { "program": episode.parent_id, "name": episode.title, "is_public": True, }, } ) return forms.SoundCreateForm(**kwargs) def get_context_data(self, **kwargs): forms = ( ("soundlist_formset", self.get_soundlist_formset), ("tracklist_formset", self.get_tracklist_formset), ("sound_form", self.get_sound_form), ) for key, func in forms: if key not in kwargs: kwargs[key] = func(self.object) for key in ("soundlist_formset", "tracklist_formset"): formset = kwargs[key] kwargs[f"{key}_data"] = self.get_formset_data(formset, {"episode": self.object.id}) return super().get_context_data(**kwargs) def post(self, request, *args, **kwargs): resp = super().post(request, *args, **kwargs) formsets = { "soundlist_formset": self.get_soundlist_formset(self.object, data=request.POST), "tracklist_formset": self.get_tracklist_formset(self.object, data=request.POST), } invalid = False for formset in formsets.values(): if not formset.is_valid(): invalid = True else: formset.save() if invalid: return self.get(request, **formsets) return resp