from uuid import uuid4 from django import forms from django.contrib.auth.mixins import LoginRequiredMixin 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 django.views.generic import ListView from django.utils.translation import gettext_lazy as _ from colloscope.models import * from colloscope.pdfexport import handle from colloscope.icalexport import to_calendar def handler404(request): context = {} return render(request, '404.html', context, status=404) class ColleListView(ListView): model = Colle context_object_name = "colles" def get_queryset(self): term = Term.objects.get(pk=self.kwargs.get("term")) base_query = (term.cls .current_term() .query_colles() .filter(datetime__gte=date.today())) if self.kwargs.get("subject") is not None: print(base_query) print(self.kwargs.get("subject")) base_query = base_query.filter(slot__subject__id=self.kwargs.get("subject")) if self.kwargs.get("colleur") is not None: base_query = base_query.filter(slot__colleur__id=self.kwargs.get("colleur")) return base_query @login_required def dashboard(request): try: student = (Student.objects .select_related("cls") .prefetch_related("cls__term_set") .get(profile__user=request.user)) 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 = (Student.objects .select_related("cls") .prefetch_related("cls__term_set") .get(profile__user=request.user)) except ValueError: return redirect("colloscope:select_profile") if not isinstance(student, Student): return HttpResponse(_("Not supported yet.")) 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 = (Student.objects .select_related("cls") .prefetch_related("cls__term_set") .get(profile__user=request.user)) 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"/colloscope/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 = (Student.objects .select_related("cls") .prefetch_related("cls__term_set") .get(profile__user=request.user)) 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'))