Séparation des vues import recurrent

This commit is contained in:
SebF 2025-04-04 11:08:42 +02:00
parent 8aebc2d3a4
commit b529a33b24
4 changed files with 239 additions and 225 deletions

View File

@ -37,6 +37,15 @@ from .views import (
add_import, add_import,
cancel_import, cancel_import,
update_orphan_events, update_orphan_events,
# Import récurrent
RecurrentImportCreateView,
RecurrentImportDeleteView,
RecurrentImportUpdateView,
recurrent_imports,
run_all_fb_rimports,
run_all_rimports,
run_rimport,
view_rimport,
# Moderation # Moderation
EventModerateView, EventModerateView,
moderate_event_next, moderate_event_next,
@ -83,14 +92,8 @@ from .views import (
clear_cache, clear_cache,
export_event_ical, export_event_ical,
MessageDeleteView, MessageDeleteView,
run_all_fb_rimports,
run_all_rimports,
EventDetailView, EventDetailView,
EventUpdateView, EventUpdateView,
RecurrentImportCreateView,
RecurrentImportDeleteView,
RecurrentImportUpdateView,
run_rimport,
duplicates, duplicates,
DuplicatedEventsDetailView, DuplicatedEventsDetailView,
StaticContentCreateView, StaticContentCreateView,
@ -100,7 +103,6 @@ from .views import (
EventCreateView, EventCreateView,
event_search, event_search,
event_search_full, event_search_full,
recurrent_imports,
delete_cm_spam, delete_cm_spam,
update_from_source, update_from_source,
change_status_event, change_status_event,
@ -112,7 +114,6 @@ from .views import (
view_messages, view_messages,
MessageUpdateView, MessageUpdateView,
statistics, statistics,
view_rimport,
update_duplicate_event, update_duplicate_event,
UserProfileUpdateView, UserProfileUpdateView,
) )
@ -181,6 +182,33 @@ urlpatterns = [
update_orphan_events, update_orphan_events,
name="update_orphan_events", name="update_orphan_events",
), ),
# Import récurrent
path("rimports/add", RecurrentImportCreateView.as_view(), name="add_rimport"),
path(
"rimports/<int:pk>/delete",
RecurrentImportDeleteView.as_view(),
name="delete_rimport",
),
path(
"rimports/<int:pk>/edit",
RecurrentImportUpdateView.as_view(),
name="edit_rimport",
),
path("rimports/", recurrent_imports, name="recurrent_imports"),
path(
"rimports/status/<status>",
recurrent_imports,
name="recurrent_imports_status",
),
path("rimports/fb/run", run_all_fb_rimports, name="run_all_fb_rimports"),
path("rimports/run", run_all_rimports, name="run_all_rimports"),
path(
"rimports/status/<status>/run",
run_all_rimports,
name="run_all_rimports_status",
),
path("rimports/<int:pk>/run", run_rimport, name="run_rimport"),
path("rimports/<int:pk>/view", view_rimport, name="view_rimport"),
# Moderation # Moderation
path("moderate", EventModerateView.as_view(), name="moderate"), path("moderate", EventModerateView.as_view(), name="moderate"),
path( path(
@ -434,33 +462,7 @@ urlpatterns = [
MessageDeleteView.as_view(), MessageDeleteView.as_view(),
name="delete_message", name="delete_message",
), ),
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"),
path(
"rimports/status/<status>",
recurrent_imports,
name="recurrent_imports_status",
),
path(
"rimports/status/<status>/run",
run_all_rimports,
name="run_all_rimports_status",
),
path("rimports/add", RecurrentImportCreateView.as_view(), name="add_rimport"),
path("rimports/<int:pk>/view", view_rimport, name="view_rimport"),
path("rimports/<int:pk>/stats", statistics, name="stats_rimport"), path("rimports/<int:pk>/stats", statistics, name="stats_rimport"),
path(
"rimports/<int:pk>/edit",
RecurrentImportUpdateView.as_view(),
name="edit_rimport",
),
path(
"rimports/<int:pk>/delete",
RecurrentImportDeleteView.as_view(),
name="delete_rimport",
),
path("rimports/<int:pk>/run", run_rimport, name="run_rimport"),
path("duplicates/", duplicates, name="duplicates"), path("duplicates/", duplicates, name="duplicates"),
path( path(
"duplicates/<int:pk>", "duplicates/<int:pk>",

View File

@ -3,6 +3,7 @@ from .categorisation_rules_view import *
from .errors import * from .errors import *
from .general_pages_views import * from .general_pages_views import *
from .import_batch_views import * from .import_batch_views import *
from .import_recurrent_views import *
from .moderation_views import * from .moderation_views import *
from .organisations_views import * from .organisations_views import *
from .places_views import * from .places_views import *

View File

@ -0,0 +1,202 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db.models import 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 django.views.generic import CreateView, UpdateView, DeleteView
from . import PaginatorFilter
from ..celery import (
run_all_recurrent_imports,
run_all_recurrent_imports_canceled,
run_all_recurrent_imports_failed,
run_recurrent_import,
)
from ..filters import RecurrentImportFilter
from ..forms import RecurrentImportForm
from ..models import BatchImportation, RecurrentImport
@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_recurrentimport")
def recurrent_imports(request, status=None):
newest = BatchImportation.objects.filter(recurrentImport=OuterRef("pk")).order_by(
"-created_date"
)
qs = (
RecurrentImport.objects.all()
.annotate(last_run_status=Subquery(newest.values("status")[:1]))
.order_by("-pk")
)
nb_failed = qs.filter(last_run_status=BatchImportation.STATUS.FAILED).count()
nb_canceled = qs.filter(last_run_status=BatchImportation.STATUS.CANCELED).count()
nb_running = qs.filter(last_run_status=BatchImportation.STATUS.RUNNING).count()
nb_all = qs.count()
if status is not None:
qs = qs.filter(last_run_status=status)
filter = RecurrentImportFilter(request.GET, queryset=qs)
paginator = PaginatorFilter(filter, 20, request)
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/rimports.html",
{
"paginator_filter": response,
"filter": filter,
"nb_all": nb_all,
"nb_failed": nb_failed,
"nb_canceled": nb_canceled,
"nb_running": nb_running,
"status": status,
},
)
class RecurrentImportCreateView(
LoginRequiredMixin, PermissionRequiredMixin, CreateView
):
model = RecurrentImport
permission_required = "agenda_culturel.add_recurrentimport"
success_url = reverse_lazy("recurrent_imports")
form_class = RecurrentImportForm
class RecurrentImportUpdateView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
UpdateView,
):
model = RecurrentImport
permission_required = "agenda_culturel.change_recurrentimport"
form_class = RecurrentImportForm
success_message = _("The recurrent import has been successfully modified.")
class RecurrentImportDeleteView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
DeleteView,
):
model = RecurrentImport
permission_required = "agenda_culturel.delete_recurrentimport"
success_url = reverse_lazy("recurrent_imports")
success_message = _("The recurrent import has been successfully deleted.")
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.view_batchimportation",
]
)
def view_rimport(request, pk):
obj = get_object_or_404(RecurrentImport, pk=pk)
paginator = Paginator(
BatchImportation.objects.filter(recurrentImport=pk).order_by("-created_date"),
10,
)
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/page-rimport.html",
{"paginator_filter": response, "object": obj},
)
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.run_recurrentimport",
]
)
def run_rimport(request, pk):
rimport = get_object_or_404(RecurrentImport, pk=pk)
if request.method == "POST":
# run recurrent import
run_recurrent_import.delay(pk)
messages.success(request, _("The import has been launched."))
return HttpResponseRedirect(reverse_lazy("view_rimport", args=[pk]))
else:
return render(
request,
"agenda_culturel/run_rimport_confirm.html",
{"object": rimport},
)
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.run_recurrentimport",
]
)
def run_all_rimports(request, status=None):
if request.method == "POST":
# run recurrent import
if status == BatchImportation.STATUS.FAILED:
run_all_recurrent_imports_failed.delay()
elif status == BatchImportation.STATUS.CANCELED:
run_all_recurrent_imports_canceled.delay()
else:
run_all_recurrent_imports.delay()
messages.success(request, _("Imports has been launched."))
return HttpResponseRedirect(reverse_lazy("recurrent_imports"))
else:
if status == BatchImportation.STATUS.FAILED:
return render(request, "agenda_culturel/run_failed_rimports_confirm.html")
elif status == BatchImportation.STATUS.CANCELED:
return render(request, "agenda_culturel/run_canceled_rimports_confirm.html")
else:
return render(request, "agenda_culturel/run_all_rimports_confirm.html")
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.run_recurrentimport",
]
)
def run_all_fb_rimports(request, status=None):
if request.method == "POST":
run_all_recurrent_imports.delay(True)
messages.success(request, _("Facebook imports has been launched."))
return HttpResponseRedirect(reverse_lazy("recurrent_imports"))
else:
return render(request, "agenda_culturel/run_all_fb_rimports_confirm.html")

View File

@ -46,17 +46,12 @@ from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
from ..celery import ( from ..celery import (
import_events_from_url, import_events_from_url,
import_events_from_urls, import_events_from_urls,
run_all_recurrent_imports,
run_all_recurrent_imports_canceled,
run_all_recurrent_imports_failed,
run_recurrent_import,
) )
from ..filters import ( from ..filters import (
DuplicatedEventsFilter, DuplicatedEventsFilter,
EventFilter, EventFilter,
EventFilterAdmin, EventFilterAdmin,
MessagesFilterAdmin, MessagesFilterAdmin,
RecurrentImportFilter,
SearchEventFilter, SearchEventFilter,
SimpleSearchEventFilter, SimpleSearchEventFilter,
) )
@ -67,7 +62,6 @@ from ..forms import (
MergeDuplicates, MergeDuplicates,
MessageEventForm, MessageEventForm,
MessageForm, MessageForm,
RecurrentImportForm,
SelectEventInList, SelectEventInList,
SimpleContactForm, SimpleContactForm,
URLSubmissionFormSet, URLSubmissionFormSet,
@ -1299,191 +1293,6 @@ def event_search_full(request):
return event_search(request, True) return event_search(request, True)
#########################
## recurrent importations
#########################
@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_recurrentimport")
def recurrent_imports(request, status=None):
newest = BatchImportation.objects.filter(recurrentImport=OuterRef("pk")).order_by(
"-created_date"
)
qs = (
RecurrentImport.objects.all()
.annotate(last_run_status=Subquery(newest.values("status")[:1]))
.order_by("-pk")
)
nb_failed = qs.filter(last_run_status=BatchImportation.STATUS.FAILED).count()
nb_canceled = qs.filter(last_run_status=BatchImportation.STATUS.CANCELED).count()
nb_running = qs.filter(last_run_status=BatchImportation.STATUS.RUNNING).count()
nb_all = qs.count()
if status is not None:
qs = qs.filter(last_run_status=status)
filter = RecurrentImportFilter(request.GET, queryset=qs)
paginator = PaginatorFilter(filter, 20, request)
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/rimports.html",
{
"paginator_filter": response,
"filter": filter,
"nb_all": nb_all,
"nb_failed": nb_failed,
"nb_canceled": nb_canceled,
"nb_running": nb_running,
"status": status,
},
)
class RecurrentImportCreateView(
LoginRequiredMixin, PermissionRequiredMixin, CreateView
):
model = RecurrentImport
permission_required = "agenda_culturel.add_recurrentimport"
success_url = reverse_lazy("recurrent_imports")
form_class = RecurrentImportForm
class RecurrentImportUpdateView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
UpdateView,
):
model = RecurrentImport
permission_required = "agenda_culturel.change_recurrentimport"
form_class = RecurrentImportForm
success_message = _("The recurrent import has been successfully modified.")
class RecurrentImportDeleteView(
SuccessMessageMixin,
PermissionRequiredMixin,
LoginRequiredMixin,
DeleteView,
):
model = RecurrentImport
permission_required = "agenda_culturel.delete_recurrentimport"
success_url = reverse_lazy("recurrent_imports")
success_message = _("The recurrent import has been successfully deleted.")
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.view_batchimportation",
]
)
def view_rimport(request, pk):
obj = get_object_or_404(RecurrentImport, pk=pk)
paginator = Paginator(
BatchImportation.objects.filter(recurrentImport=pk).order_by("-created_date"),
10,
)
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/page-rimport.html",
{"paginator_filter": response, "object": obj},
)
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.run_recurrentimport",
]
)
def run_rimport(request, pk):
rimport = get_object_or_404(RecurrentImport, pk=pk)
if request.method == "POST":
# run recurrent import
run_recurrent_import.delay(pk)
messages.success(request, _("The import has been launched."))
return HttpResponseRedirect(reverse_lazy("view_rimport", args=[pk]))
else:
return render(
request,
"agenda_culturel/run_rimport_confirm.html",
{"object": rimport},
)
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.run_recurrentimport",
]
)
def run_all_rimports(request, status=None):
if request.method == "POST":
# run recurrent import
if status == BatchImportation.STATUS.FAILED:
run_all_recurrent_imports_failed.delay()
elif status == BatchImportation.STATUS.CANCELED:
run_all_recurrent_imports_canceled.delay()
else:
run_all_recurrent_imports.delay()
messages.success(request, _("Imports has been launched."))
return HttpResponseRedirect(reverse_lazy("recurrent_imports"))
else:
if status == BatchImportation.STATUS.FAILED:
return render(request, "agenda_culturel/run_failed_rimports_confirm.html")
elif status == BatchImportation.STATUS.CANCELED:
return render(request, "agenda_culturel/run_canceled_rimports_confirm.html")
else:
return render(request, "agenda_culturel/run_all_rimports_confirm.html")
@login_required(login_url="/accounts/login/")
@permission_required(
[
"agenda_culturel.view_recurrentimport",
"agenda_culturel.run_recurrentimport",
]
)
def run_all_fb_rimports(request, status=None):
if request.method == "POST":
run_all_recurrent_imports.delay(True)
messages.success(request, _("Facebook imports has been launched."))
return HttpResponseRedirect(reverse_lazy("recurrent_imports"))
else:
return render(request, "agenda_culturel/run_all_fb_rimports_confirm.html")
######################### #########################
## duplicated events ## duplicated events
######################### #########################