Compare commits

..

1 Commits

Author SHA1 Message Date
5c6f3b1e0f misc: add in-site episode management for animators 2023-12-04 11:32:48 +01:00
8 changed files with 105 additions and 17 deletions

View File

@ -6,22 +6,13 @@
{% endblock %} {% endblock %}
{% block main %} {% block main %}
<h2 class="subtitle is-3">{% trans 'My programs' %}</h2> <h2 class="subtitle is-3">Mes émissions</h2>
{% if programs|length %} {% if programs|length %}
<ul> <ul>
{% for p in programs %} {% for p in programs %}
<li><a href="{% url 'program-detail' slug=p.slug %}">{{ p.title }}</a></li> <li><a href="{% url 'program-detail' slug=p.slug %}">{{ p.title }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
<br />
<h2 class="subtitle is-3">{% trans 'Episodes' %}</h2>
{% for e in episodes %}
<ul>
<li><a href="{% url 'episode-detail' slug=e.slug %}">{{ e.title }}</a></li>
</ul>
{% endfor %}
{% else %} {% else %}
{% trans 'You are not listed as a program editor yet' %} {% trans 'You are not listed as a program editor yet' %}
{% endif %} {% endif %}

View File

@ -5,6 +5,19 @@
{% include "aircox/program_sidebar.html" %} {% include "aircox/program_sidebar.html" %}
{% block top-nav-tools %}
{% has_perm page page.program.change_permission_codename simple=True as can_edit %}
{% if can_edit %}
<a class="navbar-item" href="{% url 'episode-edit' page.pk %}" target="_self">
<span class="icon is-small">
<i class="fa fa-pen"></i>
</span>&nbsp;
<span>{% translate "Edit" %}</span>
</a>
{% endif %}
{% endblock %}
{% block content %} {% block content %}
<a-episode :page="{title: &quot;{{ page.title }}&quot;, podcasts: {{ object.podcasts|json }}}"> <a-episode :page="{title: &quot;{{ page.title }}&quot;, podcasts: {{ object.podcasts|json }}}">
<template v-slot="{podcasts,page}"> <template v-slot="{podcasts,page}">

View File

@ -0,0 +1,30 @@
{% extends "aircox/basepage_detail.html" %}
{% load static i18n humanize honeypot aircox %}
{% block head_extra %}
{{ form.media }}
{% endblock %}
{% block init-scripts %}
{% endblock %}
{% block top-nav-tools %}
<a class="navbar-item" href="{% url 'episode-detail' object.slug %}" target="_self">
<span class="icon is-small">
<i class="fa fa-eye"></i>
</span>&nbsp;
<span>{% translate "View" %}</span>
</a>
{% endblock %}
{% block main %}
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<table>
{{ form.as_table }}
{% render_honeypot_field "website" %}
</table>
<br/>
<input type="submit" value="Update" class="button is-success">
</form>
{% endblock %}

View File

@ -47,6 +47,13 @@ Context variables:
{% block actions %} {% block actions %}
{% has_perm page object.program.change_permission_codename simple=True as can_edit %}
{% if can_edit %}
<a class="button" href="{% url 'episode-edit' object.pk %}" target="_self">
<span class="icon is-small"><i class="fas fa-pen" alt="{% trans 'edit' %}"></i></span>
</a>
{% endif %}
{% if object.sound_set.public.count %} {% if object.sound_set.public.count %}
<button class="button" @click="player.playButtonClick($event)" <button class="button" @click="player.playButtonClick($event)"
data-sounds="{{ object.podcasts|json }}"> data-sounds="{{ object.podcasts|json }}">

View File

@ -97,6 +97,11 @@ urls = [
views.ProgramUpdateView.as_view(), views.ProgramUpdateView.as_view(),
name="program-edit", name="program-edit",
), ),
path(
_("episode/<pk>/edit/"),
views.EpisodeUpdateView.as_view(),
name="episode-edit",
),
path( path(
_("programs/<slug:parent_slug>/episodes/"), _("programs/<slug:parent_slug>/episodes/"),
views.EpisodeListView.as_view(), views.EpisodeListView.as_view(),

View File

@ -2,7 +2,7 @@ from . import admin, errors
from .article import ArticleDetailView, ArticleListView from .article import ArticleDetailView, ArticleListView
from .base import BaseAPIView, BaseView from .base import BaseAPIView, BaseView
from .diffusion import DiffusionListView from .diffusion import DiffusionListView
from .episode import EpisodeDetailView, EpisodeListView from .episode import EpisodeDetailView, EpisodeListView, EpisodeUpdateView
from .home import HomeView from .home import HomeView
from .log import LogListAPIView, LogListView from .log import LogListAPIView, LogListView
from .page import ( from .page import (
@ -30,6 +30,7 @@ __all__ = (
"DiffusionListView", "DiffusionListView",
"EpisodeDetailView", "EpisodeDetailView",
"EpisodeListView", "EpisodeListView",
"EpisodeUpdateView",
"HomeView", "HomeView",
"LogListAPIView", "LogListAPIView",
"LogListView", "LogListView",

View File

@ -1,7 +1,17 @@
from django.contrib.auth.mixins import UserPassesTestMixin
from django.forms import ModelForm, FileField
from django.urls import reverse
from ckeditor.fields import RichTextField
from filer.models.filemodels import File
from aircox.controllers.sound_file import SoundFile
from ..filters import EpisodeFilters from ..filters import EpisodeFilters
from ..models import Episode, Program, StaticPage from ..models import Episode, Program, StaticPage
from .page import PageListView from .page import PageListView
from .program import ProgramPageDetailView from .program import ProgramPageDetailView, BaseProgramMixin
from .page import PageUpdateView
__all__ = ( __all__ = (
"EpisodeDetailView", "EpisodeDetailView",
@ -25,3 +35,36 @@ class EpisodeListView(PageListView):
has_headline = True has_headline = True
parent_model = Program parent_model = Program
attach_to_value = StaticPage.ATTACH_TO_EPISODES attach_to_value = StaticPage.ATTACH_TO_EPISODES
class EpisodeForm(ModelForm):
content = RichTextField()
new_podcast = FileField(required=False)
class Meta:
model = Episode
fields = ["content"]
def save(self, commit=True):
file_obj = self.cleaned_data["new_podcast"]
if file_obj:
obj, _ = File.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
sound_file = SoundFile(obj.path)
sound_file.sync(
program=self.instance.program, episode=self.instance, type=0, is_public=True, is_downloadable=True
)
class EpisodeUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
model = Episode
form_class = EpisodeForm
def get_sidebar_queryset(self):
return super().get_sidebar_queryset().filter(parent=self.program)
def test_func(self):
program = self.get_object().program
return self.request.user.has_perm("aircox.%s" % program.change_permission_codename)
def get_success_url(self):
return reverse("episode-detail", kwargs={"slug": self.get_object().slug})

View File

@ -1,17 +1,15 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from aircox.models import Episode, Program from aircox.models import Program
@login_required @login_required
def profile(request): def profile(request):
programs, episodes = [], [] programs = []
ugroups = request.user.groups.all() ugroups = request.user.groups.all()
for p in Program.objects.all(): for p in Program.objects.all():
if p.editors in ugroups: if p.editors in ugroups:
programs.append(p) programs.append(p)
for e in Episode.objects.filter(parent=p): context = {"user": request.user, "programs": programs}
episodes.append(e)
context = {"user": request.user, "programs": programs, "episodes": episodes}
return TemplateResponse(request, "accounts/profile.html", context) return TemplateResponse(request, "accounts/profile.html", context)