forked from rc/aircox
168 lines
5.3 KiB
Python
168 lines
5.3 KiB
Python
from django.contrib.auth.mixins import UserPassesTestMixin
|
|
from django.http import HttpResponseRedirect
|
|
from django.shortcuts import get_object_or_404
|
|
from django.urls import reverse
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views.generic.base import View
|
|
|
|
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",
|
|
"EpisodeCreateView",
|
|
"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 get_form_kwargs(self, *args, **kwargs):
|
|
"""Render selected attribute on option 0."""
|
|
fk = super().get_form_kwargs(*args, **kwargs)
|
|
if not fk["instance"].status:
|
|
fk["initial"]["status"] = "0"
|
|
return fk
|
|
|
|
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
|
|
|
|
|
|
class EpisodeCreateView(UserPassesTestMixin, View):
|
|
def get(self, request, **kwargs):
|
|
program = self.get_object()
|
|
episode = Episode.objects.create(program=program, title="%s (%s)" % (program.title, _("draft")))
|
|
return HttpResponseRedirect(reverse("episode-edit", kwargs={"pk": episode.pk}))
|
|
|
|
def test_func(self):
|
|
program = self.get_object()
|
|
return permissions.program.can(self.request.user, "update", program)
|
|
|
|
def get_object(self):
|
|
return get_object_or_404(Program, pk=self.kwargs["pk"])
|