async work but meant to be WIP until I have a lot of time...

This commit is contained in:
Valentin Moguérou 2024-04-30 23:38:38 +02:00
parent bcb94faac5
commit a6e02eb966
5 changed files with 47 additions and 54 deletions

View File

@ -6,10 +6,10 @@ from pathlib import Path
pd_eleves = pandas.read_csv('Resources/eleves-v2.csv', delimiter=";", header=None) #pd_eleves = pandas.read_csv('Resources/eleves-v2.csv', delimiter=";", header=None)
np_eleves = pd_eleves.to_numpy() #np_eleves = pd_eleves.to_numpy()
pd_colles = pandas.read_csv('Resources/colloscope-v3.csv', delimiter=";", header=None) pd_colles = pandas.read_csv('static/colloscope-v3.csv', delimiter=";", header=None)
np_colles = pd_colles.to_numpy() np_colles = pd_colles.to_numpy()
local_tz = "Europe/Paris" local_tz = "Europe/Paris"

View File

@ -5,7 +5,7 @@ from os import path
from icalendar import Calendar, Event, vCalAddress, vText from icalendar import Calendar, Event, vCalAddress, vText
from colloscope.models import * from colloscope.models import *
from create_calendar import get_calendar from .create_calendar import get_calendar
LOCAL_TZ = "Europe/Paris" LOCAL_TZ = "Europe/Paris"
@ -23,18 +23,12 @@ def emailize(nom, prenom=None):
def to_calendar(etudiant, periode, include_EDT: bool = True): def to_calendar(etudiant, periode, include_EDT: bool = True):
p = path.abspath('./static/Base_Calendar.ics') p = path.abspath('./static/Base_Calendar.ics')
with open(p) as f: with open(p) as f:
cal = Calendar.from_ical(f.read()) cal = Calendar.from_ical(f.read())
rotations = periode.query_rotations_etudiant(etudiant)
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: for rotation in rotations:
event = Event() event = Event()
@ -50,12 +44,11 @@ def to_calendar(etudiant, periode, include_EDT: bool = True):
event.add("dtstamp", datetime.now()) event.add("dtstamp", datetime.now())
event.add("uid", str(uuid4())) event.add("uid", str(uuid4()))
event.add("location", f"{rotation.creneau.salle} ({rotation.creneau.periode.classe.lycee})") event.add("location", f"{rotation.creneau.salle} ({rotation.creneau.periode.classe.lycee})")
event.add("categories", "COLLE-" + str(rotation.creneau.matiere)) event.add("categories", "COLLE-" + str(rotation.creneau.matiere))
description = f"Groupes: {','.join(str(groupe) for groupe in rotation.groupes.all())}" description = f"Groupes: {','.join(str(groupe) for groupe in rotation.groupes.all())}"
event.add(description) event.add("description", description)
organizer = vCalAddress(f"mailto:{emailize(rotation.creneau.colleur.nom)}") organizer = vCalAddress(f"mailto:{emailize(rotation.creneau.colleur.nom)}")
organizer.params["cn"] = vText(str(rotation.creneau.colleur)) organizer.params["cn"] = vText(str(rotation.creneau.colleur))
@ -71,11 +64,13 @@ def to_calendar(etudiant, periode, include_EDT: bool = True):
cal.add_component(event) cal.add_component(event)
"""
if include_EDT: if include_EDT:
#TODO: get le groupe de l'étudiant et ses langue #TODO: get le groupe de l'étudiant et ses langue
edt = get_calendar() edt = get_calendar()
for event in edt.walk("VEVENT"): for event in edt.walk("VEVENT"):
cal.add_component(event) cal.add_component(event)
"""
return cal return cal

View File

@ -52,7 +52,7 @@ class Classe(models.Model):
vacances = calendrier[zone] vacances = calendrier[zone]
jour0 = self.jour_zero jour0 = self.jour_zero
n = 1 + ((jour - jour0).days) // 7 n = 1 + (jour - jour0).days // 7
for debut, fin in vacances: for debut, fin in vacances:
if jour > debut: if jour > debut:
n -= round((fin - debut) / timedelta(weeks=1)) n -= round((fin - debut) / timedelta(weeks=1))
@ -91,7 +91,7 @@ class Classe(models.Model):
return jour return jour
def periode(self, jour): async def periode(self, jour):
""" """
Entrées : Entrées :
- self - self
@ -104,9 +104,9 @@ class Classe(models.Model):
- Le jour n'est pas dans une période - Le jour n'est pas dans une période
- Le jour est au chevauchement de deux périodes - Le jour est au chevauchement de deux périodes
""" """
return Periode.objects.get(classe=self, debut__lte=jour, fin__gte=jour) return Periode.objects.aget(classe=self, debut__lte=jour, fin__gte=jour)
def periode_actuelle(self): async def periode_actuelle(self):
#return self.periode(date.today()) // ne fonctionne pas entre les périodes #return self.periode(date.today()) // ne fonctionne pas entre les périodes
""" """
On prend la période non révolue la plus récente On prend la période non révolue la plus récente
@ -115,7 +115,7 @@ class Classe(models.Model):
return Periode.objects \ return Periode.objects \
.filter(classe=self, fin__gte=date.today()) \ .filter(classe=self, fin__gte=date.today()) \
.order_by("-debut") \ .order_by("-debut") \
.first() .afirst()
def __str__(self): def __str__(self):
return f"{self.libelle} ({self.lycee.libelle})" return f"{self.libelle} ({self.lycee.libelle})"
@ -356,10 +356,6 @@ class Rotation(models.Model):
amendement = Amendement(rotation=self, etudiant=etudiant, est_positif=est_positif) amendement = Amendement(rotation=self, etudiant=etudiant, est_positif=est_positif)
amendement.save() amendement.save()
if notifier:
loop =
asyncio.run_until_complete(amendement.notifier())
def __str__(self): def __str__(self):
return f"{self.creneau} le {self.date} avec groupes {'+'.join(str(groupe) for groupe in self.groupes.all())}" return f"{self.creneau} le {self.date} avec groupes {'+'.join(str(groupe) for groupe in self.groupes.all())}"
@ -391,16 +387,16 @@ class Profil(models.Model):
return f"Profil {self.utilisateur} : {self.etudiant} ; {self.colleur}" return f"Profil {self.utilisateur} : {self.etudiant} ; {self.colleur}"
@staticmethod @staticmethod
def from_request(request, preprocess=lambda query: query): async def from_request(request, preprocess=lambda query: query):
user = request.user user = request.user
session = request.session session = request.session
match session.get("profil"): match await session.aget("profil"):
case "etudiant": case "etudiant":
profil = preprocess(Profil.objects.filter(utilisateur=user)).get() profil = await preprocess(Profil.objects.filter(utilisateur=user)).aget()
return profil.etudiant return profil.etudiant
case "colleur": case "colleur":
profil = preprocess(Profil.objects.filter(utilisateur=user)).get() profil = await preprocess(Profil.objects.filter(utilisateur=user)).aget()
return profil.colleur return profil.colleur
case _: case _:
raise ValueError("profil non choisi") raise ValueError("profil non choisi")

View File

@ -53,25 +53,25 @@ def choix_profil(request):
return HttpResponse(template.render(context)) return HttpResponse(template.render(context))
def get_lien_calendrier(etudiant, periode): async def get_lien_calendrier(etudiant, periode):
try: try:
lien = LienCalendrier.objects.get(etudiant=etudiant, periode=periode) lien = await LienCalendrier.objects.aget(etudiant=etudiant, periode=periode)
except LienCalendrier.DoesNotExist: except LienCalendrier.DoesNotExist:
code = uuid4().hex code = uuid4().hex
lien = LienCalendrier(code=code, etudiant=etudiant, periode=periode) lien = LienCalendrier(code=code, etudiant=etudiant, periode=periode)
lien.save() await lien.asave()
return f"calendrier.ics?key={lien.code}" return f"calendrier.ics?key={lien.code}"
@login_required #@login_required
def dashboard(request): async def dashboard(request):
try: try:
etudiant = Profil.from_request( etudiant = await Profil.from_request(
request, request,
preprocess=lambda query: query \ preprocess=lambda query: (query
.select_related("etudiant__classe") \ .select_related("etudiant__classe")
.prefetch_related("etudiant__classe__periode_set") .prefetch_related("etudiant__classe__periode_set"))
) )
except ValueError: except ValueError:
return redirect("colloscope.choix_profil") return redirect("colloscope.choix_profil")
@ -79,19 +79,19 @@ def dashboard(request):
if not isinstance(etudiant, Etudiant): if not isinstance(etudiant, Etudiant):
return HttpResponse("pas encore supporté") return HttpResponse("pas encore supporté")
periode = etudiant.classe.periode_actuelle() periode = await etudiant.classe.periode_actuelle()
groupe = etudiant.groupe_de_colle(periode) groupe = await etudiant.groupe_de_colle(periode)
rotations = periode.query_rotations_etudiant(etudiant) rotations = periode.query_rotations_etudiant(etudiant)
colles_par_sem = [None] * len(periode.range_semaines()) colles_par_sem = [None] * len(periode.range_semaines())
for i, n in enumerate(periode.range_semaines()): for i, n in enumerate(periode.range_semaines()):
lundi = periode.classe.date_debut_sem(n) lundi = periode.classe.date_debut_sem(n)
colles = rotations.filter(date__gte=lundi, date__lt=lundi+timedelta(weeks=1)) colles = rotations.filter(date__gte=lundi, date__lt=lundi + timedelta(weeks=1))
colles_par_sem[i] = n, lundi, colles colles_par_sem[i] = n, lundi, colles
template = loader.get_template("dashboard.html") template = loader.get_template("dashboard.html")
lien_calendrier = get_lien_calendrier(etudiant, periode) lien_calendrier = await get_lien_calendrier(etudiant, periode)
context = { context = {
"etudiant": etudiant, "etudiant": etudiant,
@ -105,9 +105,9 @@ def dashboard(request):
@login_required @login_required
def marketplace(request): async def marketplace(request):
try: try:
etudiant = Profil.from_request( etudiant = await Profil.from_request(
request, request,
preprocess=lambda query: query \ preprocess=lambda query: query \
.select_related("etudiant__classe") \ .select_related("etudiant__classe") \
@ -119,14 +119,13 @@ def marketplace(request):
if not isinstance(etudiant, Etudiant): if not isinstance(etudiant, Etudiant):
return HttpResponse("pas encore supporté") return HttpResponse("pas encore supporté")
periode = etudiant.classe.periode_actuelle() periode = etudiant.classe.periode_actuelle()
colles = periode.query_rotations_not_full() colles = periode.query_rotations_not_full()
template = loader.get_template("marketplace.html") template = loader.get_template("marketplace.html")
context = { context = {
"colles" : colles "colles": colles
} }
return HttpResponse(template.render(context, request)) return HttpResponse(template.render(context, request))
@ -262,6 +261,7 @@ def amender(request, colle_id, est_positif):
def inscription(request, colle_id): def inscription(request, colle_id):
return amender(request, colle_id, True) return amender(request, colle_id, True)
@login_required @login_required
def desinscription(request, colle_id): def desinscription(request, colle_id):
return amender(request, colle_id, False) return amender(request, colle_id, False)

View File

@ -39,6 +39,7 @@ CORS_ORIGIN_WHITELIST = [
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
"daphne",
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
@ -76,7 +77,8 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = 'kholles_web.wsgi.application' ASGI_APPLICATION = "kholles_web.asgi.application"
#WSGI_APPLICATION = 'kholles_web.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases # https://docs.djangoproject.com/en/5.0/ref/settings/#databases