khana/config/views.py

274 lines
9.1 KiB
Python

# coding=UTF-8
from django.db.models import Q
from django.shortcuts import render
from django.template import RequestContext
from django.utils import timezone
from django.utils.html import format_html
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from datetime import datetime, timedelta, date
from functools import reduce
import operator
from planning.models import (
Season,
Event,
Unavailability,
Course,
get_number_of_weeks_between,
)
from people.models import Gymnast, Accident # people model
from location.models import Club # location model
from objective.models import Skill, Routine # objective model
from profile.models import Profile
from communication.views import get_number_of_unread_message
import pendulum
def login(request):
"""
Formulaire d'authentifictation.
"""
club_list = Club.objects.all()
if request.method == "POST":
username = request.POST["login"]
password = request.POST["password"]
user = authenticate(username=username, password=password)
if user is not None: # Pq pas "if user:" ??
if user.is_active:
auth_login(request, user)
try:
profile = Profile.objects.get(user=user)
request.session["profileid"] = profile.id
request.session["template"] = profile.template_color
request.session["sidebar"] = profile.sidebar_color
request.session["is_sidebar_minified"] = profile.is_sidebar_minified
except expression as identifier:
pass
request.session["clubid"] = request.POST.get("clubid", None)
return HttpResponseRedirect("/")
else:
context = {"message": "Account disabled.", "clubs": club_list}
else:
context = {"message": "Wrong login/password.", "clubs": club_list}
else:
context = {"clubs": club_list}
return render(request, "login.html", context)
@login_required
@require_http_methods(["GET"])
def logout(request):
"""
Fonction de déconnexion
"""
auth_logout(request)
return HttpResponseRedirect("/login/")
@login_required
def __getEventInfo(request):
"""
Fonction 'private' qui renvoie les informations relatives à une liste d'évenements.
.. todo:: il refuse mon 'filter' que ce soit avant ou après le 'next(5)'. Une idée ?
next_event = Event.objects.filter(club__in=(request.session["clubid"], )).next(5)
"""
# rest = 0
# counted = 0
# event_list = []
# today = pendulum.now().date()
next_event_list = Event.objects.next(5)
# for event in next_event:
# counted = event.get_number_of_occurence_to_event(today)
# # print('pouf !')
# unavailabilities = Unavailability.objects.filter(datebegin__lte=event.datebegin.date(), dateend__gte=today)
# for unavailable in unavailabilities:
# counted -= unavailable.get_total_occurence()
# event_list.append((event, counted, int((counted/16)*100)))
return next_event_list
@login_required
def __getCourseInfo(request):
"""
Fonction `private` qui renvoie les informations relatives à une liste de cours :
cours, nombre de cours donnés, nombre de cours restant.
"""
rest = 0
counted = 0
courses = []
courses_done = 0
courses_left = 0
today = timezone.now().date()
# CourseList = Course.objects.filter(trainers__in=(request.user, ), club__in=(request.session["clubid"], )).order_by('iso_day_number', 'hour_begin')
CourseList = Course.objects.filter(trainers__in=(request.user,)).order_by(
"iso_day_number", "hour_begin"
)
for course in CourseList:
# Nombre de cours total sur la saison.
counted = course.get_total_occurence()
# Nombre de cours restant (à partir d'aujourd'hui)
rest = course.get_number_of_occurence_inbetween(today, True)
tmp = course.dateend.date() - today
if course.dateend.weekday() <= (today.weekday() + ((tmp.days + 1) % 7) % 7):
rest = int((tmp.days + 1) / 7) + 1
else:
rest = int((tmp.days + 1) / 7)
# # select tous les unavailables liés au cours
# unavailabilities = Unavailability.objects.filter(course=course)
# for unavailable in unavailabilities:
# tmp = unavailable.get_total_occurence()
# counted -= tmp
# rest -= tmp # si un unavailability.date < today, on soustrait quand même de rest ??? Si oui => BUG !!!!
courses_left += rest
courses_done += counted - rest
# courses.append((course, counted, (counted - rest)))
return courses, courses_done, courses_left
@login_required
@require_http_methods(["GET"])
def home(request):
"""Génère la page d'accueil du site basée sur la saison (si celle-ci est
connue)
.. todo:: vérifier s'il y a des élèves qui devait participer à une compé-
tition (passée) pour laquelle il n'y a pas de points encodés. Si c'est le
cas, générer un popup. (le coach doit soit encoder les points soit suppri-
mer la participation de l'élève à l'event)
"""
today = pendulum.today().date()
try:
season = Season.objects.get(datebegin__lte=today, dateend__gte=today)
except Season.DoesNotExist:
context = {"error": "No season founded."}
return render(request, "index.html", context)
except Season.MultipleObjectsReturned:
context = {"error": "Multiple season founded."}
return render(request, "index.html", context)
week_number = season.week_number_from_begin(today)
# Afficher les 3 prochains cours.
weekdays_included = (today.weekday(), today.weekday() + 1, today.weekday() + 2)
courses_list = Course.objects.filter(trainers__in=(request.user,)).order_by(
"iso_day_number", "hour_begin"
)
# enlever les cours s'il sont repris dans des unavalability
event_list = __getEventInfo(request)
unavailable_list = Unavailability.objects.next(5)
birthday_list = next_birthdays(request, 5)
number_unreaded_message = get_number_of_unread_message(request)
courses, courses_done, courses_left = __getCourseInfo(request)
context = {
"week_number": week_number,
"number_of_courses": len(courses_list),
"courses_list": courses_list,
"event_list": event_list,
"birthday_list": birthday_list,
"unavailable_list": unavailable_list,
"courses_left": courses_left,
"donecourses": courses_done,
"today": today,
"number_unreaded_message": number_unreaded_message,
}
return render(request, "index.html", context)
@login_required
def birthdays_within(request, days):
"""
Renvoie la liste des gymnastes ayant leur anniversaires dans les `days` prochains jours.
"""
now = datetime.now()
then = now + timedelta(days)
# Build the list of month/day tuples.
monthdays = [(now.month, now.day)]
while now <= then:
monthdays.append((now.month, now.day))
now += timedelta(days=1)
# Tranform each into queryset keyword args.
monthdays = (
dict(zip(("birthdate__month", "birthdate__day"), t)) for t in monthdays
)
# Compose the djano.db.models.Q objects together for a single query.
query = reduce(operator.or_, (Q(**d) for d in monthdays))
# Run the query.
return Gymnast.objects.filter(query).order_by("birthdate")
@login_required
def next_birthdays(request, number_of_birthday):
"""
Renvoie la liste des `number_of_birthday` prochains anniversaires.
"""
birthday_list = sorted(
Gymnast.objects.all(), key=lambda t: t.next_birthday_in_days
)[:5]
return birthday_list
@login_required
@require_http_methods(["GET"])
def search(request):
"""
Recherche globale au travers de toutes les applications.
"""
pattern = request.GET.get("pattern", None)
if pattern:
event_list = Event.objects.filter(
name__icontains=pattern
) # ou gymnaste qui y participe !
gymnast_list = Gymnast.objects.filter(
Q(user__last_name__icontains=pattern)
| Q(user__first_name__icontains=pattern)
)
accident_list = Accident.objects.filter(
Q(gymnast__user__last_name__icontains=pattern)
| Q(gymnast__user__first_name__icontains=pattern)
)
skill_list = Skill.objects.filter(
Q(longLabel__icontains=pattern) | Q(shortLabel__icontains=pattern)
)
routine_list = Routine.objects.filter(
Q(longLabel__icontains=pattern) | Q(shortLabel__icontains=pattern)
)
context = {
"event_list": event_list,
"gymnast_list": gymnast_list,
"accident_list": accident_list,
"skill_list": skill_list,
"routine_list": routine_list,
}
else:
context = {}
return render(request, "results.html", context)