mirror of https://gitlab.crans.org/bde/nk20
Export activites as an ICS Calendar
This commit is contained in:
parent
5c7fe716ad
commit
70e1a611dd
|
@ -14,4 +14,5 @@ urlpatterns = [
|
||||||
path('<int:pk>/entry/', views.ActivityEntryView.as_view(), name='activity_entry'),
|
path('<int:pk>/entry/', views.ActivityEntryView.as_view(), name='activity_entry'),
|
||||||
path('<int:pk>/update/', views.ActivityUpdateView.as_view(), name='activity_update'),
|
path('<int:pk>/update/', views.ActivityUpdateView.as_view(), name='activity_update'),
|
||||||
path('new/', views.ActivityCreateView.as_view(), name='activity_create'),
|
path('new/', views.ActivityCreateView.as_view(), name='activity_create'),
|
||||||
|
path('calendar.ics', views.CalendarView.as_view(), name='calendar_ics'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db.models import F, Q
|
from django.db.models import F, Q
|
||||||
|
from django.http import HttpResponse
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views import View
|
||||||
from django.views.generic import DetailView, TemplateView, UpdateView
|
from django.views.generic import DetailView, TemplateView, UpdateView
|
||||||
from django_tables2.views import SingleTableView
|
from django_tables2.views import SingleTableView
|
||||||
from note.models import Alias, NoteSpecial, NoteUser
|
from note.models import Alias, NoteSpecial, NoteUser
|
||||||
|
@ -281,3 +284,61 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView):
|
||||||
Entry(activity=a, note=self.request.user.note,))]
|
Entry(activity=a, note=self.request.user.note,))]
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarView(View):
|
||||||
|
"""
|
||||||
|
Render an ICS calendar with all valid activities.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def multilines(self, string, maxlength, offset=0):
|
||||||
|
newstring = string[:maxlength - offset]
|
||||||
|
string = string[maxlength - offset:]
|
||||||
|
while string:
|
||||||
|
newstring += "\r\n "
|
||||||
|
newstring += string[:maxlength - 1]
|
||||||
|
string = string[maxlength - 1:]
|
||||||
|
return newstring
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
ics = """BEGIN:VCALENDAR
|
||||||
|
VERSION: 2.0
|
||||||
|
PRODID:Note Kfet 2020
|
||||||
|
X-WR-CALNAME:Kfet Calendar
|
||||||
|
NAME:Kfet Calendar
|
||||||
|
CALSCALE:GREGORIAN
|
||||||
|
BEGIN:VTIMEZONE
|
||||||
|
TZID:Europe/Berlin
|
||||||
|
TZURL:http://tzurl.org/zoneinfo-outlook/Europe/Berlin
|
||||||
|
X-LIC-LOCATION:Europe/Berlin
|
||||||
|
BEGIN:DAYLIGHT
|
||||||
|
TZOFFSETFROM:+0100
|
||||||
|
TZOFFSETTO:+0200
|
||||||
|
TZNAME:CEST
|
||||||
|
DTSTART:19700329T020000
|
||||||
|
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
|
||||||
|
END:DAYLIGHT
|
||||||
|
BEGIN:STANDARD
|
||||||
|
TZOFFSETFROM:+0200
|
||||||
|
TZOFFSETTO:+0100
|
||||||
|
TZNAME:CET
|
||||||
|
DTSTART:19701025T030000
|
||||||
|
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
|
||||||
|
END:STANDARD
|
||||||
|
END:VTIMEZONE
|
||||||
|
"""
|
||||||
|
for activity in Activity.objects.filter(valid=True).order_by("-date_start").all():
|
||||||
|
ics += f"""BEGIN:VEVENT
|
||||||
|
DTSTAMP:{"{:%Y%m%dT%H%M%S}".format(activity.date_start)}Z
|
||||||
|
UID:{activity.id}
|
||||||
|
SUMMARY;CHARSET=UTF-8:{self.multilines(activity.name, 75, 22)}
|
||||||
|
DTSTART;TZID=Europe/Berlin:{"{:%Y%m%dT%H%M%S}".format(activity.date_start)}
|
||||||
|
DTEND;TZID=Europe/Berlin:{"{:%Y%m%dT%H%M%S}".format(activity.date_end)}
|
||||||
|
LOCATION:{self.multilines(activity.location, 75, 9) if activity.location else "Kfet"}
|
||||||
|
DESCRIPTION;CHARSET=UTF-8:{self.multilines(activity.description, 75, 26)}
|
||||||
|
-- {activity.organizer.name}
|
||||||
|
END:VEVENT
|
||||||
|
"""
|
||||||
|
ics += "END:VCALENDAR"
|
||||||
|
ics = ics.replace("\r", "").replace("\n", "\r\n")
|
||||||
|
return HttpResponse(ics, content_type="text/calendar; charset=UTF-8")
|
||||||
|
|
|
@ -117,10 +117,7 @@ def delete_object(sender, instance, **kwargs):
|
||||||
Each time a model is deleted, an entry in the table `Changelog` is added in the database
|
Each time a model is deleted, an entry in the table `Changelog` is added in the database
|
||||||
"""
|
"""
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
if instance._meta.label_lower in EXCLUDED:
|
if instance._meta.label_lower in EXCLUDED or hasattr(instance, "_no_log"):
|
||||||
return
|
|
||||||
|
|
||||||
if hasattr(instance, "_no_log"):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Si un utilisateur est connecté, on récupère l'utilisateur courant ainsi que son adresse IP
|
# Si un utilisateur est connecté, on récupère l'utilisateur courant ainsi que son adresse IP
|
||||||
|
|
Loading…
Reference in New Issue