diff --git a/.pylintrc b/.pylintrc index c04c254..cbad9a6 100644 --- a/.pylintrc +++ b/.pylintrc @@ -20,7 +20,7 @@ fail-on= fail-under=10.0 # Files or directories to be skipped. They should be base names, not paths. -ignore=CVS +ignore=CVS, tests.py, tests_tools.py, tests_models.py, tests_views.py, urls.py, migrations # Add files or directories matching the regex patterns to the ignore-list. The # regex matches against paths and can be in Posix or Windows format. @@ -80,20 +80,11 @@ confidence= # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". -disable=raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - empty-docstring, +disable= missing-class-docstring, missing-module-docstring, missing-function-docstring, - consider-using-f-string, - duplicate-code, + unsupported-binary-operation, # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option @@ -571,5 +562,5 @@ preferred-modules= # Exceptions that will emit a warning when being caught. Defaults to # "BaseException, Exception". -overgeneral-exceptions=BaseException, - Exception +overgeneral-exceptions=builtins.BaseException, + builtins.Exception diff --git a/jarvis/followup/models.py b/jarvis/followup/models.py index c1132e8..6980237 100644 --- a/jarvis/followup/models.py +++ b/jarvis/followup/models.py @@ -1,7 +1,7 @@ +from datetime import date from django.db import models from django.contrib.auth import get_user_model from django.core.validators import MaxValueValidator, MinValueValidator -from datetime import date from jarvis.tools.models import Markdownizable, Seasonisable from jarvis.people.models import Gymnast, GENDER_CHOICES @@ -175,7 +175,7 @@ class Chrono(Seasonisable): return f"{self.gymnast} - {self.score} ({self.date} - {self.chrono_type})" def timeline_representation(self): - return f"
  • {self.date:%d %b %Y} - New personel best {CHRONO_TYPE_CHOICE[self.chrono_type][1]}: {self.score}' ({self.tof}')
  • " + return f"
  • {self.date:%d %b %Y} - New personel best {CHRONO_TYPE_CHOICE[self.chrono_type][1]}: {self.score}' ({self.tof}')
  • " # pylint: disable=line-too-long @staticmethod def compute_tof(value): @@ -246,7 +246,7 @@ class Injury(Markdownizable, Seasonisable): return f"{self.gymnast} ({self.date})" def timeline_representation(self): - return f"
  • {self.date:%d %b %Y} - Accident ({self.skill}): {self.nb_week_off} (weeks off)
  • " + return f"
  • {self.date:%d %b %Y} - Accident ({self.skill}): {self.nb_week_off} (weeks off)
  • " # pylint: disable=line-too-long class LearnedSkill(Seasonisable): @@ -281,7 +281,7 @@ class LearnedSkill(Seasonisable): return f"{self.gymnast} - {self.date} - {self.learning_step} - {self.skill}" def timeline_representation(self): - return f"
  • {self.date:%d %b %Y} - learning of {self.skill.long_label} ({self.skill.short_label}): {LEARNING_STEP_CHOICES[self.learning_step][1]}
  • " + return f"
  • {self.date:%d %b %Y} - learning of {self.skill.long_label} ({self.skill.short_label}): {LEARNING_STEP_CHOICES[self.learning_step][1]}
  • " # pylint: disable=line-too-long class Plan(Seasonisable, Markdownizable): @@ -398,7 +398,7 @@ class WellBeing(Markdownizable, Seasonisable): updated_at = models.DateTimeField(auto_now=True) def __str__(self): - return f"{self.gymnast} - {self.date} : {self.mindstate} | {self.sleep} | {self.stress} | {self.fatigue} | {self.muscle_soreness}" + return f"{self.gymnast} - {self.date} : {self.mindstate} | {self.sleep} | {self.stress} | {self.fatigue} | {self.muscle_soreness}" # pylint: disable=line-too-long @property def get_inversed_stress(self): @@ -482,7 +482,7 @@ class NumberOfRoutineDone(Seasonisable): ) def __str__(self): - return f"{self.gymnast} - {self.routine_type} ({self.routine}) : {self.number_of_try} | {self.number_of_successes}" + return f"{self.gymnast} - {self.routine_type} ({self.routine}) : {self.number_of_try} | {self.number_of_successes}" # pylint: disable=line-too-long class HeightWeight(Seasonisable): @@ -573,7 +573,7 @@ class Intensity(Markdownizable, Seasonisable): number_of_passes = models.PositiveSmallIntegerField() def __str__(self): - return f"{self.gymnast} - {self.date} : {self.time} - {self.difficulty} - {self.quantity_of_skill} - {self.number_of_passes}" + return f"{self.gymnast} - {self.date} : {self.time} - {self.difficulty} - {self.quantity_of_skill} - {self.number_of_passes}" # pylint: disable=line-too-long @property def mean_time_by_passe(self): @@ -616,7 +616,7 @@ class SeasonInformation(models.Model): verbose_name_plural = "Season Informations" unique_together = ("gymnast", "season") - CATEGORY_CHOICES_ARRAY = [(key, value) for key, value in CATEGORY_CHOICES.items()] + CATEGORY_CHOICES_ARRAY = list(CATEGORY_CHOICES.items()) gymnast = models.ForeignKey( Gymnast, on_delete=models.CASCADE, related_name="season_informations" @@ -648,7 +648,7 @@ class SeasonInformation(models.Model): created_at = models.DateTimeField(auto_now_add=True) def __str__(self): - return f"{self.gymnast} - {self.season} : {self.number_of_training_sessions_per_week} - {self.number_of_hours_per_week} - {self.category} - {self.club}" + return f"{self.gymnast} - {self.season} : {self.number_of_training_sessions_per_week} - {self.number_of_hours_per_week} - {self.category} - {self.club}" # pylint: disable=line-too-long class CompetitivePointsStats(Markdownizable, Seasonisable): @@ -704,7 +704,7 @@ class CompetitivePointsStats(Markdownizable, Seasonisable): ) def __str__(self): - return f"{self.age_category} - {self.gender} - {self.routine_type} : {self.total} ({self.statistic_type})" + return f"{self.age_category} - {self.gender} - {self.routine_type} : {self.total} ({self.statistic_type})" # pylint: disable=line-too-long # class Stability(Seasonisable): diff --git a/jarvis/followup/views.py b/jarvis/followup/views.py index ce30720..1ba11f5 100644 --- a/jarvis/followup/views.py +++ b/jarvis/followup/views.py @@ -1,3 +1,4 @@ +from datetime import date, datetime from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods @@ -7,12 +8,15 @@ from django.urls import reverse from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType - from django.core.mail import send_mail +import pendulum + from jarvis.people.models import Gymnast from jarvis.planning.models import Event from jarvis.objective.models import Skill +from jarvis.tools.date_week_transition import from_date_to_week_number +from jarvis.tools.models import Season from .models import ( CHRONO_TYPE_CHOICE, @@ -52,16 +56,6 @@ from .forms import ( NumberOfRoutineDoneForm, ) -from jarvis.tools.date_week_transition import ( - from_date_to_week_number, - from_week_number_to_date, -) - -from jarvis.tools.models import Season - -from datetime import date, datetime -import pendulum - User = get_user_model() MAIL_HEADER = """ @@ -129,7 +123,8 @@ def jump_chrono_details(request, chrono_id): Args: chrono_id (int) identifiant chrono - QTF : Est-ce que je ne devrais pas faire un prefetch_related sur mon objet chrono pour optimiser mon affichage ? + QTF : Est-ce que je ne devrais pas faire un prefetch_related sur mon objet chrono pour + optimiser mon affichage ? chrono = Chrono.object.get(pk=chrono_id).prefetch_related('chrono_details') ? """ @@ -175,14 +170,8 @@ def average_jump_chrono_details_for_gymnast( season, week_number = from_date_to_week_number(today) else: season = Season(season).label - - if week_number > 52: - week_number = 52 - - if week_number < 1: - week_number = 1 - - date_begin, date_end = from_week_number_to_date(season, week_number) + week_number = min(week_number, 52) + week_number = max(week_number, 1) return average_jump_chrono_details_for_season_and_week( request, @@ -225,8 +214,8 @@ def add_jump_chrono_value(request): if created: return HttpResponse(200, (row, created)) # devrait être un 201 - else: - return HttpResponse(400, (row, created)) + + return HttpResponse(400, (row, created)) @login_required @@ -264,7 +253,8 @@ def average_jump_chrono_details_between_two_date( date_begin (date) date de début date_end (date) date de fin - QTF : le cast en date devrait être dans un try mais comment gérer correctement l'erreur - si erreur il y a ? + QTF : le cast en date devrait être dans un try mais comment gérer correctement l'erreur - si + erreur il y a ? """ if date_end: @@ -582,14 +572,14 @@ def note_create_or_update(request, note_id=None, gymnast_id=None): return HttpResponseRedirect( reverse("gymnast_details_tab", args=(new_note.gymnast.id, "event")) ) - else: - return render(request, "notes/create.html", {"form": form}) - else: - last_note = ( - Note.objects.filter(gymnast=gymnast_id, status=1).order_by("-date").first() - ) - if last_note: - data["informations"] = last_note.informations + + return render(request, "notes/create.html", {"form": form}) + + last_note = ( + Note.objects.filter(gymnast=gymnast_id, status=1).order_by("-date").first() + ) + if last_note: + data["informations"] = last_note.informations form = NoteForm(instance=note, initial=data) context = {"form": form, "note_id": note_id} @@ -658,8 +648,8 @@ def chrono_create_or_update(request, chrono_id=None, gymnast_id=None): return HttpResponseRedirect( reverse("gymnast_details_tab", args=(new_chrono.gymnast.id, "scores")) ) - else: - return render(request, "chronos/create.html", {"form": form}) + + return render(request, "chronos/create.html", {"form": form}) form = ChronoForm(instance=chrono, initial=data) context = {"form": form, "chrono_id": chrono_id} @@ -746,8 +736,8 @@ def learnedskill_create_or_update(request, gymnast_id=None): return HttpResponseRedirect( reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) ) - else: - render(request, "followup/learnedskills/create.html", {"form": form}) + + return render(request, "followup/learnedskills/create.html", {"form": form}) form = LearnedSkillForm(initial=data) context = {"form": form, "gymnast_id": gymnast_id} @@ -824,8 +814,8 @@ def score_create_or_update(request, score_id=None, gymnast_id=None): args=(form.cleaned_data["gymnast"].id, "scores"), ) ) - else: - render(request, "followup/scores/create.html", {"form": form}) + + return render(request, "followup/scores/create.html", {"form": form}) form = ScoreForm(instance=score, initial=data) context = {"form": form, "score_id": score_id} @@ -950,8 +940,8 @@ def injury_create_or_update(request, injury_id=None, gymnast_id=None): ) return HttpResponseRedirect(reverse("injury_details", args=(injury.pk,))) - else: - return render(request, "injuries/create.html", {"form": form}) + + return render(request, "injuries/create.html", {"form": form}) form = InjuryForm(instance=injury, initial=data) context = {"form": form, "injury_id": injury_id} @@ -1063,8 +1053,8 @@ def wellbeing_create_or_update( return HttpResponseRedirect( reverse("wellbeing_details", args=(wellbeing.pk,)) ) - else: - return render(request, "wellbeing/create.html", {"form": form}) + + return render(request, "wellbeing/create.html", {"form": form}) form = WellBeingForm(instance=wellbeing, initial=data) context = {"form": form, "wellbeing_id": wellbeing_id} @@ -1152,7 +1142,7 @@ def heightweight_create_or_update(request, heightweight_id=None, gymnast_id=None send_mail( f"{gymnast} : Nouveau poids/taille enregistré", - f"Un nouveau poids/taille enregistré pour {gymnast} ({date}) : {height} cm / {weight} kg (BMI: {bmi}).", + f"Un nouveau poids/taille enregistré pour {gymnast} ({date}) : {height} cm / {weight} kg (BMI: {bmi}).", # pylint: disable=line-too-long settings.EMAIL_HOST_USER, receiver, fail_silently=False, @@ -1172,9 +1162,8 @@ def heightweight_create_or_update(request, heightweight_id=None, gymnast_id=None args=(form.cleaned_data["gymnast"].id, "physiological"), ) ) - else: - print(form.errors) - return render(request, "heightweight/create.html", {"form": form}) + + return render(request, "heightweight/create.html", {"form": form}) form = HeightWeightForm(instance=heightweight, initial=data) context = { @@ -1239,8 +1228,8 @@ def increment_routinedone(request): if form.is_valid(): form.save() return HttpResponse(status=200) - else: - return HttpResponse(status=406) + + return HttpResponse(status=406) @login_required @@ -1312,8 +1301,8 @@ def routinedone_create_or_update(request, routinedone_id=None, gymnast_id=None): args=(form.cleaned_data["gymnast"].id, "routine"), ) ) - else: - return render(request, "routinedone/create.html", {"form": form}) + + return render(request, "routinedone/create.html", {"form": form}) form = NumberOfRoutineDoneForm(instance=routinedone, initial=data) context = {"form": form, "routinedone_id": routinedone_id} @@ -1385,8 +1374,8 @@ def plan_create_or_update(request, plan_id=None, gymnast_id=None, skill_id=None) return HttpResponseRedirect( reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) ) - else: - return render(request, "plan/create.html", {"form": form}) + + return render(request, "plan/create.html", {"form": form}) form = PlanForm(instance=plan, initial=data) context = {"form": form, "plan_id": plan_id} @@ -1517,8 +1506,8 @@ def intensity_create_or_update(request, intensity_id=None, gymnast_id=None): args=(form.cleaned_data["gymnast"].id, "routine"), ) ) - else: - return render(request, "intensities/create.html", {"form": form}) + + return render(request, "intensities/create.html", {"form": form}) form = IntensityForm(instance=intensity, initial=data) context = {"form": form, "intensity_id": intensity_id} @@ -1588,8 +1577,8 @@ def season_information_create_or_update( args=(form.cleaned_data["gymnast"].id,), ) ) - else: - return render(request, "seasoninformations/create.html", {"form": form}) + + return render(request, "seasoninformations/create.html", {"form": form}) form = SeasonInformationForm(instance=season_information, initial=data) context = {"form": form, "season_information_id": season_information_id} diff --git a/jarvis/location/models.py b/jarvis/location/models.py index 0ff452d..e0bb571 100644 --- a/jarvis/location/models.py +++ b/jarvis/location/models.py @@ -45,7 +45,7 @@ class Place(models.Model): is_active = models.BooleanField(default=1, verbose_name="Active") def __str__(self): - return "%s (%s)" % (self.name, self.city if self.city else "?") + return f"{self.name} ({self.city})" class Club(models.Model): @@ -70,4 +70,4 @@ class Club(models.Model): is_active = models.BooleanField(default=1, verbose_name="Active") def __str__(self): - return "%s (%s)" % (self.name, self.place.city if self.place.city else "?") + return f"{self.name} ({self.place.city})" diff --git a/jarvis/location/tests_urls.py b/jarvis/location/tests_urls.py index c7930c5..241ddc6 100644 --- a/jarvis/location/tests_urls.py +++ b/jarvis/location/tests_urls.py @@ -1,5 +1,5 @@ from django.test import TestCase -from django.urls import reverse, resolve +from django.urls import resolve class URLTestCase(TestCase): diff --git a/jarvis/location/views.py b/jarvis/location/views.py index e0e1c98..57c6c52 100644 --- a/jarvis/location/views.py +++ b/jarvis/location/views.py @@ -96,8 +96,8 @@ def place_create_or_update(request, place_id=None): if form.is_valid(): place = form.save() return HttpResponseRedirect(reverse("place_details", args=(place.pk,))) - else: - return render(request, "places/create.html", {"form": form}) + + return render(request, "places/create.html", {"form": form}) form = PlaceForm(instance=place, initial=data) context = {"form": form, "place_id": place_id} diff --git a/jarvis/objective/admin.py b/jarvis/objective/admin.py index e024220..8af2a7c 100644 --- a/jarvis/objective/admin.py +++ b/jarvis/objective/admin.py @@ -1,10 +1,8 @@ from django.contrib import admin # from django_extensions.admin import ForeignKeyAutocompleteAdmin - from django_admin_listfilter_dropdown.filters import ( DropdownFilter, - ChoiceDropdownFilter, RelatedDropdownFilter, ) diff --git a/jarvis/objective/models.py b/jarvis/objective/models.py index cf43b92..7c69452 100644 --- a/jarvis/objective/models.py +++ b/jarvis/objective/models.py @@ -104,13 +104,15 @@ class Educative(Markdownizable): def __str__(self): return f"{self.long_label} ({self.short_label} - {self.difficulty})" - def breadcrumb(self, path=[]): + def breadcrumb(self, path=None): """ Renvoie le breadcrumb pour l'édutatif courant. Exemple : >>> s = Skill.objects.get(pk=44) >>> s.breadcrumb() """ + if path is None: + path = [] path = [self] + path if self.prerequisites.all().count() == 0: @@ -145,7 +147,7 @@ class PrerequisiteClosure(models.Model): path = models.PositiveIntegerField() def __str__(self): - return f"{self.ancestor.long_label} -> {self.descendant.long_label} ({self.level}|{self.path})" + return f"""{self.ancestor.long_label} -> {self.descendant.long_label} ({self.level}|{self.path})""" # pylint: disable=line-too-long class TouchPosition(models.Model): @@ -273,8 +275,8 @@ class Routine(Educative): - la difficulté - si c'est une routine (série) - si c'est une routine (série) de compétition - A chaque fois qu'on le peut, on garde les informations entrées par les utilisateurs néanmoins on vérifie qu'il - n'a pas encodé n'importe quoi. + A chaque fois qu'on le peut, on garde les informations entrées par les utilisateurs + néanmoins on vérifie qu'il n'a pas encodé n'importe quoi. """ rank = 0 level = 0 diff --git a/jarvis/objective/tests.py b/jarvis/objective/tests.py index 1abca22..88fb536 100644 --- a/jarvis/objective/tests.py +++ b/jarvis/objective/tests.py @@ -42,7 +42,12 @@ class EducativeTestCase(TestCase): ) educ_7.prerequisites.add(educ_6) educ_7.prerequisites.add(educ_1) - # educ_8 = Educative.objects.create(long_label="3/4 Avant vrille", difficulty=0.5, level=1, rank=1) + # educ_8 = Educative.objects.create( + # long_label="3/4 Avant vrille", + # difficulty=0.5, + # level=1, + # rank=1 + # ) # educ_8.prerequisites.add(educ_6) # educ_8.prerequisites.add(educ_2) educ_9 = Educative.objects.create( diff --git a/jarvis/objective/tests_models.py b/jarvis/objective/tests_models.py index 3f4de13..e9190d1 100644 --- a/jarvis/objective/tests_models.py +++ b/jarvis/objective/tests_models.py @@ -10,19 +10,19 @@ from jarvis.objective.models import ( class ToolsModels(TestCase): def setUp(self): - """ """ + """Set up des variables pour les test.""" touch_position_1 = TouchPosition.objects.create( long_label="debout", short_label="debout", is_default=True ) - touch_position_2 = TouchPosition.objects.create( - long_label="quadrupédique", short_label="4 patte", is_default=False - ) - educ_1 = Educative.objects.create( - long_label="1/2 vrille", short_label="1/2T", difficulty=0.1, level=1, rank=1 - ) - educ_3 = Educative.objects.create( - long_label="4 pattes", short_label="4P", difficulty=0.1, level=1, rank=1 - ) + # touch_position_2 = TouchPosition.objects.create( + # long_label="quadrupédique", short_label="4 patte", is_default=False + # ) + # educ_1 = Educative.objects.create( + # long_label="1/2 vrille", short_label="1/2T", difficulty=0.1, level=1, rank=1 + # ) + # educ_3 = Educative.objects.create( + # long_label="4 pattes", short_label="4P", difficulty=0.1, level=1, rank=1 + # ) skill_1 = Skill.objects.create( long_label="Salto arrière groupé", short_label="Arrière o", @@ -34,29 +34,29 @@ class ToolsModels(TestCase): landing=touch_position_1, difficulty=0.5, ) - skill_2 = Skill.objects.create( - long_label="Barani groupé", - short_label="Barani o", - rotation_type=2, - notation=".41o", - rotation=4, - twist=1, - departure=touch_position_1, - landing=touch_position_1, - difficulty=0.5, - ) + # skill_2 = Skill.objects.create( + # long_label="Barani groupé", + # short_label="Barani o", + # rotation_type=2, + # notation=".41o", + # rotation=4, + # twist=1, + # departure=touch_position_1, + # landing=touch_position_1, + # difficulty=0.5, + # ) routine_1 = Routine.objects.create( long_label="BOT Bronze", short_label="Bronze", is_active=True, is_competitive=True, ) - routine_skill_1 = RoutineSkill.objects.create( - routine=routine_1, skill=skill_1, rank=1 - ) - routine_skill_1 = RoutineSkill.objects.create( - routine=routine_1, skill=skill_2, rank=2 - ) + # routine_skill_1 = RoutineSkill.objects.create( + # routine=routine_1, skill=skill_1, rank=1 + # ) + # routine_skill_1 = RoutineSkill.objects.create( + # routine=routine_1, skill=skill_2, rank=2 + # ) def test_touch_position_to_string(self): touch_position = TouchPosition.objects.get(long_label="debout") diff --git a/jarvis/objective/tools.py b/jarvis/objective/tools.py index cf328a7..1891ea2 100644 --- a/jarvis/objective/tools.py +++ b/jarvis/objective/tools.py @@ -17,9 +17,9 @@ def nb_skill_by_type(max_value, desired_type="level"): Example: >>> from jarvis.objective.tools import nb_skill_by_type >>> nb_skill_by_type(2) - + # pylint: disable=line-too-long """ - if desired_type != "level" and desired_type != "rank": + if desired_type not in ("level", "rank"): return None nb_skill_by_level = ( @@ -48,7 +48,7 @@ def nb_skill_lte_type(max_value, desired_type="level"): >>> nb_skill_lte_type(2) 62 """ - if desired_type != "level" and desired_type != "rank": + if desired_type not in ("level", "rank"): return None if desired_type == "level": @@ -79,7 +79,7 @@ def compute_completude(total_skill, gymnast_nb_known_skills, max_level_skill): """ if total_skill: percentage = gymnast_nb_known_skills / total_skill - completude = "%s%%" % (int(percentage * 100)) + completude = f"{int(percentage * 100)}%" evaluated_level = int(max_level_skill * percentage) else: completude = None @@ -125,7 +125,7 @@ def compute_statistics_by_type( [(1, 5, 2, 40), (2, 5, 4, 80), …] """ - if desired_type != "level" and desired_type != "rank": + if desired_type not in ("level", "rank"): return None j = 0 diff --git a/jarvis/objective/views.py b/jarvis/objective/views.py index 8019f1b..c115659 100644 --- a/jarvis/objective/views.py +++ b/jarvis/objective/views.py @@ -24,7 +24,8 @@ from .models import ( @require_http_methods(["POST"]) def skill_lookup(request): """ - Récupère la liste des skill à la volée suivant des caractères de recherche entrés. (min 3 caractères) + Récupère la liste des skill à la volée suivant des caractères de recherche entrés (min 3 + caractères). """ results = [] pattern = request.POST.get("pattern", None) @@ -77,7 +78,7 @@ def skill_listing(request, field=None, expression=None, value=None, level=None): Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern) ) elif field and expression and value: - kwargs = {"{0}__{1}".format(field, expression): value} + kwargs = {f"{field}__{expression}": value} skill_list = Skill.objects.filter(**kwargs) elif level is not None: skill_list = Skill.objects.filter(level=level) @@ -149,12 +150,12 @@ def skill_details(request, skill_id): skill.save() - # Je sépare les educatifs de type "skill" et les éducatifs de type "combination" pour mieux gérer l'affichage - # Du code bien dégueulasse ! + # Je sépare les educatifs de type "skill" et les éducatifs de type "combination" pour mieux + # gérer l'affichage. Du code bien dégueulasse ! # QTF : une idée pour faire ca de manière plus propre, plus élégante ? combination_dict = {} - educative_skill = skill.educatives.filter(id__in=(Skill.objects.all())) - for educative in skill.educatives.filter(id__in=(Routine.objects.all())): + educative_skill = skill.educatives.filter(id__in=Skill.objects.all()) + for educative in skill.educatives.filter(id__in=Routine.objects.all()): combination = Routine.objects.get(pk=educative.id) combination_dict[combination] = [] for educ_skill in combination.routine.skill_links.all(): @@ -188,8 +189,7 @@ def skill_create_or_update(request, skill_id=None): if form.is_valid(): skill = form.save() return HttpResponseRedirect(reverse("skill_details", args=(skill.pk,))) - else: - return render(request, "skill/create.html", {"form": form}) + return render(request, "skill/create.html", {"form": form}) form = SkillForm(instance=skill) context = {"form": form, "skill_id": skill_id} @@ -199,7 +199,8 @@ def skill_create_or_update(request, skill_id=None): @login_required @require_http_methods(["GET"]) def competition_routine_listing(request, gymnast_id=None): - """Récupère la liste des routines (séries) de compétition suivant un pattern si celui-ci est défini + """Récupère la liste des routines (séries) de compétition suivant un pattern si celui-ci est + défini. Args: gymnast_id (int) identifiant de la classe Gymnast @@ -379,13 +380,14 @@ def combination_create_or_update(request, combination_id=None): combination = form.save() # ici faire un FOR skill in form_skills_list: # record.save() # ca sauve le record dans la table RoutineSkill - # something like this : http://stackoverflow.com/questions/3074938/django-m2m-form-save-through-table + # something like this : + # http://stackoverflow.com/questions/3074938/django-m2m-form-save-through-table # QTF : can you help me ? return HttpResponseRedirect( reverse("combination_details", args=(combination.pk,)) ) - else: - return render(request, "combinations/create.html", {"form": form}) + + return render(request, "combinations/create.html", {"form": form}) form = CombinationForm(instance=combination) context = {"form": form, "combination_id": combination_id} @@ -436,8 +438,8 @@ def link_skill_to_combination(request): rank=form.cleaned_data["rank"], ) return HttpResponse(200, (link, created)) - else: - return HttpResponse(406) + + return HttpResponse(406) @require_http_methods(["POST"]) diff --git a/jarvis/people/models.py b/jarvis/people/models.py index 37fbb36..7a5c9dd 100644 --- a/jarvis/people/models.py +++ b/jarvis/people/models.py @@ -1,10 +1,9 @@ """ Modelisation des gymnastes """ - +from datetime import date from django.contrib.auth import get_user_model from django.db.models import Count from django.db import models -from datetime import date import pendulum from jarvis.objective.models import Skill @@ -121,7 +120,7 @@ class Gymnast(Markdownizable): >>> gymnast.skill_max_for_type("rank") 19 """ - if desired_type != "level" and desired_type != "rank": + if desired_type not in ("level", "rank"): return None tmp = ( @@ -155,7 +154,7 @@ class Gymnast(Markdownizable): >>> gymnast.nb_known_skill_by_type("rank") """ - if desired_type != "level" and desired_type != "rank": + if desired_type not in ("level", "rank"): return None nb_known_skill_by_type = ( @@ -237,7 +236,7 @@ class Gymnast(Markdownizable): on va chercher tous les Skill qui existent et on les compte. """ - if desired_type != "level" and desired_type != "rank": + if desired_type not in ("level", "rank"): return None context = {} diff --git a/jarvis/people/tests_views.py b/jarvis/people/tests_views.py index 3e10126..76fddae 100644 --- a/jarvis/people/tests_views.py +++ b/jarvis/people/tests_views.py @@ -1,4 +1,4 @@ -from django.test import TestCase +# from django.test import TestCase # from django.urls import reverse, resolve # from jarvis.profiles.views import profile_update diff --git a/jarvis/people/urls.py b/jarvis/people/urls.py index 9e45736..a938cb1 100644 --- a/jarvis/people/urls.py +++ b/jarvis/people/urls.py @@ -101,11 +101,6 @@ gymnast_urlpatterns = [ views.generate_timeline_report, name="gymnast_timeline_export_from_date", ), - path( - r"report/evaluation//", - views.gymnast_report_evaluation, - name="gymnast_report_evaluation", - ), # path( # r"resume//season//week_number//", # views.generate_week_resume, diff --git a/jarvis/people/views.py b/jarvis/people/views.py index 2198385..7d7d3f6 100644 --- a/jarvis/people/views.py +++ b/jarvis/people/views.py @@ -1,3 +1,5 @@ +from datetime import date +from statistics import mean from django.contrib.auth.decorators import login_required from django.contrib.auth.models import Group from django.contrib.auth import get_user_model @@ -24,8 +26,7 @@ from weasyprint import HTML, CSS # from weasyprint.fonts import FontConfiguration import pendulum -from datetime import date -from statistics import mean + from jarvis.followup.models import Event from jarvis.followup.forms import GymnastHasRoutineForm @@ -97,9 +98,9 @@ def gymnast_listing(request): ).select_related("gymnast") context = {"season_information_list": season_information_list} return render(request, "gymnasts/list.html", context) - else: - gymnast = Gymnast.objects.get(user=request.user) # a mettre dans un TRY - return gymnast_details(request, gymnast.id) + + gymnast = Gymnast.objects.get(user=request.user) # a mettre dans un TRY + return gymnast_details(request, gymnast.id) @login_required @@ -199,48 +200,6 @@ def gymnast_report_list(request, gymnast_id): return render(request, "gymnasts/tabs/tab_documents.html", context) -@login_required -@require_http_methods(["GET"]) -def gymnast_report_evaluation(request, gymnast_id): - """ """ - context = { - "SITE_TITLE": settings.SITE_TITLE, - "CLUB_NAME": settings.CLUB_NAME, - "ADDRESS": settings.ADDRESS, - "CITY": settings.CITY, - "ZIP": settings.ZIP, - "HEAD_COACH": settings.HEAD_COACH, - "MOBILE_PHONE": settings.MOBILE_PHONE, - "HEAD_COACH_EMAIL": settings.HEAD_COACH_EMAIL, - # "week_number": week_number, - # "gymnast": gymnast, - # "today": date_begin, - # "season": season, - # "sorted_records": sorted_records, - } - return render(request, "gymnasts/reports/report_evaluation.html", context) - # response = HttpResponse(content_type="application/pdf") - # response[ - # "Content-Disposition" - # ] = "attachment; filename={lastname}-{firstname}-report-timeline.pdf".format( - # lastname=gymnast.last_name, - # firstname=gymnast.first_name, - # ) - - # html = render_to_string("people/gymnasts/reports/report_timeline.html", context) - - # # font_config = FontConfiguration() - # HTML(string=html, base_url=request.build_absolute_uri()).write_pdf( - # response, - # stylesheets=[ - # CSS(settings.STATICFILES_DIRS[0] + "/css/gymnast_report.css"), - # CSS(settings.STATICFILES_DIRS[0] + "/css/black-dashboard_report.css"), - # CSS(settings.STATICFILES_DIRS[0] + "/css/font_awesome_all_5.15.3.css"), - # ], - # ) # , font_config=font_config) - # return response - - @login_required @require_http_methods(["GET"]) def gymnast_display_events_and_notes(request, gymnast_id): @@ -507,10 +466,8 @@ def gymnast_create_or_update(request, gymnast_id=None): # user.set_password(gymnast.last_name.lower() + _ + str(gymnast.birthdate)[-2:]) return HttpResponseRedirect(reverse("gymnast_details", args=(gymnast.pk,))) - else: - return render( - request, "people/gymnasts/create.html", {"form": gymnast_form} - ) + + return render(request, "people/gymnasts/create.html", {"form": gymnast_form}) form = GymnastForm(instance=gymnast) context = {"form": form, "gymnast_id": gymnast_id} @@ -546,7 +503,7 @@ def gymnast_display_skill(request, gymnast_id): context.update(gymnast.get_informations_from_type("rank")) planned_skill = ( - Plan.objects.filter(gymnast=gymnast.id, educative__in=(Skill.objects.all())) + Plan.objects.filter(gymnast=gymnast.id, educative__in=Skill.objects.all()) .select_related("educative", "educative__skill") .order_by("-date", "educative__long_label") ) @@ -571,11 +528,11 @@ def gymnast_display_skill(request, gymnast_id): # skill_learned_by_phase = [[]] * 5 # print(skill_learned_by_phase) - confused_skill = list() - skill_whith_help = list() - skill_without_help = list() - skill_chained = list() - skill_masterised = list() + confused_skill = [] + skill_whith_help = [] + skill_without_help = [] + skill_chained = [] + skill_masterised = [] for learned_skill in learned_skills: # print('Add skill for ' + str(learned_skill.learning_step) + ' phase') # skill_learned_by_phase[learned_skill.learning_step].append(learned_skill.skill) @@ -840,7 +797,7 @@ def report_choice(request, gymnast_id): def __mindstate_analyse(gymnast, date_begin, date_end, period, mindstate_score): - """ """ + """Analyse de l'état d'esprit entre deux dates.""" previous_period_date_end = date_begin if period == "week": period_length = 7 @@ -872,7 +829,7 @@ def __mindstate_analyse(gymnast, date_begin, date_end, period, mindstate_score): def __height_analyse(gymnast, date_begin, date_end, period, height_score): - """ """ + """Analyse de la taille du gymnaste entre deux dates.""" previous_period_date_end = date_begin if period == "week": period_length = 7 @@ -905,7 +862,7 @@ def __height_analyse(gymnast, date_begin, date_end, period, height_score): def __weight_analyse(gymnast, date_begin, date_end, period, weight_score): - """ """ + """Analyse du poids du gymnaste entre deux dates.""" previous_period_date_end = date_begin if period == "week": period_length = 7 @@ -1196,7 +1153,7 @@ def generate_report_for_period( # PLANNED SKILLS plan_list = ( - Plan.objects.filter(gymnast=gymnast, educative__in=(Skill.objects.all())) + Plan.objects.filter(gymnast=gymnast, educative__in=Skill.objects.all()) .filter(Q(is_done=False) | Q(date__gte=date.today())) .order_by("date") .distinct()[:6] @@ -1284,7 +1241,7 @@ def generate_report_for_period( response = HttpResponse(content_type="application/pdf") response[ "Content-Disposition" - ] = f"attachment; filename={gymnast.last_name}_{gymnast.first_name}_{period}-report_{date_begin}_{date_end}.pdf" + ] = f"attachment; filename={gymnast.last_name}_{gymnast.first_name}_{period}-report_{date_begin}_{date_end}.pdf" # pylint: disable=line-too-long html = render_to_string("gymnasts/reports/report_periodical.html", context) @@ -1524,5 +1481,5 @@ def generate_timeline_report( # date_begin = date_begin.date() # wellbeing_list = gymnast.wellbeing.objects.filter(season="season", week_number="week_number") -# intensity_list = gymnast.intensities.objects.filter(season="season", week_number="week_number") +# intensity_list = gymnast.intensities.objects.filter(season="season", week_number="week_number") # pylint: disable=line-too-long # injury_list = gymnast.injuries.filter(season="season", week_number="week_number") diff --git a/jarvis/planning/models.py b/jarvis/planning/models.py index 057f379..5f9a370 100644 --- a/jarvis/planning/models.py +++ b/jarvis/planning/models.py @@ -90,7 +90,7 @@ class Event(Markdownizable, Temporizable): class EventParticipation(models.Model): - """ """ + """Classe représentant la participation à un évènement.""" class Meta: verbose_name = "Event Participation" diff --git a/jarvis/planning/views.py b/jarvis/planning/views.py index 72ea185..ca21d20 100644 --- a/jarvis/planning/views.py +++ b/jarvis/planning/views.py @@ -56,8 +56,8 @@ def event_create_or_update(request, event_id=None): if form.is_valid(): event = form.save() return HttpResponseRedirect(reverse("event_details", args=(event.pk,))) - else: - return render(request, "objectives/routines/create.html", {"form": form}) + + return render(request, "objectives/routines/create.html", {"form": form}) form = EventForm(instance=event, initial=data) context = {"form": form, "event_id": event_id} diff --git a/jarvis/profiles/admin.py b/jarvis/profiles/admin.py index 1859ed0..5e0316c 100644 --- a/jarvis/profiles/admin.py +++ b/jarvis/profiles/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import Profile, Notification from django_admin_listfilter_dropdown.filters import RelatedDropdownFilter +from .models import Profile, Notification class ProfileAdmin(admin.ModelAdmin): diff --git a/jarvis/profiles/tests_urls.py b/jarvis/profiles/tests_urls.py index 5c68bde..f2a3b44 100644 --- a/jarvis/profiles/tests_urls.py +++ b/jarvis/profiles/tests_urls.py @@ -1,5 +1,5 @@ from django.test import TestCase -from django.urls import reverse, resolve +from django.urls import resolve # from jarvis.profiles.views import profile_update diff --git a/jarvis/profiles/tests_views.py b/jarvis/profiles/tests_views.py index 8bec857..5b75039 100644 --- a/jarvis/profiles/tests_views.py +++ b/jarvis/profiles/tests_views.py @@ -1,7 +1,8 @@ from django.test import RequestFactory, TestCase, Client -from django.urls import reverse, resolve +from django.contrib.auth.models import User, AnonymousUser + +# from django.urls import reverse, resolve from jarvis.profiles.views import profile_update -from django.contrib.auth.models import AnonymousUser, User class ViewsTestCase(TestCase): diff --git a/jarvis/profiles/views.py b/jarvis/profiles/views.py index 279ed2c..c5dc1f7 100644 --- a/jarvis/profiles/views.py +++ b/jarvis/profiles/views.py @@ -8,9 +8,9 @@ from django.shortcuts import render, get_object_or_404 from django.views.decorators.http import require_http_methods from django.urls import reverse +from jarvis.people.models import Gymnast from .forms import ProfileForm from .models import Profile, Notification -from jarvis.people.models import Gymnast User = get_user_model() @@ -85,8 +85,8 @@ def notification_add(request): if created: return HttpResponse(200, (row, created)) # devrait être un 201 - else: - return HttpResponse(400, (row, created)) + + return HttpResponse(400, (row, created)) @require_http_methods(["POST"]) diff --git a/jarvis/tools/date_week_transition.py b/jarvis/tools/date_week_transition.py index 47de4dc..7449d6f 100644 --- a/jarvis/tools/date_week_transition.py +++ b/jarvis/tools/date_week_transition.py @@ -82,7 +82,7 @@ def from_month_number_to_date(season, month_number): dash = season.find("-") - if month_number >= 1 and month_number <= 8: + if 8 >= month_number >= 1: # and month_number <= 8: year = int(season[dash + 1 :]) else: year = int(season[:dash]) @@ -208,7 +208,8 @@ def get_number_of_weeks_between(first_date, second_date): if first_date.year == second.year: return second.week_of_year - first.week_of_year - elif second_date.year > first_date.year: + + if second_date.year > first_date.year: return (52 - first.week_of_year) + second.week_of_year - else: - return (52 - second.week_of_year) + first.week_of_year + + return (52 - second.week_of_year) + first.week_of_year diff --git a/jarvis/tools/models.py b/jarvis/tools/models.py index 3b12701..11e2c9e 100644 --- a/jarvis/tools/models.py +++ b/jarvis/tools/models.py @@ -1,4 +1,7 @@ """Ensemble des classes d'utilité publique :-)""" +import re +import markdown +import pendulum from django.db import models from django.utils import timezone @@ -7,9 +10,6 @@ from .date_week_transition import ( get_number_of_weeks_between, from_date_to_week_number, ) -import markdown -import pendulum -import re class Season: @@ -78,7 +78,7 @@ def get_default_date(): class Seasonisable(models.Model): - """ """ + """Classe abstraite définissant des champs commun à tout ce qui est relatif à une saison.""" class Meta: abstract = True @@ -224,11 +224,11 @@ def max_even_if_none(value_1, value_2): if value_1 is not None and value_2 is not None: if value_1 > value_2: return value_1 - else: - return value_2 - elif value_1 is not None: - return value_1 - elif value_2 is not None: return value_2 - else: - return 0 + + if value_1 is not None: + return value_1 + + if value_2 is not None: + return value_2 + return 0 diff --git a/jarvis/tools/templatetags/submenuitems.py b/jarvis/tools/templatetags/submenuitems.py index 2a63062..ec7d5b3 100644 --- a/jarvis/tools/templatetags/submenuitems.py +++ b/jarvis/tools/templatetags/submenuitems.py @@ -12,8 +12,10 @@ def submenuitem(context, url, minititle, title): # css_class = "" + css_class return format_html( - '
  • {}{}
  • ', - url, - minititle, - title, + f"""
  • + + {minititle} + {title} + +
  • """ ) diff --git a/jarvis/tools/tests_date_week_transition.py b/jarvis/tools/tests_date_week_transition.py index 8a2a4b8..a711aa3 100644 --- a/jarvis/tools/tests_date_week_transition.py +++ b/jarvis/tools/tests_date_week_transition.py @@ -1,7 +1,7 @@ """ Test du module date_week_transition """ - -from django.test import TestCase from datetime import datetime +import pendulum +from django.test import TestCase import pytz from jarvis.tools.date_week_transition import ( @@ -10,12 +10,10 @@ from jarvis.tools.date_week_transition import ( get_number_of_weeks_between, ) -import pendulum - class FunctionTestCase(TestCase): def test_from_week_number_to_date(self): - timezone = pytz.timezone("UTC") + # timezone = pytz.timezone("UTC") start_date = datetime(2022, 10, 3, 0, 0, 0, tzinfo=pytz.UTC) end_date = datetime(2022, 10, 9, 0, 0, 0, tzinfo=pytz.UTC)