From 77b459114d1087f3327a81e2085df355ff691470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Mogu=C3=A9rou?= Date: Sat, 20 Apr 2024 02:35:09 +0200 Subject: [PATCH] ics export --- colloscope/icalexport.py | 50 ++++++++++++++++++++++++++++++++++++++++ colloscope/models.py | 9 ++++++-- colloscope/urls.py | 1 + colloscope/views.py | 26 +++++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 colloscope/icalexport.py diff --git a/colloscope/icalexport.py b/colloscope/icalexport.py new file mode 100644 index 0000000..355b116 --- /dev/null +++ b/colloscope/icalexport.py @@ -0,0 +1,50 @@ +from datetime import date, time, datetime, timedelta +from pytz import timezone + +from icalendar import Calendar, Event, vCalAddress, vText + +from colloscope.models import * + + +def to_calendar(etudiant, periode): + cal = Calendar() + + cal.add("prodid", "-//Colloscope//colles.mp2i-vms.fr//") + cal.add("version", "2.0") + + rotations = Rotation.objects \ + .filter(groupes__membres=etudiant) \ + .select_related("creneau__periode__classe__lycee") \ + .select_related("creneau__matiere") \ + .select_related("creneau__colleur") \ + + for rotation in rotations: + event = Event() + event.add("name", "Colle") + event.add("summary", str(rotation)) + + start = rotation.datetime() + fin = start + rotation.creneau.duree + + event.add("dtstart", start) + event.add("dtend", fin) + event.add("dtstamp", datetime.now()) + + event.add("location", f"{rotation.creneau.salle} ({rotation.creneau.periode.classe.lycee})") + event.add("matiere", str(rotation.creneau.matiere)) + + organizer = vCalAddress("mailto:unknown@mp2i-vms.fr") + organizer.params["cn"] = vText(str(rotation.creneau.colleur)) + organizer.params["role"] = vText("Colleur") + event.add("organizer", organizer) + + for e in rotation.groupe_effectif(): + attendee = vCalAddress("mailto:unknown@mp2i-vms.fr") + attendee.params["cn"] = vText(str(e)) + attendee.params["role"] = vText("Etudiant") + + event.add("attendee", attendee, encode=0) + + cal.add_component(event) + + return cal diff --git a/colloscope/models.py b/colloscope/models.py index 4f76f57..38b7872 100644 --- a/colloscope/models.py +++ b/colloscope/models.py @@ -1,4 +1,5 @@ from datetime import date, datetime, timedelta +from pytz import timezone from django.db import models from django.db.models import F, Q @@ -21,8 +22,8 @@ class Lycee(models.Model): libelle = models.CharField(max_length=100) vacances = models.CharField(max_length=1) - def __self__(self): - return self.uai + def __str__(self): + return self.libelle class Classe(models.Model): @@ -328,6 +329,10 @@ class Rotation(models.Model): def __str__(self): return f"{self.creneau} le {self.date} avec groupes {'+'.join(str(groupe) for groupe in self.groupes.all())}" + + def datetime(self): + return datetime.combine( self.date, self.creneau.heure, tzinfo=timezone("Europe/Paris") ) + class Amendement(models.Model): est_positif = models.BooleanField() diff --git a/colloscope/urls.py b/colloscope/urls.py index 72ec4e2..aa72ca1 100644 --- a/colloscope/urls.py +++ b/colloscope/urls.py @@ -6,5 +6,6 @@ urlpatterns = [ path("table.html", views.colloscope, name="colloscope.table"), path("dashboard.html", views.dashboard, name="colloscope.dashboard"), path("export.pdf", views.export, name="colloscope.export"), + path("calendrier.ics", views.icalendar, name="colloscope.calendrier"), path("choix_profil", views.choix_profil, name="colloscope.choix_profil"), ] diff --git a/colloscope/views.py b/colloscope/views.py index beb9dc5..6e7b89f 100644 --- a/colloscope/views.py +++ b/colloscope/views.py @@ -8,6 +8,7 @@ from django.contrib.auth.decorators import login_required from colloscope.models import * from colloscope.table import table_colloscope from colloscope.pdfexport import handle +from colloscope.icalexport import to_calendar def handler404(request): @@ -150,9 +151,34 @@ def colloscope(request): return HttpResponse(template.render(context, request)) +@login_required def export(request): return HttpResponse(bytes(handle(request).output()), content_type="application/pdf") +@login_required +def icalendar(request): + user = request.user + session = request.session + + try: + etudiant = Profil.from_request( + request, + preprocess=lambda query: query \ + .select_related("etudiant__classe") \ + .prefetch_related("etudiant__classe__periode_set") + ) + except ValueError: + return redirect("colloscope.choix_profil") + + if not isinstance(etudiant, Etudiant): + return HttpResponse("pas encore supporté") + + periode = etudiant.classe.periode_actuelle() + + return HttpResponse(to_calendar(etudiant, periode).to_ical(), content_type="text/calendar") + + + def data_dump(request): template = loader.get_template("data_dump.html") return HttpResponse(template.render())