Séparation des vues modération
This commit is contained in:
parent
76610993ba
commit
69ced85e1e
@ -26,7 +26,11 @@ from .views import (
|
||||
mentions_legales,
|
||||
moderation_rules,
|
||||
thank_you,
|
||||
# tags
|
||||
# Moderation
|
||||
EventModerateView,
|
||||
moderate_event_next,
|
||||
moderate_from_date,
|
||||
# Tags
|
||||
view_tag,
|
||||
view_tag_past,
|
||||
TagUpdateView,
|
||||
@ -72,8 +76,6 @@ from .views import (
|
||||
run_all_rimports,
|
||||
EventDetailView,
|
||||
EventUpdateView,
|
||||
EventModerateView,
|
||||
moderate_event_next,
|
||||
RecurrentImportCreateView,
|
||||
RecurrentImportDeleteView,
|
||||
RecurrentImportUpdateView,
|
||||
@ -92,7 +94,6 @@ from .views import (
|
||||
delete_cm_spam,
|
||||
PlaceCreateView,
|
||||
PlaceFromEventCreateView,
|
||||
moderate_from_date,
|
||||
update_from_source,
|
||||
change_status_event,
|
||||
EventDeleteView,
|
||||
@ -149,6 +150,38 @@ urlpatterns = [
|
||||
path("mentions-legales", mentions_legales, name="mentions_legales"),
|
||||
path("regles-de-moderation", moderation_rules, name="moderation_rules"),
|
||||
path("merci", thank_you, name="thank_you"),
|
||||
# Moderation
|
||||
path("moderate", EventModerateView.as_view(), name="moderate"),
|
||||
path(
|
||||
"event/<int:pk>/moderate",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate-force",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event_force",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate/after/<int:pred>",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event_step",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate/back/<int:pred>",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event_backstep",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate-next",
|
||||
moderate_event_next,
|
||||
name="moderate_event_next",
|
||||
),
|
||||
path(
|
||||
"moderate/<int:y>/<int:m>/<int:d>",
|
||||
moderate_from_date,
|
||||
name="moderate_from_date",
|
||||
),
|
||||
# TODO pas encore trié
|
||||
path("", home, name="home"),
|
||||
path("cat:<cat>/", home, name="home_category"),
|
||||
@ -218,37 +251,6 @@ urlpatterns = [
|
||||
path(
|
||||
"event/<int:pk>/edit-force", EventUpdateView.as_view(), name="edit_event_force"
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate-force",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event_force",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate/after/<int:pred>",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event_step",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate/back/<int:pred>",
|
||||
EventModerateView.as_view(),
|
||||
name="moderate_event_backstep",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/moderate-next",
|
||||
moderate_event_next,
|
||||
name="moderate_event_next",
|
||||
),
|
||||
path("moderate", EventModerateView.as_view(), name="moderate"),
|
||||
path(
|
||||
"moderate/<int:y>/<int:m>/<int:d>",
|
||||
moderate_from_date,
|
||||
name="moderate_from_date",
|
||||
),
|
||||
path(
|
||||
"event/<int:pk>/simple-clone/edit",
|
||||
EventUpdateView.as_view(),
|
||||
|
@ -1,4 +1,5 @@
|
||||
from .oldviews import *
|
||||
from .errors import *
|
||||
from .general_pages_views import *
|
||||
from .moderation_views import *
|
||||
from .tag_views import *
|
||||
|
168
src/agenda_culturel/views/moderation_views.py
Normal file
168
src/agenda_culturel/views/moderation_views.py
Normal file
@ -0,0 +1,168 @@
|
||||
from datetime import date
|
||||
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import UpdateView
|
||||
from django.db.models import Q, F
|
||||
from django.utils.timezone import datetime
|
||||
from ..forms import EventModerateForm
|
||||
from ..models import Event
|
||||
|
||||
|
||||
class EventModerateView(
|
||||
SuccessMessageMixin,
|
||||
PermissionRequiredMixin,
|
||||
LoginRequiredMixin,
|
||||
UpdateView,
|
||||
):
|
||||
model = Event
|
||||
permission_required = "agenda_culturel.change_event"
|
||||
template_name = "agenda_culturel/event_form_moderate.html"
|
||||
form_class = EventModerateForm
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs["is_moderation_expert"] = (
|
||||
self.request.user.userprofile.is_moderation_expert
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_success_message(self, cleaned_data):
|
||||
txt = (
|
||||
_(" A message has been sent to the person who proposed the event.")
|
||||
if hasattr(self, "with_msg") and self.with_msg
|
||||
else ""
|
||||
)
|
||||
return mark_safe(
|
||||
_('The event <a href="{}">{}</a> has been moderated with success.').format(
|
||||
self.object.get_absolute_url(), self.object.title
|
||||
)
|
||||
+ txt
|
||||
)
|
||||
|
||||
def is_moderate_next(self):
|
||||
return "after" in self.request.path.split("/")
|
||||
|
||||
def is_moderate_back(self):
|
||||
return "back" in self.request.path.split("/")
|
||||
|
||||
def is_moderate_force(self):
|
||||
return "moderate-force" in self.request.path.split("/")
|
||||
|
||||
def is_starting_moderation(self):
|
||||
return "pk" not in self.kwargs
|
||||
|
||||
def is_moderation_from_date(self):
|
||||
return "m" in self.kwargs and "y" in self.kwargs and "d" in self.kwargs
|
||||
|
||||
def get_next_event(start_day, start_time, opk):
|
||||
# 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__gt=start_time))
|
||||
)
|
||||
)
|
||||
else:
|
||||
qs = qs.filter(Q(start_day__gte=start_day) & ~Q(pk=opk))
|
||||
|
||||
# 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["pred"]
|
||||
return context
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
if self.is_starting_moderation():
|
||||
now = datetime.now()
|
||||
event = EventModerateView.get_next_event(now.date(), now.time(), None)
|
||||
else:
|
||||
event = super().get_object(queryset)
|
||||
if event.status == Event.STATUS.DRAFT:
|
||||
event.status = Event.STATUS.PUBLISHED
|
||||
if self.is_moderate_back():
|
||||
pred = Event.objects.filter(pk=self.kwargs["pred"]).first()
|
||||
pred.free_modification_lock(self.request.user)
|
||||
if self.is_moderate_force():
|
||||
event.free_modification_lock(self.request.user, False)
|
||||
return event
|
||||
|
||||
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()
|
||||
form.instance.set_processing_user(self.request.user)
|
||||
self.with_msg = form.instance.notify_if_required(self.request)
|
||||
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])
|
||||
elif "save_and_edit_local" in self.request.POST:
|
||||
return reverse_lazy("edit_event", args=[self.object.get_local_version().pk])
|
||||
else:
|
||||
return self.object.get_absolute_url()
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
@permission_required("agenda_culturel.change_event")
|
||||
def moderate_event_next(request, pk):
|
||||
# current event
|
||||
obj = Event.objects.filter(pk=pk).first()
|
||||
# free lock
|
||||
obj.free_modification_lock(request.user)
|
||||
start_day = obj.start_day
|
||||
start_time = obj.start_time
|
||||
|
||||
next_obj = EventModerateView.get_next_event(start_day, start_time, pk)
|
||||
if next_obj is None:
|
||||
return render(
|
||||
request,
|
||||
"agenda_culturel/event_next_error_message.html",
|
||||
{"pk": pk, "object": obj},
|
||||
)
|
||||
else:
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy("moderate_event_step", args=[next_obj.pk, obj.pk])
|
||||
)
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
@permission_required("agenda_culturel.change_event")
|
||||
def moderate_from_date(request, y, m, d):
|
||||
d = date(y, m, d)
|
||||
obj = EventModerateView.get_next_event(d, None, None)
|
||||
return HttpResponseRedirect(reverse_lazy("moderate_event", args=[obj.pk]))
|
@ -14,10 +14,13 @@ from django.contrib.auth.mixins import (
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.core.cache import cache
|
||||
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
||||
from django.db.models import Aggregate, FloatField
|
||||
from django.db.models import Avg, Max, Min
|
||||
from django.db.models import Count, F, Func, OuterRef, Q, Subquery
|
||||
from django.db.models.aggregates import StdDev
|
||||
from django.db.models.functions import ExtractDay
|
||||
from django.db.models.functions import TruncMonth
|
||||
from django.http import (
|
||||
Http404,
|
||||
HttpResponse,
|
||||
HttpResponseForbidden,
|
||||
HttpResponseRedirect,
|
||||
@ -37,10 +40,6 @@ from django.views.generic.edit import (
|
||||
UpdateView,
|
||||
)
|
||||
from honeypot.decorators import check_honeypot
|
||||
from django.db.models.aggregates import StdDev
|
||||
from django.db.models import Avg, Max, Min
|
||||
from django.db.models import Aggregate, FloatField
|
||||
from django.db.models.functions import ExtractDay
|
||||
|
||||
from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
|
||||
from ..celery import app as celery_app
|
||||
@ -70,7 +69,6 @@ from ..forms import (
|
||||
EventAddPlaceForm,
|
||||
EventForm,
|
||||
EventFormWithContact,
|
||||
EventModerateForm,
|
||||
FixDuplicates,
|
||||
MergeDuplicates,
|
||||
MessageEventForm,
|
||||
@ -159,6 +157,17 @@ class PaginatorFilter(Paginator):
|
||||
return page
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# Useful for translation
|
||||
to_be_translated = [
|
||||
_("Recurrent import name"),
|
||||
_("Add another"),
|
||||
_("Browse..."),
|
||||
_("No file selected."),
|
||||
]
|
||||
|
||||
|
||||
def home(request, cat=None):
|
||||
return week_view(request, home=True, cat=cat)
|
||||
|
||||
@ -475,159 +484,6 @@ class EventUpdateView(
|
||||
return self.object.get_absolute_url()
|
||||
|
||||
|
||||
class EventModerateView(
|
||||
SuccessMessageMixin,
|
||||
PermissionRequiredMixin,
|
||||
LoginRequiredMixin,
|
||||
UpdateView,
|
||||
):
|
||||
model = Event
|
||||
permission_required = "agenda_culturel.change_event"
|
||||
template_name = "agenda_culturel/event_form_moderate.html"
|
||||
form_class = EventModerateForm
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs["is_moderation_expert"] = (
|
||||
self.request.user.userprofile.is_moderation_expert
|
||||
)
|
||||
return kwargs
|
||||
|
||||
def get_success_message(self, cleaned_data):
|
||||
txt = (
|
||||
_(" A message has been sent to the person who proposed the event.")
|
||||
if hasattr(self, "with_msg") and self.with_msg
|
||||
else ""
|
||||
)
|
||||
return mark_safe(
|
||||
_('The event <a href="{}">{}</a> has been moderated with success.').format(
|
||||
self.object.get_absolute_url(), self.object.title
|
||||
)
|
||||
+ txt
|
||||
)
|
||||
|
||||
def is_moderate_next(self):
|
||||
return "after" in self.request.path.split("/")
|
||||
|
||||
def is_moderate_back(self):
|
||||
return "back" in self.request.path.split("/")
|
||||
|
||||
def is_moderate_force(self):
|
||||
return "moderate-force" in self.request.path.split("/")
|
||||
|
||||
def is_starting_moderation(self):
|
||||
return "pk" not in self.kwargs
|
||||
|
||||
def is_moderation_from_date(self):
|
||||
return "m" in self.kwargs and "y" in self.kwargs and "d" in self.kwargs
|
||||
|
||||
def get_next_event(start_day, start_time, opk):
|
||||
# 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__gt=start_time))
|
||||
)
|
||||
)
|
||||
else:
|
||||
qs = qs.filter(Q(start_day__gte=start_day) & ~Q(pk=opk))
|
||||
|
||||
# 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["pred"]
|
||||
return context
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
if self.is_starting_moderation():
|
||||
now = datetime.now()
|
||||
event = EventModerateView.get_next_event(now.date(), now.time(), None)
|
||||
else:
|
||||
event = super().get_object(queryset)
|
||||
if event.status == Event.STATUS.DRAFT:
|
||||
event.status = Event.STATUS.PUBLISHED
|
||||
if self.is_moderate_back():
|
||||
pred = Event.objects.filter(pk=self.kwargs["pred"]).first()
|
||||
pred.free_modification_lock(self.request.user)
|
||||
if self.is_moderate_force():
|
||||
event.free_modification_lock(self.request.user, False)
|
||||
return event
|
||||
|
||||
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()
|
||||
form.instance.set_processing_user(self.request.user)
|
||||
self.with_msg = form.instance.notify_if_required(self.request)
|
||||
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])
|
||||
elif "save_and_edit_local" in self.request.POST:
|
||||
return reverse_lazy("edit_event", args=[self.object.get_local_version().pk])
|
||||
else:
|
||||
return self.object.get_absolute_url()
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
@permission_required("agenda_culturel.change_event")
|
||||
def moderate_event_next(request, pk):
|
||||
# current event
|
||||
obj = Event.objects.filter(pk=pk).first()
|
||||
# free lock
|
||||
obj.free_modification_lock(request.user)
|
||||
start_day = obj.start_day
|
||||
start_time = obj.start_time
|
||||
|
||||
next_obj = EventModerateView.get_next_event(start_day, start_time, pk)
|
||||
if next_obj is None:
|
||||
return render(
|
||||
request,
|
||||
"agenda_culturel/event_next_error_message.html",
|
||||
{"pk": pk, "object": obj},
|
||||
)
|
||||
else:
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy("moderate_event_step", args=[next_obj.pk, obj.pk])
|
||||
)
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
@permission_required("agenda_culturel.change_event")
|
||||
def moderate_from_date(request, y, m, d):
|
||||
d = date(y, m, d)
|
||||
obj = EventModerateView.get_next_event(d, None, None)
|
||||
return HttpResponseRedirect(reverse_lazy("moderate_event", args=[obj.pk]))
|
||||
|
||||
|
||||
class EventDeleteView(
|
||||
SuccessMessageMixin,
|
||||
PermissionRequiredMixin,
|
||||
|
Loading…
x
Reference in New Issue
Block a user