colles.mp2i-vms.fr/colloscope/views.py

291 lines
8.4 KiB
Python

from uuid import uuid4
from django import forms
from django.shortcuts import redirect, render
from django.http import HttpResponse, HttpResponseRedirect
from django.template import loader
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required
from colloscope.models import *
from colloscope.pdfexport import handle
from colloscope.icalexport import to_calendar
def handler404(request):
template = loader.get_template("404.html")
context = {}
return HttpResponse(template.render(context), status=404)
def home_redirect(request):
return redirect("/colloscope/dashboard.html")
@login_required
def select_profile(request):
user = request.user
session = request.session
if not Profile.objects.filter(user=user).exists():
profile = Profile(user=user)
profile.save()
else:
profile = Profile.objects.get(user=user)
if profile.student is not None and profile.colleur is None:
session["profile"] = "student"
return redirect("/colloscope/")
elif profile.colleur is not None and profile.student is None:
session["profile"] = "colleur"
return redirect("/colloscope/")
else:
if profile.student is not None:
template = loader.get_template("select_profile.html")
else:
template = loader.get_template("unbound_profile.html")
context = {
"profile": profile,
}
return HttpResponse(template.render(context))
def get_lien_calendrier(student, term):
try:
lien = CalendarLink.objects.get(student=student, term=term)
except CalendarLink.DoesNotExist:
key = uuid4().hex
lien = CalendarLink(key=key, student=student, term=term)
lien.save()
return f"calendrier.ics?key={lien.key}"
@login_required
def dashboard(request):
try:
student = Profile.from_request(
request,
preprocess=lambda query: (query
.select_related("student__cls")
.prefetch_related("student__cls__term_set"))
)
except ValueError:
return redirect("colloscope.select_profile")
if not isinstance(student, Student):
return HttpResponse("pas encore supporté")
term = student.cls.current_term()
group = student.colle_group(term)
colles = term.query_colles_of_student(student)
colles_per_sem = [None] * len(term.range_weeks())
for k, n in enumerate(term.range_weeks()):
lundi = term.cls.week_beginning_date(n)
colles_per_sem[k] = n, lundi, colles.filter(datetime__gte=max(lundi, date.today()),
datetime__lt=lundi + timedelta(weeks=1))
template = loader.get_template("dashboard.html")
calendar_link = get_calendar_link(student, term)
context = {
"student": student,
"term": term,
"group": group,
"colles_per_sem": colles_per_sem,
"calendar_link": calendar_link,
}
return HttpResponse(template.render(context, request))
class AmendForm(forms.Form):
colle_id = forms.IntegerField(widget=forms.HiddenInput(), required=True)
class EnrollForm(AmendForm):
pass
class WithdrawForm(AmendForm):
pass
@login_required
def marketplace(request):
try:
student = Profile.from_request(
request,
preprocess=lambda query: (query
.select_related("student__cls")
.prefetch_related("student__cls__term_set"))
)
except ValueError:
return redirect("colloscope.select_profile")
if not isinstance(student, Student):
return HttpResponse("pas encore supporté")
term = student.cls.current_term()
colles = term.query_colles_not_full_excluding_student(student)
context = {
"colles": colles,
}
return render(request, "marketplace.html", context)
@login_required
def colloscope(request):
try:
student = Profile.from_request(
request,
preprocess=lambda query: (query
.select_related("student__cls")
.prefetch_related("student__cls__term_set"))
)
except ValueError:
return redirect("colloscope.select_profile")
if not isinstance(student, Student):
return HttpResponse("pas encore supporté")
term_str = request.GET.get("term")
if term_str is None:
term = student.cls.current_term()
else:
try:
term = Term.objects.get(id=int(term_str), cls=student.cls)
except Term.DoesNotExist:
template = loader.get_template("404.html")
context = {}
response = HttpResponse(template.render(context, request))
response.status_code = 404
return response
slots = (Slot.objects
.filter(term=term, type__description="colle")
.order_by()
.prefetch_related("colle_set"))
weeks = term.range_weeks()
colles = [(c, []) for c in slots]
for c, l in colles:
for sem in weeks:
lundi = term.cls.week_beginning_date(sem)
rot = Colle.objects.filter(slot=c, datetime__gte=lundi, datetime__lt=lundi + timedelta(weeks=1))
exists = rot.exists()
if exists:
r = rot.first()
is_edited = r.is_edited()
groups = (g.description for g in r.groups.all())
else:
r = is_edited = groups = None
l.append((sem, exists, r, is_edited, groups))
template = loader.get_template("table.html")
context = {
"term": term,
"weeks": weeks,
"mondays": [term.cls.week_beginning_date(n) for n in weeks],
"days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
"colles": colles,
}
return HttpResponse(template.render(context, request))
@login_required
def export(request):
return HttpResponse(bytes(handle(request).output()), content_type="application/pdf")
def get_calendar_link(student, term):
try:
lien = CalendarLink.objects.get(student=student, term=term)
except CalendarLink.DoesNotExist:
key = uuid4().hex
lien = CalendarLink(key=key, student=student, term=term)
lien.save()
return f"export/calendar/{lien.key}/calendar.ics"
def icalendar(request, key):
try:
link = CalendarLink.objects.get(key=key)
if not request.GET.get("edt"):
return HttpResponse(to_calendar(link.student, link.term, include_EDT=True).to_ical(),
content_type="text/calendar")
return HttpResponse(to_calendar(link.student, link.term, include_EDT=True).to_ical(),
content_type="text/calendar")
except CalendarLink.DoesNotExist:
return HttpResponse("Invalid key", status=404)
def amend(request, colle_id, do_enroll):
try:
student = Profile.from_request(
request,
preprocess=lambda query: (query
.select_related("student__cls")
.prefetch_related("student__cls__term_set"))
)
except ValueError:
return redirect("colloscope.choix_profil")
if not isinstance(student, Student):
return HttpResponse("pas encore supporté")
if do_enroll:
(Colle.objects
.get(id=colle_id, slot__term__cls=student.cls)
.amend(enroll=True, student=student, notify=True))
else:
colle = Colle.objects.get(id=colle_id)
if colle.is_attendee(student):
colle.amend(enroll=False, student=student, notify=True)
else:
raise Exception("vous n'êtes pas dans la colle...")
@require_POST
@login_required
def enroll(request):
form = WithdrawForm(request.POST)
if form.is_valid():
colle_id = form.cleaned_data["colle_id"]
amend(request, colle_id, True)
else:
print("!!!! invalide")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
@require_POST
@login_required
def withdraw(request):
form = WithdrawForm(request.POST)
if form.is_valid():
colle_id = form.cleaned_data["colle_id"]
amend(request, colle_id, False)
else:
print("!!!! invalide")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))