diff --git a/src/agenda_culturel/models.py b/src/agenda_culturel/models.py index e7dfc7f..b92f9b6 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,46 @@ 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/templates/agenda_culturel/single-event/event-single-inc.html b/src/agenda_culturel/templates/agenda_culturel/single-event/event-single-inc.html index fe179b6..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 @@ -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..695051e 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -158,6 +158,10 @@ urlpatterns = [ UnknownPlaceAddView.as_view(), name="add_place_to_event", ), + 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 15ba308..29a0d9d 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 from django.urls import reverse from collections import Counter @@ -598,6 +598,24 @@ 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) + + 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( choices=Event.STATUS.choices, widget=forms.CheckboxSelectMultiple