From 0c7280f50ef926768ad58337d4bb9384cfa3df2c Mon Sep 17 00:00:00 2001 From: SebF Date: Mon, 14 Apr 2025 18:07:05 +0200 Subject: [PATCH] =?UTF-8?q?S=C3=A9paration=20des=20vues=20export?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agenda_culturel/urls.py | 34 +++---- src/agenda_culturel/views/__init__.py | 1 + src/agenda_culturel/views/export_views.py | 103 ++++++++++++++++++++++ src/agenda_culturel/views/oldviews.py | 95 -------------------- 4 files changed, 122 insertions(+), 111 deletions(-) create mode 100644 src/agenda_culturel/views/export_views.py diff --git a/src/agenda_culturel/urls.py b/src/agenda_culturel/urls.py index 2d57292..3ea4e02 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -33,6 +33,9 @@ from .views import ( merge_duplicate, set_duplicate, update_duplicate_event, + # Export + export_event_ical, + export_ical, # General pages about, activite, @@ -102,11 +105,9 @@ from .views import ( month_view, day_view, upcoming_events, - export_ical, recent, administration, clear_cache, - export_event_ical, EventDetailView, EventUpdateView, StaticContentCreateView, @@ -187,6 +188,21 @@ urlpatterns = [ DuplicatedEventsDetailView.as_view(), name="view_duplicate", ), + # Export + path( + "event/////ical", + export_event_ical, + name="export_event_ical", + ), + path("cat:/ical", export_ical, name="export_ical_category"), + path("ical", export_ical, name="export_ical"), + path( + "organisme//ical", + export_ical, + name="export_ical_organisation", + ), + path("place//ical", export_ical, name="export_ical_place"), + path("tag//ical", export_ical, name="export_ical_tag"), path("duplicates/", duplicates, name="duplicates"), path("duplicates//fix", fix_duplicate, name="fix_duplicate"), # General pages @@ -416,7 +432,6 @@ urlpatterns = [ name="a_venir_jour_category", ), path("cat:/cette-semaine/", week_view, name="cette_semaine_category"), - path("cat:/ical", export_ical, name="export_ical_category"), path("cat:/ce-mois-ci", month_view, name="ce_mois_ci_category"), path("semaine///", week_view, name="week_view"), path("mois///", month_view, name="month_view"), @@ -431,7 +446,6 @@ urlpatterns = [ ), path("cette-semaine/", week_view, name="cette_semaine"), path("ce-mois-ci", month_view, name="ce_mois_ci"), - path("tag//ical", export_ical, name="export_ical_tag"), path("recent/", recent, name="recent"), path("administration/", administration, name="administration"), path( @@ -483,18 +497,6 @@ urlpatterns = [ name="edit_static_content", ), path("rimports//stats", statistics, name="stats_rimport"), - path( - "organisme//ical", - export_ical, - name="export_ical_organisation", - ), - path("place//ical", export_ical, name="export_ical_place"), - path( - "event/////ical", - export_event_ical, - name="export_event_ical", - ), - path("ical", export_ical, name="export_ical"), re_path(r"^robots\.txt", include("robots.urls")), path("__debug__/", include("debug_toolbar.urls")), path("ckeditor5/", include("django_ckeditor_5.urls")), diff --git a/src/agenda_culturel/views/__init__.py b/src/agenda_culturel/views/__init__.py index 5374993..9c383f5 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 .event_duplicate_views import * from .errors import * +from .export_views import * from .general_pages_views import * from .import_batch_views import * from .import_recurrent_views import * diff --git a/src/agenda_culturel/views/export_views.py b/src/agenda_culturel/views/export_views.py new file mode 100644 index 0000000..42600c2 --- /dev/null +++ b/src/agenda_culturel/views/export_views.py @@ -0,0 +1,103 @@ +import hashlib +from datetime import timedelta, date + +import emoji +from django.core.cache import cache + +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import get_object_or_404 + +from . import get_event_qs +from ..calendar import CalendarList +from ..filters import EventFilter +from ..models import Event, Category, Place, Organisation + + +def export_event_ical(request, year, month, day, pk): + event = get_object_or_404(Event, pk=pk) + event = event.get_recurrence_at_date(year, month, day) + + events = list() + events.append(event) + + cal = Event.export_to_ics(events, request) + + response = HttpResponse(content_type="text/calendar") + response.content = cal.to_ical().decode("utf-8").replace("\r\n", "\n") + response["Content-Disposition"] = "attachment; filename={0}{1}".format( + event.title.replace("\n", " ").replace("\r", "")[0:32], ".ics" + ) + + return response + + +def export_ical(request, cat=None, tag=None, organisation_pk=None, place_pk=None): + now = date.today() + + qs = get_event_qs(request) + if cat is not None: + category = Category.objects.filter(slug=cat).first() + qs = qs.filter(category=category) + else: + category = None + + if place_pk is not None: + qs = qs.filter(exact_location=place_pk) + if organisation_pk is not None: + qs = qs.filter(organisers__in=[organisation_pk]) + if tag is not None: + qs = qs.filter(tags__in=[tag]) + + request = EventFilter.set_default_values(request) + filter = EventFilter(request.GET, queryset=qs, request=request) + + if filter.has_category_parameters(): + return HttpResponseRedirect(filter.get_new_url()) + + id_cache = hashlib.md5( + ( + filter.get_url() + + "-" + + str(tag) + + "-" + + str(cat) + + "-" + + str(organisation_pk) + + "-" + + str(place_pk) + ).encode("utf8") + ).hexdigest() + ical = cache.get(id_cache) + if not ical: + calendar = CalendarList( + now + timedelta(days=-7), now + timedelta(days=+60), filter + ) + ical = calendar.export_to_ics(request) + cache.set(id_cache, ical, 3600) # 1 heure + + response = HttpResponse(content_type="text/calendar") + response.content = ical.to_ical().decode("utf-8").replace("\r\n", "\n") + extra = filter.to_str(" ") + if extra is None: + extra = "" + if category is not None: + extra += " " + str(category) + if place_pk is not None: + extra += ( + " @ " + Place.objects.filter(pk=place_pk).values("name").first()["name"] + ) + if organisation_pk is not None: + extra += ( + " - " + + Organisation.objects.filter(pk=organisation_pk) + .values("name") + .first()["name"] + ) + if tag is not None: + extra += " - " + emoji.replace_emoji(tag, replace="") + + response["Content-Disposition"] = "attachment; filename={0}{1}{2}".format( + "Pommes de lune", extra, ".ics" + ) + + return response diff --git a/src/agenda_culturel/views/oldviews.py b/src/agenda_culturel/views/oldviews.py index f4efc10..774fdf4 100644 --- a/src/agenda_culturel/views/oldviews.py +++ b/src/agenda_culturel/views/oldviews.py @@ -1,8 +1,6 @@ -import hashlib import logging from datetime import date, timedelta -import emoji from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.mixins import ( @@ -16,7 +14,6 @@ from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db.models import Aggregate, FloatField from django.db.models import F, OuterRef, Q, Subquery from django.http import ( - HttpResponse, HttpResponseForbidden, HttpResponseRedirect, ) @@ -60,8 +57,6 @@ from ..models import ( DuplicatedEvents, Event, Message, - Organisation, - Place, RecurrentImport, StaticContent, UserProfile, @@ -826,96 +821,6 @@ def import_from_url(request): ) -def export_event_ical(request, year, month, day, pk): - event = get_object_or_404(Event, pk=pk) - event = event.get_recurrence_at_date(year, month, day) - - events = list() - events.append(event) - - cal = Event.export_to_ics(events, request) - - response = HttpResponse(content_type="text/calendar") - response.content = cal.to_ical().decode("utf-8").replace("\r\n", "\n") - response["Content-Disposition"] = "attachment; filename={0}{1}".format( - event.title.replace("\n", " ").replace("\r", "")[0:32], ".ics" - ) - - return response - - -def export_ical(request, cat=None, tag=None, organisation_pk=None, place_pk=None): - now = date.today() - - qs = get_event_qs(request) - if cat is not None: - category = Category.objects.filter(slug=cat).first() - qs = qs.filter(category=category) - else: - category = None - - if place_pk is not None: - qs = qs.filter(exact_location=place_pk) - if organisation_pk is not None: - qs = qs.filter(organisers__in=[organisation_pk]) - if tag is not None: - qs = qs.filter(tags__in=[tag]) - - request = EventFilter.set_default_values(request) - filter = EventFilter(request.GET, queryset=qs, request=request) - - if filter.has_category_parameters(): - return HttpResponseRedirect(filter.get_new_url()) - - id_cache = hashlib.md5( - ( - filter.get_url() - + "-" - + str(tag) - + "-" - + str(cat) - + "-" - + str(organisation_pk) - + "-" - + str(place_pk) - ).encode("utf8") - ).hexdigest() - ical = cache.get(id_cache) - if not ical: - calendar = CalendarList( - now + timedelta(days=-7), now + timedelta(days=+60), filter - ) - ical = calendar.export_to_ics(request) - cache.set(id_cache, ical, 3600) # 1 heure - - response = HttpResponse(content_type="text/calendar") - response.content = ical.to_ical().decode("utf-8").replace("\r\n", "\n") - extra = filter.to_str(" ") - if extra is None: - extra = "" - if category is not None: - extra += " " + str(category) - if place_pk is not None: - extra += ( - " @ " + Place.objects.filter(pk=place_pk).values("name").first()["name"] - ) - if organisation_pk is not None: - extra += ( - " - " - + Organisation.objects.filter(pk=organisation_pk) - .values("name") - .first()["name"] - ) - if tag is not None: - extra += " - " + emoji.replace_emoji(tag, replace="") - - response["Content-Disposition"] = "attachment; filename={0}{1}{2}".format( - "Pommes de lune", extra, ".ics" - ) - - return response - - @login_required(login_url="/accounts/login/") @permission_required("agenda_culturel.view_event") def administration(request):