From 0c283e4ae0cd26e910f1a9f2270a75b6cd64ffdd Mon Sep 17 00:00:00 2001 From: SebF Date: Fri, 3 May 2024 18:54:07 +0200 Subject: [PATCH 1/5] first poc --- .../agenda_culturel/single-event/event-single-inc.html | 7 ++++--- src/agenda_culturel/urls.py | 1 + src/agenda_culturel/views.py | 8 ++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html b/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html index fe179b6..ce14523 100644 --- a/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html +++ b/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html @@ -70,11 +70,12 @@ {% endif %}

- {% if perms.agenda_culturel.change_event and not noedit %}
- {% include "agenda_culturel/edit-buttons-inc.html" with event=event %} + Exporter ical {% picto_from_name "calendar" %} + {% if perms.agenda_culturel.change_event and not noedit %} + {% include "agenda_culturel/edit-buttons-inc.html" with event=event %} + {% endif %}
- {% endif %} diff --git a/src/agenda_culturel/urls.py b/src/agenda_culturel/urls.py index e526ff3..9ff32f5 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -158,6 +158,7 @@ urlpatterns = [ UnknownPlaceAddView.as_view(), name="add_place_to_event", ), + path("event/", export_event_ical, name="export_event_ical"), ] if settings.DEBUG: diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 15ba308..ef3c06a 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -598,6 +598,14 @@ def import_from_url(request): ) +def export_event_ical(request, pk): + event = get_object_or_404(Event, pk=pk) + logger = logging.getLogger(__name__) + logger.info("titre event" + event.title) + + return HttpResponse(event.title + ".ical", content_type="text/calendar") + + class EventFilterAdmin(django_filters.FilterSet): status = django_filters.MultipleChoiceFilter( choices=Event.STATUS.choices, widget=forms.CheckboxSelectMultiple From 1fef9eeef9e3796f6819ece99b4c14a428776173 Mon Sep 17 00:00:00 2001 From: SebF Date: Sat, 4 May 2024 15:47:39 +0200 Subject: [PATCH 2/5] export single event --- src/agenda_culturel/models.py | 40 +++++++++++++++++++++++++++++++++++ src/agenda_culturel/views.py | 15 +++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/agenda_culturel/models.py b/src/agenda_culturel/models.py index e7dfc7f..b1c9a32 100644 --- a/src/agenda_culturel/models.py +++ b/src/agenda_culturel/models.py @@ -26,6 +26,8 @@ from django.utils import timezone from location_field.models.plain import PlainLocationField from .calendar import CalendarList, CalendarDay +from icalendar import Calendar as icalCal +from icalendar import Event as icalEvent import logging @@ -1090,6 +1092,44 @@ class Event(models.Model): return (dtstart <= e_dtstart <= dtend) or (e_dtstart <= dtstart <= e_dtend) + def export_to_ics(events): + cal = icalCal() + # Some properties are required to be compliant + cal.add("prodid", "-//My calendar product//example.com//") + cal.add("version", "2.0") + + for event in events: + eventIcal = icalEvent() + # mapping + eventIcal.add( + "dtstart", + datetime( + event.start_day.year, + event.start_day.month, + event.start_day.day, + event.start_time.hour, + event.start_time.minute, + ), + ) + eventIcal.add( + "dtend", + datetime( + event.end_day.year, + event.end_day.month, + event.end_day.day, + event.end_time.hour, + event.end_time.minute, + ), + ) + eventIcal.add("summary", event.title) + eventIcal.add("name", event.title) + eventIcal.add("description", event.description + "\r" + event.reference_urls[0]) + eventIcal.add("location", event.exact_location or event.location) + + cal.add_component(eventIcal) + + return cal + class ContactMessage(models.Model): class Meta: diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index ef3c06a..96457b6 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -10,7 +10,7 @@ from django.http import QueryDict from django import forms from django.contrib.postgres.search import SearchQuery, SearchHeadline -from django.http import HttpResponseRedirect +from django.http import HttpResponseRedirect, HttpResponse, HttpResponseNotFound, FileResponse from django.urls import reverse from collections import Counter @@ -600,10 +600,17 @@ def import_from_url(request): def export_event_ical(request, pk): event = get_object_or_404(Event, pk=pk) - logger = logging.getLogger(__name__) - logger.info("titre event" + event.title) - return HttpResponse(event.title + ".ical", content_type="text/calendar") + events = list() + events.append(event) + + cal = Event.export_to_ics(events) + + return FileResponse( + cal.to_ical().decode("utf-8").replace("\r\n", "\n"), + as_attachment=True, + filename= event.title + ".ics", + content_type="text/calendar") class EventFilterAdmin(django_filters.FilterSet): From 59d93cf6862a6a39c413824cb315420e1ddca06f Mon Sep 17 00:00:00 2001 From: SebF Date: Sat, 4 May 2024 15:52:54 +0200 Subject: [PATCH 3/5] make format --- src/agenda_culturel/models.py | 4 +++- src/agenda_culturel/views.py | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/agenda_culturel/models.py b/src/agenda_culturel/models.py index b1c9a32..b92f9b6 100644 --- a/src/agenda_culturel/models.py +++ b/src/agenda_culturel/models.py @@ -1123,7 +1123,9 @@ class Event(models.Model): ) eventIcal.add("summary", event.title) eventIcal.add("name", event.title) - eventIcal.add("description", event.description + "\r" + event.reference_urls[0]) + eventIcal.add( + "description", event.description + "\r" + event.reference_urls[0] + ) eventIcal.add("location", event.exact_location or event.location) cal.add_component(eventIcal) diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 96457b6..630dce1 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -10,7 +10,7 @@ from django.http import QueryDict from django import forms from django.contrib.postgres.search import SearchQuery, SearchHeadline -from django.http import HttpResponseRedirect, HttpResponse, HttpResponseNotFound, FileResponse +from django.http import HttpResponseRedirect, FileResponse from django.urls import reverse from collections import Counter @@ -608,9 +608,10 @@ def export_event_ical(request, pk): return FileResponse( cal.to_ical().decode("utf-8").replace("\r\n", "\n"), - as_attachment=True, - filename= event.title + ".ics", - content_type="text/calendar") + as_attachment=True, + filename=event.title + ".ics", + content_type="text/calendar", + ) class EventFilterAdmin(django_filters.FilterSet): From 1a52d02141b0f888eabbf269834aaa24e72544dc Mon Sep 17 00:00:00 2001 From: SebF Date: Mon, 6 May 2024 16:11:48 +0200 Subject: [PATCH 4/5] correction du nom de fichier --- src/agenda_culturel/views.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 630dce1..fb56d95 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -10,7 +10,7 @@ from django.http import QueryDict from django import forms from django.contrib.postgres.search import SearchQuery, SearchHeadline -from django.http import HttpResponseRedirect, FileResponse +from django.http import HttpResponseRedirect, HttpResponse from django.urls import reverse from collections import Counter @@ -606,13 +606,14 @@ def export_event_ical(request, pk): cal = Event.export_to_ics(events) - return FileResponse( - cal.to_ical().decode("utf-8").replace("\r\n", "\n"), - as_attachment=True, - filename=event.title + ".ics", - content_type="text/calendar", + 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, ".ics" ) + return response + class EventFilterAdmin(django_filters.FilterSet): status = django_filters.MultipleChoiceFilter( From bf043f954da3f248c43ce6b3ba177f6d02334515 Mon Sep 17 00:00:00 2001 From: Jean-Marie Favreau Date: Sat, 1 Jun 2024 10:52:24 +0200 Subject: [PATCH 5/5] fix export for recurrent events --- .../agenda_culturel/single-event/event-single-inc.html | 2 +- src/agenda_culturel/urls.py | 5 ++++- src/agenda_culturel/views.py | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html b/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html index ce14523..d29e73a 100644 --- a/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html +++ b/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html @@ -71,7 +71,7 @@

- Exporter ical {% picto_from_name "calendar" %} + Exporter ical {% picto_from_name "calendar" %} {% if perms.agenda_culturel.change_event and not noedit %} {% include "agenda_culturel/edit-buttons-inc.html" with event=event %} {% endif %} diff --git a/src/agenda_culturel/urls.py b/src/agenda_culturel/urls.py index 9ff32f5..695051e 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -158,7 +158,10 @@ urlpatterns = [ UnknownPlaceAddView.as_view(), name="add_place_to_event", ), - path("event/", export_event_ical, name="export_event_ical"), + path( + "event/////ical", + export_event_ical, + name="export_event_ical"), ] if settings.DEBUG: diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index fb56d95..29a0d9d 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -598,8 +598,9 @@ def import_from_url(request): ) -def export_event_ical(request, pk): +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)