Ultron/people/views.py

438 lines
15 KiB
Python

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from django.http import HttpResponse, HttpResponseRedirect
from django.db.models import Q, Count, Min
from django.contrib import messages
from .models import Gymnast
from followup.models import Chrono, LearnedSkill, MindState, Skill, Point, Accident
from .forms import GymnastForm
from followup.forms import GymnastHasRoutineForm
from followup.models import Event
from objective.models import Educative
import simplejson
import pendulum
@login_required
@require_http_methods(["GET"])
def gymnast_lookup(request):
"""
Récupère la liste des gymnastes à la volée suivant des caractères de
recherche entrés. (min 3 caractères)
"""
results = []
pattern = request.GET.get("pattern", None)
# Ignore queries shorter than length 3
if pattern is not None and len(pattern) > 3:
model_results = Gymnast.objects.filter(
Q(last_name__icontains=pattern) | Q(first_name__icontains=pattern)
)
results = [{"ID": x.id, "Name": str(x)} for x in model_results]
json = simplejson.dumps(results)
return HttpResponse(json, content_type="application/json")
@login_required
@require_http_methods(["GET"])
def gymnast_listing(request):
"""
Liste tous les gymnasts connus
"""
gymnast_list = Gymnast.objects.all()
context = {'gymnast_list': gymnast_list}
return render(request, "peoples/gymnasts/list.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_details(request, gymnastid):
"""
Récupère toutes les informations d'un gymnaste.
"""
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
learnedskills_list = LearnedSkill.objects.filter(gymnast=gymnastid).order_by('-date')[:10]
nb_skill = Skill.objects.all().count()
nb_known_skill = LearnedSkill.objects.filter(gymnast=gymnastid).distinct('skill').count()
percentage_known_skill = ( nb_known_skill / nb_skill ) * 100
chronos_list = Chrono.objects.filter(gymnast=gymnastid).order_by('-date')[:10]
straightjump_score = Chrono.objects.filter(gymnast=gymnastid).filter(type=0).order_by('-date')
best_straightjump = Chrono.objects.filter(gymnast=gymnastid).filter(type=0).order_by('-score')[:1]
best_routine = Chrono.objects.filter(gymnast=gymnastid).filter(type=1).order_by('-score')[:1]
routine_score = Chrono.objects.filter(gymnast=gymnastid).filter(type=1).order_by('-date')
points_routine_1_list = Point.objects.filter(gymnast=gymnastid).filter(routine_type=0).order_by('-event__datebegin')
points_routine_2_list = Point.objects.filter(gymnast=gymnastid).filter(routine_type=1).order_by('-event__datebegin')
points_routine_final_list = Point.objects.filter(gymnast=gymnastid).filter(routine_type=2).order_by('-event__datebegin')
context = {
'gymnast': gymnast,
'learnedskills_list': learnedskills_list,
'chronos_list': chronos_list,
'straightjump_score': straightjump_score,
'routine_score': routine_score,
'best_routine': best_routine,
'best_straightjump': best_straightjump,
'nb_skill': nb_skill,
'nb_known_skill': nb_known_skill,
'points_routine_1_list': points_routine_1_list,
'points_routine_2_list': points_routine_2_list,
'points_routine_final_list': points_routine_final_list,
'percentage_known_skill': percentage_known_skill,
}
return render(request, "peoples/gymnasts/details.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_display_event(request, gymnastid):
"""
Renvoie deux listes d'évènements : ceux à venir et ceux passés.
"""
today = pendulum.now().date()
next_event_list = Event.objects.filter(gymnasts=gymnastid, datebegin__gte=today)
previous_event_list = Event.objects.filter(gymnasts=gymnastid, datebegin__lte=today)
context = {
"next_event_list": next_event_list,
"previous_event_list": previous_event_list,
}
return render(request, "peoples/gymnasts/list_event.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_display_accident(request, gymnastid):
"""
Renvoie deux listes d'évènements : ceux à venir et ceux passés.
"""
accident_list = Accident.objects.filter(gymnast=gymnastid)
context = {
"accident_list": accident_list,
"gymnastid": gymnastid
}
return render(request, "peoples/gymnasts/list_accident.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_display_scores_chrono(request, gymnastid):
"""
Selectionne tous les scores réalisés par le gymnaste
"""
score_list = Point.objects.filter(gymnast=gymnastid).order_by("-event__datebegin")
score_routine1_list = score_list.filter(routine_type=0)
score_routine2_list = score_list.filter(routine_type=1)
score_routine3_list = score_list.filter(routine_type=2)
chrono_list = Chrono.objects.filter(gymnast=gymnastid).order_by("date")
chrono_10c = chrono_list.filter(type=0)
chrono_r1 = chrono_list.filter(type=1)
chrono_r2 = chrono_list.filter(type=2)
chrono_rf = chrono_list.filter(type=3)
context = {
"score_list": score_list,
"score_routine1_list": score_routine1_list,
"score_routine2_list": score_routine2_list,
"score_routine3_list": score_routine3_list,
"chrono_list": chrono_list,
"chrono_10c": chrono_10c,
"chrono_r1": chrono_r1,
"chrono_r2": chrono_r2,
"chrono_rf": chrono_rf,
"gymnastid": gymnastid,
}
return render(request, "peoples/gymnasts/list_scores_chronos.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_display_mindstate(request, gymnastid):
"""
Selectionne tous les scores réalisés par le gymnaste
"""
mindstate_list = MindState.objects.filter(gymnast=gymnastid).order_by("-date")
context = {
"mindstate_list": mindstate_list,
"gymnastid": gymnastid,
}
return render(request, "peoples/gymnasts/list_mindstate.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_display_routines(request, gymnastid):
"""
Tag affichant les séries d'un gymnaste.
"""
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
ghr_list = gymnast.has_routine.prefetch_related("routine")
context = {"ghr_list": ghr_list, "gymnastid": gymnastid}
return render(request, "peoples/gymnasts/list_routine.html", context)
@login_required
@require_http_methods(["GET", "POST"])
def link_routine_to_gymnast(request, gymnastid=None):
"""
"""
if gymnastid:
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
data = {"gymnast": gymnast.id, "gymnast_related": str(gymnast), "dateend": None}
else:
gymnast = None
data = {"dateend": None}
if request.method == "POST":
form = GymnastHasRoutineForm(request.POST)
if form.is_valid():
form.save()
if gymnastid is not None:
return HttpResponseRedirect("/gymnast/details/" + str(gymnastid) + "/")
else:
return HttpResponseRedirect("/gymnast/")
else:
form = GymnastHasRoutineForm(instance=gymnast, initial=data)
context = {"form": form, "gymnastid": gymnastid}
return render(request, "peoples/gymnasts/link_to_routine.html", context)
@login_required
@require_http_methods(["GET", "POST"])
def gymnast_create_or_update(request, gymnastid=None):
"""
Formulaire de creation et modification d'un gymnaste.
"""
if gymnastid:
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
data = {'club_related': gymnast.club}
else:
gymnast = None
data = {}
if request.method == "POST":
gymnast_form = GymnastForm(request.POST, instance=gymnast)
if gymnast_form.is_valid():
gymnast = gymnast_form.save()
return HttpResponseRedirect("/gymnast/details/" + str(gymnast.id))
else:
print(gymnast_form.errors)
form = GymnastForm(instance=gymnast, initial=data)
context = {"form": form, "gymnastid": gymnastid}
return render(request, "peoples/gymnasts/create.html", context)
def __get_informations_from_level(gymnast, gymnast_nb_known_skills):
"""
Calcule toutes les statistiques par rapport au niveau.
1. on va chercher le niveau maximum de skill que le gymnast sait faire
2. on va chercher le nombre de skill par niveau que le gymnast sait faire
3. si le niveau max est supérieur à 0
OUI:
NON:
"""
context = {}
max_level_skill = gymnast.max_level_skill()
context["max_level_skill"] = max_level_skill
nb_known_skill_by_level = gymnast.nb_known_skill_by_level()
if max_level_skill > 0:
context["total_skill"] = Skill.nb_skill_lte_level(max_level_skill)
nb_skill_by_level = Skill.nb_skill_by_level(max_level_skill)
j = 0
percentages = []
for skill in nb_skill_by_level:
tmp = None
if skill["level"] == nb_known_skill_by_level[j]["level"]:
if skill["nb_skill"] != nb_known_skill_by_level[j]["nb_known_skill"]:
tmp = (
skill["level"],
skill["nb_skill"],
nb_known_skill_by_level[j]["nb_known_skill"],
int(
(nb_known_skill_by_level[j]["nb_known_skill"] / skill["nb_skill"])
* 100
),
)
j += 1
else:
tmp = (skill["level"], skill["nb_skill"], 0, 0)
if tmp:
percentages.append(tmp)
context["percentages"] = percentages
# Liste des Skill que le gymnaste ne sait PAS faire, classé par niveau (ayant un niveau inférieur ou égal au niveau max du gym)
context["skillByLevel"] = Skill.objects.filter(
level__lte=context["max_level_skill"]
).exclude(known_by__gymnast=gymnast.id)
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau plus grand que le niveau max du gym)
context["unknown_skill"] = Skill.objects.filter(
level__gt=context["max_level_skill"]
).exclude(known_by__gymnast=gymnast.id)
else:
tmp = Skill.objects.all()
context["total_skill"] = tmp.count()
context["unknown_skill"] = tmp
# Calcul des statistiques
if context["total_skill"] != 0:
context["completude"] = "%s%%" % (
int((gymnast_nb_known_skills / context["total_skill"]) * 100)
)
context["evaluated_level"] = int(
context["max_level_skill"] * (gymnast_nb_known_skills / context["total_skill"])
)
else:
context["completude"] = 0
context["evaluated_level"] = 0
return context
def __get_informations_from_rank(gymnast, gymnast_nb_known_skills):
"""
Calcule toutes les statistiques des skills par rapport au rang du gymnaste.
"""
context = {}
min_rank_skill = gymnast.min_rank_skill()
max_rank_skill = gymnast.max_rank_skill()
context["max_rank_skill"] = max_rank_skill
nb_known_skill_by_rank = gymnast.known_skill_by_rank()
if max_rank_skill > 0:
context["total_skill"] = Skill.nb_skill_lte_rank(max_rank_skill)
nb_skill_by_rank = Skill.nb_skill_by_rank(max_rank_skill)
j = 0
percentages = []
for skill in nb_skill_by_rank:
# les deux lignes ci-dessous doivent partir
if j >= nb_known_skill_by_rank.count():
break
tmp = None
if skill["rank"] == nb_known_skill_by_rank[j]["rank"]:
if skill["nb_skill"] != nb_known_skill_by_rank[j]["nb_known_skill"]:
tmp = (
skill["rank"],
skill["nb_skill"],
nb_known_skill_by_rank[j]["nb_known_skill"],
int(
(nb_known_skill_by_rank[j]["nb_known_skill"] / skill["nb_skill"])
* 100
),
)
j += 1
else:
tmp = (skill["rank"], skill["nb_skill"], 0, 0)
if tmp:
percentages.append(tmp)
context["percentages"] = percentages
# Liste des Skill que le gymnaste ne sait PAS faire, classé par niveau
# (ayant un niveau inférieur ou égal au niveau max du gym)
context["skill_by_rank"] = Skill.objects.filter(
level__lte=context["max_rank_skill"]
).exclude(known_by__gymnast=gymnast.id)
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau
# plus grand que le niveau max du gym)
context["unknown_skill"] = Skill.objects.filter(
level__gt=context["max_rank_skill"]
).exclude(known_by__gymnast=gymnast.id)
else:
tmp = Skill.objects.all()
context["unknown_skill"] = tmp
context["total_skill"] = tmp.count()
# Calcul des statistiques
if context["total_skill"] != 0:
context["completude"] = "%s%%" % (
int((gymnast_nb_known_skills / context["total_skill"]) * 100)
)
context["evaluated_level"] = (min_rank_skill - 1) + (
int(context["max_rank_skill"] * (gymnast_nb_known_skills / context["total_skill"]))
)
else:
context["completude"] = 0
context["evaluated_level"] = 0
return context
@login_required
@require_http_methods(["GET"])
def gymnast_display_skill(request, gymnastid):
"""
Tag affichant les statistiques de skill d'un gymnaste : le nombre de saut qu'il sait faire (total,
par niveau, par rank, …), calcule la complétude, …
.. todo:: Générer UNE fois la liste de skill que le gymnaste ne sait pas faire (1 query)
et les counts puis, dans le template on parcourt plusieurs fois cette même liste mais on
affiche conditionnellement (par age, par rank, ...)
"""
context = {}
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
gymnast_nb_known_skills = gymnast.known_skills.distinct('skill').count()
context = __get_informations_from_level(gymnast, gymnast_nb_known_skills)
context.update(__get_informations_from_rank(gymnast, gymnast_nb_known_skills))
if gymnast.gender:
context["skill_by_age"] = Skill.objects.filter(age_girl__lte=gymnast.age).exclude(
known_by__gymnast=gymnast.id
)
else:
context["skill_by_age"] = Skill.objects.filter(age_boy__lte=gymnast.age).exclude(
known_by__gymnast=gymnast.id
)
skill_whith_help = Skill.objects.filter(known_by__gymnast=gymnastid, known_by__cando=1).exclude(
known_by__gymnast=gymnast.id, known_by__cando__gte=2
).distinct()
skill_not_chained = Skill.objects.filter(known_by__gymnast=gymnastid, known_by__cando=2).exclude(
known_by__gymnast=gymnast.id, known_by__cando=3
).distinct()
context["gymnast"] = gymnast
context["skill_whith_help"] = skill_whith_help
context["skill_not_chained"] = skill_not_chained
context["gymnast_nb_known_skills "] = gymnast_nb_known_skills
return render(request, "peoples/gymnasts/list_skill.html", context)