Ajout d'un mécanisme de modération en chaîne

This commit is contained in:
Jean-Marie Favreau 2024-11-16 22:06:28 +01:00
parent 0be3c30489
commit 493b42c457
8 changed files with 138 additions and 22 deletions

View File

@ -233,7 +233,6 @@ class EventModerateForm(ModelForm):
self.cleaned_data['tags'] = list(set(self.cleaned_data['tags']))
class BatchImportationForm(Form):
json = CharField(
label="JSON",

View File

@ -20,6 +20,10 @@
<article>
<header>
<div class="slide-buttons">
<a href="{% url 'moderate' %}" role="button">Modérer {% picto_from_name "check-square" %}</a>
</div>
<h2>Activité des derniers jours</h2>
</header>
<h3>Résumé des activités</h3>

View File

@ -1,5 +1,7 @@
{% extends "agenda_culturel/page.html" %}
{% load static %}
{% load utils_extra %}
{% load cat_extra %}
{% block title %}{% block og_title %}Modération de l'événement {{ object.title }}{% endblock %}{% endblock %}
@ -9,22 +11,7 @@
{% block entete_header %}
<script src="{% static 'choicejs/choices.min.js' %}"></script>
<script src="{% url 'jsi18n' %}"></script>
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
<script src="/static/admin/js/admin/DateTimeShortcuts.js"></script>
<script src="{% static 'recurrence/js/recurrence.js' %}"></script>
<script src="{% static 'recurrence/js/recurrence.js' %}"></script>
<script src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
<script>window.CKEDITOR_BASEPATH = '/static/ckeditor/ckeditor/';</script>
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
<link href="{% static 'css/django_better_admin_arrayfield.min.css' %}" type="text/css" media="all" rel="stylesheet">
<script src="{% static 'js/django_better_admin_arrayfield.min.js' %}"></script>
<script src="{% static 'js/adjust_datetimes.js' %}"></script>
{% css_categories %}
{% endblock %}
@ -61,8 +48,13 @@
</article>
</div>
<div class="grid buttons">
{% if pred %}
<a href="{% url 'moderate_event' pred %}" role="button">🠄 Revenir au précédent</a>
{% else %}
<a href="{% if request.META.HTTP_REFERER %}{{ request.META.HTTP_REFERER }}{% else %}{{ object.get_absolute_url }}{% endif %}" role="button" class="secondary">Annuler</a>
<input type="submit" value="Enregistrer">
{% endif %}
<input type="submit" value="Enregistrer" name="save">
<input type="submit" value="Enregistrer et passer au suivant 🠆" name="save_and_next">
</div>
</form>
</article>

View File

@ -0,0 +1,40 @@
{% extends "agenda_culturel/page.html" %}
{% load utils_extra %}
{% load static %}
{% block title %}{% block og_title %}Erreur pendant la recherche d'événement suivant{% endblock %}{% endblock %}
{% block entete_header %}
<script src="{% static 'js/modal.js' %}"></script>
{% endblock %}
{% block fluid %}{% endblock %}
{% block content %}
<article>
<header>
<h1>Erreur pendant la recherche d'événement suivant</h1>
</header>
{% if object %}
<p>Nous n'avons pas été capable de trouver un événement à modérer après
l'événement <a href="{{ object.get_absolute_url }}">{{ object.title }}</a>. Peut-être est-ce le dernier événement
avant la fin du monde&nbsp;?
</p>
{% else %}
<p>Nous n'avons pas été capable de trouver l'événement #{{ pk }} sur l'agenda.
Il a certainement été supprimé depuis que vous l'avez consulté.
</p>
{% endif %}
<footer>
<div class="grid buttons">
<a href="{% url 'recent' %}" role="button">Retour aux événements récents</a>
</div>
</footer>
</article>
{% endblock %}

View File

@ -18,6 +18,10 @@
<div class="grid two-columns">
<article id="contenu-principal">
<header>
<div class="slide-buttons">
<a href="{% url 'moderate' %}" role="button">Modérer {% picto_from_name "check-square" %}</a>
</div>
<h1>Derniers événements soumis</h1>
<form method="get" class="form django-form recent moderation-events">

View File

@ -1,10 +1,11 @@
{% load event_extra %}
{% load contactmessages_extra %}
{% load duplicated_extra %}
{% load utils_extra %}
<aside id="sidebar">
<article>
<header>
<h2>Administrer</h2>
<h2>Administration</h2>
</header>
<nav>
<ul>

View File

@ -33,6 +33,9 @@ urlpatterns = [
),
path("event/<int:pk>/edit", EventUpdateView.as_view(), name="edit_event"),
path("event/<int:pk>/moderate", EventModerateView.as_view(), name="moderate_event"),
path("event/<int:pk>/moderate-next", EventModerateView.as_view(), name="moderate_event_next"),
path("event/<int:pk>/moderate-next/error", error_next_event, name="error_next_event"),
path("moderate", EventModerateView.as_view(), name="moderate"),
path("event/<int:pk>/clone/edit", EventUpdateView.as_view(), name="clone_edit"),
path("event/<int:pk>/update-from-source", update_from_source, name="update_from_source"),
path(

View File

@ -7,6 +7,7 @@ from django.contrib.auth.mixins import (
PermissionRequiredMixin,
)
from django import forms
from django.http import Http404
from django.contrib.postgres.search import SearchQuery, SearchHeadline
from django.utils.safestring import mark_safe
@ -343,12 +344,84 @@ class EventModerateView(
form_class = EventModerateForm
success_message = _("The event has been successfully moderated.")
def form_valid(self, form):
def is_moderate_next(self):
return "moderate-next" in self.request.path.split('/')
def is_starting_moderation(self):
return not "pk" in self.kwargs
def get_next_event(self, start_day, start_time):
# select non moderated events
qs = Event.objects.filter(moderated_date__isnull=True)
# select events after the current one
if start_time:
qs = qs.filter(Q(start_day__gt=start_day)|(Q(start_day=start_day) & (Q(start_time__isnull=True)|Q(start_time__gte=start_time))))
else:
qs = qs.filter(start_day__gte=start_day)
# get only possibly representative events
qs = qs.filter(
Q(other_versions__isnull=True) |
Q(other_versions__representative=F('pk')) |
Q(other_versions__representative__isnull=True))
# remove trash events
qs = qs.filter(~Q(status=Event.STATUS.TRASH))
# sort by datetime
qs = qs.order_by("start_day", "start_time")
return qs.first()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.is_moderate_next():
context['pred'] = self.kwargs["pk"]
return context
def get_object(self, queryset=None):
if self.is_starting_moderation():
now = datetime.now()
return self.get_next_event(now.date(), now.time())
else:
result = super().get_object(queryset)
if self.is_moderate_next():
return self.get_next_event(result.start_day, result.start_time)
else:
return result
def post(self, request, *args, **kwargs):
try:
return super().post(request, args, kwargs)
except Http404:
return HttpResponseRedirect(reverse_lazy("error_next_event", args=[self.object.pk]))
def form_valid(self, form):
form.instance.set_no_modification_date_changed()
form.instance.set_in_moderation_process()
return super().form_valid(form)
def get_success_url(self):
if 'save_and_next' in self.request.POST:
return reverse_lazy("moderate_event_next", args=[self.object.pk])
else:
return self.object.get_absolute_url()
@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.change_event")
def error_next_event(request, pk):
obj = Event.objects.filter(pk=pk).first()
return render(
request,
"agenda_culturel/event_next_error_message.html",
{"pk": pk, "object": obj},
)
class EventDeleteView(