From 5000efc3531e82273a70e3d7a8b3aa13a3d60e89 Mon Sep 17 00:00:00 2001 From: SebF Date: Fri, 4 Apr 2025 10:39:26 +0200 Subject: [PATCH] =?UTF-8?q?S=C3=A9paration=20des=20vues=20cat=C3=A9gorisat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agenda_culturel/urls.py | 46 +++-- src/agenda_culturel/views/__init__.py | 1 + .../views/categorisation_rules_view.py | 192 ++++++++++++++++++ src/agenda_culturel/views/oldviews.py | 186 +---------------- 4 files changed, 218 insertions(+), 207 deletions(-) create mode 100644 src/agenda_culturel/views/categorisation_rules_view.py diff --git a/src/agenda_culturel/urls.py b/src/agenda_culturel/urls.py index 8513e5c..34e6e33 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -17,6 +17,12 @@ from .sitemaps import ( ) from .models import Event, Place, Organisation, Category from .views import ( + # Categorisation rules + CategorisationRuleCreateView, + CategorisationRuleDeleteView, + CategorisationRuleUpdateView, + apply_categorisation_rules, + categorisation_rules, # Errors internal_server_error, page_not_found, @@ -84,7 +90,6 @@ from .views import ( RecurrentImportDeleteView, RecurrentImportUpdateView, run_rimport, - categorisation_rules, duplicates, DuplicatedEventsDetailView, StaticContentCreateView, @@ -108,10 +113,6 @@ from .views import ( statistics, view_rimport, update_duplicate_event, - CategorisationRuleCreateView, - CategorisationRuleDeleteView, - CategorisationRuleUpdateView, - apply_categorisation_rules, UserProfileUpdateView, ) @@ -143,6 +144,24 @@ sitemaps = { } urlpatterns = [ + # Categorisation rules + path( + "catrules/add", + CategorisationRuleCreateView.as_view(), + name="add_catrule", + ), + path( + "catrules//delete", + CategorisationRuleDeleteView.as_view(), + name="delete_catrule", + ), + path( + "catrules//edit", + CategorisationRuleUpdateView.as_view(), + name="edit_catrule", + ), + path("catrules/apply", apply_categorisation_rules, name="apply_catrules"), + path("catrules/", categorisation_rules, name="categorisation_rules"), # Errors path("500/", internal_server_error, name="internal_server_error"), path("404/", page_not_found, name="page_not_found"), @@ -440,23 +459,6 @@ urlpatterns = [ name="delete_rimport", ), path("rimports//run", run_rimport, name="run_rimport"), - path("catrules/", categorisation_rules, name="categorisation_rules"), - path( - "catrules/add", - CategorisationRuleCreateView.as_view(), - name="add_catrule", - ), - path( - "catrules//edit", - CategorisationRuleUpdateView.as_view(), - name="edit_catrule", - ), - path( - "catrules//delete", - CategorisationRuleDeleteView.as_view(), - name="delete_catrule", - ), - path("catrules/apply", apply_categorisation_rules, name="apply_catrules"), path("duplicates/", duplicates, name="duplicates"), path( "duplicates/", diff --git a/src/agenda_culturel/views/__init__.py b/src/agenda_culturel/views/__init__.py index 7b37988..1281b9b 100644 --- a/src/agenda_culturel/views/__init__.py +++ b/src/agenda_culturel/views/__init__.py @@ -1,4 +1,5 @@ from .oldviews import * +from .categorisation_rules_view import * from .errors import * from .general_pages_views import * from .moderation_views import * diff --git a/src/agenda_culturel/views/categorisation_rules_view.py b/src/agenda_culturel/views/categorisation_rules_view.py new file mode 100644 index 0000000..7f83e96 --- /dev/null +++ b/src/agenda_culturel/views/categorisation_rules_view.py @@ -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")) diff --git a/src/agenda_culturel/views/oldviews.py b/src/agenda_culturel/views/oldviews.py index d1af9d6..1c70d5d 100644 --- a/src/agenda_culturel/views/oldviews.py +++ b/src/agenda_culturel/views/oldviews.py @@ -41,6 +41,7 @@ from django.views.generic.edit import ( ) from honeypot.decorators import check_honeypot +from .utils import get_event_qs from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek from ..celery import app as celery_app from ..celery import ( @@ -64,8 +65,6 @@ from ..filters import ( ) from ..forms import ( BatchImportationForm, - CategorisationForm, - CategorisationRuleImportForm, EventForm, EventFormWithContact, FixDuplicates, @@ -82,7 +81,6 @@ from ..forms import ( from ..import_tasks.extractor import Extractor from ..models import ( BatchImportation, - CategorisationRule, Category, DuplicatedEvents, Event, @@ -94,7 +92,6 @@ from ..models import ( remove_accents, UserProfile, ) -from .utils import get_event_qs 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): if pk is not None: rimport = RecurrentImport.objects.filter(pk=pk)