Séparation des vues catégorisation

This commit is contained in:
SebF 2025-04-04 10:39:26 +02:00
parent 897d8c6ea9
commit 5000efc353
4 changed files with 218 additions and 207 deletions

View File

@ -17,6 +17,12 @@ from .sitemaps import (
) )
from .models import Event, Place, Organisation, Category from .models import Event, Place, Organisation, Category
from .views import ( from .views import (
# Categorisation rules
CategorisationRuleCreateView,
CategorisationRuleDeleteView,
CategorisationRuleUpdateView,
apply_categorisation_rules,
categorisation_rules,
# Errors # Errors
internal_server_error, internal_server_error,
page_not_found, page_not_found,
@ -84,7 +90,6 @@ from .views import (
RecurrentImportDeleteView, RecurrentImportDeleteView,
RecurrentImportUpdateView, RecurrentImportUpdateView,
run_rimport, run_rimport,
categorisation_rules,
duplicates, duplicates,
DuplicatedEventsDetailView, DuplicatedEventsDetailView,
StaticContentCreateView, StaticContentCreateView,
@ -108,10 +113,6 @@ from .views import (
statistics, statistics,
view_rimport, view_rimport,
update_duplicate_event, update_duplicate_event,
CategorisationRuleCreateView,
CategorisationRuleDeleteView,
CategorisationRuleUpdateView,
apply_categorisation_rules,
UserProfileUpdateView, UserProfileUpdateView,
) )
@ -143,6 +144,24 @@ sitemaps = {
} }
urlpatterns = [ urlpatterns = [
# Categorisation rules
path(
"catrules/add",
CategorisationRuleCreateView.as_view(),
name="add_catrule",
),
path(
"catrules/<int:pk>/delete",
CategorisationRuleDeleteView.as_view(),
name="delete_catrule",
),
path(
"catrules/<int:pk>/edit",
CategorisationRuleUpdateView.as_view(),
name="edit_catrule",
),
path("catrules/apply", apply_categorisation_rules, name="apply_catrules"),
path("catrules/", categorisation_rules, name="categorisation_rules"),
# Errors # Errors
path("500/", internal_server_error, name="internal_server_error"), path("500/", internal_server_error, name="internal_server_error"),
path("404/", page_not_found, name="page_not_found"), path("404/", page_not_found, name="page_not_found"),
@ -440,23 +459,6 @@ urlpatterns = [
name="delete_rimport", name="delete_rimport",
), ),
path("rimports/<int:pk>/run", run_rimport, name="run_rimport"), path("rimports/<int:pk>/run", run_rimport, name="run_rimport"),
path("catrules/", categorisation_rules, name="categorisation_rules"),
path(
"catrules/add",
CategorisationRuleCreateView.as_view(),
name="add_catrule",
),
path(
"catrules/<int:pk>/edit",
CategorisationRuleUpdateView.as_view(),
name="edit_catrule",
),
path(
"catrules/<int:pk>/delete",
CategorisationRuleDeleteView.as_view(),
name="delete_catrule",
),
path("catrules/apply", apply_categorisation_rules, name="apply_catrules"),
path("duplicates/", duplicates, name="duplicates"), path("duplicates/", duplicates, name="duplicates"),
path( path(
"duplicates/<int:pk>", "duplicates/<int:pk>",

View File

@ -1,4 +1,5 @@
from .oldviews import * from .oldviews import *
from .categorisation_rules_view import *
from .errors import * from .errors import *
from .general_pages_views import * from .general_pages_views import *
from .moderation_views import * from .moderation_views import *

View File

@ -0,0 +1,192 @@
from datetime import datetime
from django.contrib import messages
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.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db.models import Q
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import UpdateView, CreateView, DeleteView
from ..forms import CategorisationRuleImportForm, CategorisationForm
from ..models import Event, CategorisationRule, Category
@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_categorisationrule")
def categorisation_rules(request):
paginator = Paginator(
CategorisationRule.objects.all()
.order_by("pk")
.select_related("category")
.select_related("place"),
100,
)
page = request.GET.get("page")
try:
response = paginator.page(page)
except PageNotAnInteger:
response = paginator.page(1)
except EmptyPage:
response = paginator.page(paginator.num_pages)
return render(
request,
"agenda_culturel/categorisation_rules.html",
{"paginator_filter": response},
)
class CategorisationRuleCreateView(
LoginRequiredMixin, PermissionRequiredMixin, CreateView
):
model = CategorisationRule
permission_required = "agenda_culturel.add_categorisationrule"
success_url = reverse_lazy("categorisation_rules")
form_class = CategorisationRuleImportForm
class CategorisationRuleUpdateView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
UpdateView,
):
model = CategorisationRule
permission_required = "agenda_culturel.change_categorisationrule"
form_class = CategorisationRuleImportForm
success_url = reverse_lazy("categorisation_rules")
success_message = _("The categorisation rule has been successfully modified.")
class CategorisationRuleDeleteView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
DeleteView,
):
model = CategorisationRule
permission_required = "agenda_culturel.delete_categorisationrule"
success_url = reverse_lazy("categorisation_rules")
success_message = _("The categorisation rule has been successfully deleted.")
@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.apply_categorisationrules")
def apply_categorisation_rules(request):
if request.method == "POST":
form = CategorisationForm(request.POST)
if form.is_valid():
nb = 0
for epk, c in form.get_validated():
e = Event.objects.get(pk=epk)
cat = Category.objects.filter(name=c).first()
e.category = cat
e.save()
nb += 1
if nb != 0:
if nb == 1:
messages.success(
request,
_(
"The rules were successfully applied and 1 event was categorised."
),
)
else:
messages.success(
request,
_(
"The rules were successfully applied and {} events were categorised."
).format(nb),
)
else:
messages.info(
request,
_(
"The rules were successfully applied and no events were categorised."
),
)
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))
else:
return render(
request,
"agenda_culturel/categorise_events_form.html",
context={"form": form},
)
else:
# first we check if events are not correctly categorised
to_categorise = []
events = (
Event.objects.filter(start_day__gte=datetime.now())
.exclude(category=Category.get_default_category_id())
.exclude(category=None)
.select_related("exact_location")
.select_related("category")
)
for e in events:
c = CategorisationRule.get_category_from_rules(e)
if c and c != e.category:
to_categorise.append((e, c))
# then we apply rules on events without category
nb = 0
to_save = []
events = (
Event.objects.filter(start_day__gte=datetime.now())
.filter(Q(category=Category.get_default_category_id()) | Q(category=None))
.select_related("exact_location")
.select_related("category")
)
for e in events:
success = CategorisationRule.apply_rules(e)
if success:
nb += 1
to_save.append(e)
if nb != 0:
Event.objects.bulk_update(to_save, fields=["category"])
# set messages
if nb != 0:
if nb == 1:
messages.success(
request,
_(
"The rules were successfully applied and 1 event with default category was categorised."
),
)
else:
messages.success(
request,
_(
"The rules were successfully applied and {} events with default category were categorised."
).format(nb),
)
else:
messages.info(
request,
_(
"The rules were successfully applied and no events were categorised."
),
)
if len(to_categorise) != 0:
form = CategorisationForm(events=to_categorise)
return render(
request,
"agenda_culturel/categorise_events_form.html",
context={
"form": form,
"events": dict((e.pk, e) for e, c in to_categorise),
"categories": dict((e.pk, c) for e, c in to_categorise),
},
)
else:
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))

View File

@ -41,6 +41,7 @@ from django.views.generic.edit import (
) )
from honeypot.decorators import check_honeypot from honeypot.decorators import check_honeypot
from .utils import get_event_qs
from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
from ..celery import app as celery_app from ..celery import app as celery_app
from ..celery import ( from ..celery import (
@ -64,8 +65,6 @@ from ..filters import (
) )
from ..forms import ( from ..forms import (
BatchImportationForm, BatchImportationForm,
CategorisationForm,
CategorisationRuleImportForm,
EventForm, EventForm,
EventFormWithContact, EventFormWithContact,
FixDuplicates, FixDuplicates,
@ -82,7 +81,6 @@ from ..forms import (
from ..import_tasks.extractor import Extractor from ..import_tasks.extractor import Extractor
from ..models import ( from ..models import (
BatchImportation, BatchImportation,
CategorisationRule,
Category, Category,
DuplicatedEvents, DuplicatedEvents,
Event, Event,
@ -94,7 +92,6 @@ from ..models import (
remove_accents, remove_accents,
UserProfile, UserProfile,
) )
from .utils import get_event_qs
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -1954,187 +1951,6 @@ def set_duplicate(request, year, month, day, pk):
) )
#########################
## categorisation rules
#########################
@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_categorisationrule")
def categorisation_rules(request):
paginator = Paginator(
CategorisationRule.objects.all()
.order_by("pk")
.select_related("category")
.select_related("place"),
100,
)
page = request.GET.get("page")
try:
response = paginator.page(page)
except PageNotAnInteger:
response = paginator.page(1)
except EmptyPage:
response = paginator.page(paginator.num_pages)
return render(
request,
"agenda_culturel/categorisation_rules.html",
{"paginator_filter": response},
)
class CategorisationRuleCreateView(
LoginRequiredMixin, PermissionRequiredMixin, CreateView
):
model = CategorisationRule
permission_required = "agenda_culturel.add_categorisationrule"
success_url = reverse_lazy("categorisation_rules")
form_class = CategorisationRuleImportForm
class CategorisationRuleUpdateView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
UpdateView,
):
model = CategorisationRule
permission_required = "agenda_culturel.change_categorisationrule"
form_class = CategorisationRuleImportForm
success_url = reverse_lazy("categorisation_rules")
success_message = _("The categorisation rule has been successfully modified.")
class CategorisationRuleDeleteView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
DeleteView,
):
model = CategorisationRule
permission_required = "agenda_culturel.delete_categorisationrule"
success_url = reverse_lazy("categorisation_rules")
success_message = _("The categorisation rule has been successfully deleted.")
@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.apply_categorisationrules")
def apply_categorisation_rules(request):
if request.method == "POST":
form = CategorisationForm(request.POST)
if form.is_valid():
nb = 0
for epk, c in form.get_validated():
e = Event.objects.get(pk=epk)
cat = Category.objects.filter(name=c).first()
e.category = cat
e.save()
nb += 1
if nb != 0:
if nb == 1:
messages.success(
request,
_(
"The rules were successfully applied and 1 event was categorised."
),
)
else:
messages.success(
request,
_(
"The rules were successfully applied and {} events were categorised."
).format(nb),
)
else:
messages.info(
request,
_(
"The rules were successfully applied and no events were categorised."
),
)
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))
else:
return render(
request,
"agenda_culturel/categorise_events_form.html",
context={"form": form},
)
else:
# first we check if events are not correctly categorised
to_categorise = []
events = (
Event.objects.filter(start_day__gte=datetime.now())
.exclude(category=Category.get_default_category_id())
.exclude(category=None)
.select_related("exact_location")
.select_related("category")
)
for e in events:
c = CategorisationRule.get_category_from_rules(e)
if c and c != e.category:
to_categorise.append((e, c))
# then we apply rules on events without category
nb = 0
to_save = []
events = (
Event.objects.filter(start_day__gte=datetime.now())
.filter(Q(category=Category.get_default_category_id()) | Q(category=None))
.select_related("exact_location")
.select_related("category")
)
for e in events:
success = CategorisationRule.apply_rules(e)
if success:
nb += 1
to_save.append(e)
if nb != 0:
Event.objects.bulk_update(to_save, fields=["category"])
# set messages
if nb != 0:
if nb == 1:
messages.success(
request,
_(
"The rules were successfully applied and 1 event with default category was categorised."
),
)
else:
messages.success(
request,
_(
"The rules were successfully applied and {} events with default category were categorised."
).format(nb),
)
else:
messages.info(
request,
_(
"The rules were successfully applied and no events were categorised."
),
)
if len(to_categorise) != 0:
form = CategorisationForm(events=to_categorise)
return render(
request,
"agenda_culturel/categorise_events_form.html",
context={
"form": form,
"events": dict((e.pk, e) for e, c in to_categorise),
"categories": dict((e.pk, c) for e, c in to_categorise),
},
)
else:
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))
def statistics(request, pk=None): def statistics(request, pk=None):
if pk is not None: if pk is not None:
rimport = RecurrentImport.objects.filter(pk=pk) rimport = RecurrentImport.objects.filter(pk=pk)