291 lines
8.4 KiB
Python
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'))
|