diff --git a/src/agenda_culturel/urls.py b/src/agenda_culturel/urls.py index 34e6e33..a4c3c84 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -32,6 +32,11 @@ from .views import ( mentions_legales, moderation_rules, thank_you, + # Import batch + imports, + add_import, + cancel_import, + update_orphan_events, # Moderation EventModerateView, moderate_event_next, @@ -78,10 +83,6 @@ from .views import ( clear_cache, export_event_ical, MessageDeleteView, - imports, - add_import, - update_orphan_events, - cancel_import, run_all_fb_rimports, run_all_rimports, EventDetailView, @@ -171,6 +172,15 @@ 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"), + # Import batch + path("imports/", imports, name="imports"), + path("imports/add", add_import, name="add_import"), + path("imports//cancel", cancel_import, name="cancel_import"), + path( + "imports/orphans/run", + update_orphan_events, + name="update_orphan_events", + ), # Moderation path("moderate", EventModerateView.as_view(), name="moderate"), path( @@ -424,14 +434,6 @@ urlpatterns = [ MessageDeleteView.as_view(), name="delete_message", ), - path("imports/", imports, name="imports"), - path("imports/add", add_import, name="add_import"), - path( - "imports/orphans/run", - update_orphan_events, - name="update_orphan_events", - ), - path("imports//cancel", cancel_import, name="cancel_import"), path("rimports/", recurrent_imports, name="recurrent_imports"), path("rimports/run", run_all_rimports, name="run_all_rimports"), path("rimports/fb/run", run_all_fb_rimports, name="run_all_fb_rimports"), diff --git a/src/agenda_culturel/views/__init__.py b/src/agenda_culturel/views/__init__.py index 1281b9b..2911fa1 100644 --- a/src/agenda_culturel/views/__init__.py +++ b/src/agenda_culturel/views/__init__.py @@ -2,6 +2,7 @@ from .oldviews import * from .categorisation_rules_view import * from .errors import * from .general_pages_views import * +from .import_batch_views import * from .moderation_views import * from .organisations_views import * from .places_views import * diff --git a/src/agenda_culturel/views/import_batch_views.py b/src/agenda_culturel/views/import_batch_views.py new file mode 100644 index 0000000..6b4b5c0 --- /dev/null +++ b/src/agenda_culturel/views/import_batch_views.py @@ -0,0 +1,143 @@ +from datetime import date + +from django.contrib import messages +from django.contrib.auth.decorators import login_required, permission_required +from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage +from django.db.models import F, Q, OuterRef, Subquery +from django.http import HttpResponseRedirect +from django.shortcuts import render, get_object_or_404 +from django.urls import reverse_lazy +from django.utils.translation import gettext_lazy as _ + +from ..celery import app as celery_app, update_orphan_pure_import_events +from ..celery import import_events_from_json +from ..forms import BatchImportationForm +from ..models import Event, BatchImportation, RecurrentImport + + +@login_required(login_url="/accounts/login/") +@permission_required("agenda_culturel.view_batchimportation") +def imports(request): + rel_event = Event.objects.filter( + import_sources__contains=[OuterRef("url_source")] + ).values("pk")[:1] + paginator = Paginator( + BatchImportation.objects.all() + .order_by("-created_date") + .annotate(event_id=Subquery(rel_event)), + 30, + ) + page = request.GET.get("page") + + today = date.today() + + srcs = RecurrentImport.objects.all().values_list("source") + in_future = Event.objects.filter(Q(start_day__gte=today)) + nb_in_orphan_import = in_future.filter( + ( + Q(import_sources__isnull=False) + & (Q(modified_date__isnull=True) | Q(modified_date__lte=F("imported_date"))) + ) + & ~Q(import_sources__overlap=srcs) + ).count() + + try: + response = paginator.page(page) + except PageNotAnInteger: + response = paginator.page(1) + except EmptyPage: + response = paginator.page(paginator.num_pages) + + return render( + request, + "agenda_culturel/imports.html", + { + "paginator_filter": response, + "nb_in_orphan_import": nb_in_orphan_import, + }, + ) + + +@login_required(login_url="/accounts/login/") +@permission_required( + [ + "agenda_culturel.add_batchimportation", + "agenda_culturel.run_batchimportation", + ] +) +def add_import(request): + form = BatchImportationForm() + + if request.method == "POST": + form = BatchImportationForm(request.POST) + + if form.is_valid(): + import_events_from_json.delay(form.data["json"]) + + messages.success(request, _("The import has been run successfully.")) + return HttpResponseRedirect(reverse_lazy("imports")) + + return render(request, "agenda_culturel/batchimportation_form.html", {"form": form}) + + +@login_required(login_url="/accounts/login/") +@permission_required( + [ + "agenda_culturel.view_batchimportation", + "agenda_culturel.run_batchimportation", + ] +) +def cancel_import(request, pk): + import_process = get_object_or_404(BatchImportation, pk=pk) + + if request.method == "POST": + celery_app.control.revoke(import_process.celery_id) + + import_process.status = BatchImportation.STATUS.CANCELED + import_process.save(update_fields=["status"]) + + messages.success(request, _("The import has been canceled.")) + return HttpResponseRedirect(reverse_lazy("imports")) + else: + cancel_url = reverse_lazy("imports") + return render( + request, + "agenda_culturel/cancel_import_confirm.html", + {"object": import_process, "cancel_url": cancel_url}, + ) + + +@login_required(login_url="/accounts/login/") +@permission_required( + [ + "agenda_culturel.view_batchimportation", + "agenda_culturel.run_batchimportation", + ] +) +def update_orphan_events(request): + if request.method == "POST": + # run recurrent import + update_orphan_pure_import_events.delay() + + messages.success(request, _("The orphan event update has been launched.")) + return HttpResponseRedirect(reverse_lazy("imports")) + else: + today = date.today() + + srcs = RecurrentImport.objects.all().values_list("source") + in_future = Event.objects.filter(Q(start_day__gte=today)) + nb_in_orphan_import = in_future.filter( + ( + Q(import_sources__isnull=False) + & ( + Q(modified_date__isnull=True) + | Q(modified_date__lte=F("imported_date")) + ) + ) + & ~Q(import_sources__overlap=srcs) + ).count() + return render( + request, + "agenda_culturel/run_orphan_imports_confirm.html", + {"nb_in_orphan_import": nb_in_orphan_import}, + ) diff --git a/src/agenda_culturel/views/oldviews.py b/src/agenda_culturel/views/oldviews.py index 1c70d5d..c26225c 100644 --- a/src/agenda_culturel/views/oldviews.py +++ b/src/agenda_culturel/views/oldviews.py @@ -43,16 +43,13 @@ 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 ( - import_events_from_json, import_events_from_url, import_events_from_urls, run_all_recurrent_imports, run_all_recurrent_imports_canceled, run_all_recurrent_imports_failed, run_recurrent_import, - update_orphan_pure_import_events, ) from ..filters import ( DuplicatedEventsFilter, @@ -64,7 +61,6 @@ from ..filters import ( SimpleSearchEventFilter, ) from ..forms import ( - BatchImportationForm, EventForm, EventFormWithContact, FixDuplicates, @@ -1303,139 +1299,6 @@ def event_search_full(request): return event_search(request, True) -######################### -## batch importations -######################### - - -@login_required(login_url="/accounts/login/") -@permission_required("agenda_culturel.view_batchimportation") -def imports(request): - rel_event = Event.objects.filter( - import_sources__contains=[OuterRef("url_source")] - ).values("pk")[:1] - paginator = Paginator( - BatchImportation.objects.all() - .order_by("-created_date") - .annotate(event_id=Subquery(rel_event)), - 30, - ) - page = request.GET.get("page") - - today = date.today() - - srcs = RecurrentImport.objects.all().values_list("source") - in_future = Event.objects.filter(Q(start_day__gte=today)) - nb_in_orphan_import = in_future.filter( - ( - Q(import_sources__isnull=False) - & (Q(modified_date__isnull=True) | Q(modified_date__lte=F("imported_date"))) - ) - & ~Q(import_sources__overlap=srcs) - ).count() - - try: - response = paginator.page(page) - except PageNotAnInteger: - response = paginator.page(1) - except EmptyPage: - response = paginator.page(paginator.num_pages) - - return render( - request, - "agenda_culturel/imports.html", - { - "paginator_filter": response, - "nb_in_orphan_import": nb_in_orphan_import, - }, - ) - - -@login_required(login_url="/accounts/login/") -@permission_required( - [ - "agenda_culturel.add_batchimportation", - "agenda_culturel.run_batchimportation", - ] -) -def add_import(request): - form = BatchImportationForm() - - if request.method == "POST": - form = BatchImportationForm(request.POST) - - if form.is_valid(): - import_events_from_json.delay(form.data["json"]) - - messages.success(request, _("The import has been run successfully.")) - return HttpResponseRedirect(reverse_lazy("imports")) - - return render(request, "agenda_culturel/batchimportation_form.html", {"form": form}) - - -@login_required(login_url="/accounts/login/") -@permission_required( - [ - "agenda_culturel.view_batchimportation", - "agenda_culturel.run_batchimportation", - ] -) -def cancel_import(request, pk): - import_process = get_object_or_404(BatchImportation, pk=pk) - - if request.method == "POST": - celery_app.control.revoke(import_process.celery_id) - - import_process.status = BatchImportation.STATUS.CANCELED - import_process.save(update_fields=["status"]) - - messages.success(request, _("The import has been canceled.")) - return HttpResponseRedirect(reverse_lazy("imports")) - else: - cancel_url = reverse_lazy("imports") - return render( - request, - "agenda_culturel/cancel_import_confirm.html", - {"object": import_process, "cancel_url": cancel_url}, - ) - - -@login_required(login_url="/accounts/login/") -@permission_required( - [ - "agenda_culturel.view_batchimportation", - "agenda_culturel.run_batchimportation", - ] -) -def update_orphan_events(request): - if request.method == "POST": - # run recurrent import - update_orphan_pure_import_events.delay() - - messages.success(request, _("The orphan event update has been launched.")) - return HttpResponseRedirect(reverse_lazy("imports")) - else: - today = date.today() - - srcs = RecurrentImport.objects.all().values_list("source") - in_future = Event.objects.filter(Q(start_day__gte=today)) - nb_in_orphan_import = in_future.filter( - ( - Q(import_sources__isnull=False) - & ( - Q(modified_date__isnull=True) - | Q(modified_date__lte=F("imported_date")) - ) - ) - & ~Q(import_sources__overlap=srcs) - ).count() - return render( - request, - "agenda_culturel/run_orphan_imports_confirm.html", - {"nb_in_orphan_import": nb_in_orphan_import}, - ) - - ######################### ## recurrent importations #########################