Multiple updates

This commit is contained in:
Gregory Trullemans 2024-03-06 15:13:09 +01:00
parent b9a9bd2c9a
commit c302214924
9 changed files with 307 additions and 140 deletions

View File

@ -59,7 +59,22 @@ Dans le répertoire racine, tapez la commande suivante :
(à venir)
### Coverage
(à venir)
```bash
pip install coverage
```
#### Configuration
```bash
touch .coveragerc
vim .coveragerc
```
Ajoutez les lignes suivantes :
```bash
omit = *__init__.py,*/migrations/*,*test*,*settings*,*urls*,*wsgi*,manage.py,*apps*
```
## Déploiement sur Heroku

144
jarvis/core/global_vars.py Normal file
View File

@ -0,0 +1,144 @@
"""All global variables to avoid circular import."""
INJURY_MECHANISM_CHOICE = (
(0, "Overuse"),
(1, "Trauma"),
)
INJURY_BODY_SIDE_CHOICE = (
(0, "Not Applicable"),
(1, "Left"),
(2, "Right"),
(3, "Both"),
)
INJURY_TYPE_CHOICE = (
(0, "Abrasion"),
(1, "Dental Injury"),
(2, "Dislocation / Subluxation"),
(3, "Fracture"),
(4, "Haematoma / Contusion / Bruise"),
(5, "Head Concussion"),
(6, "Laceration"),
(7, "Lesion of Meniscus or Cartilage"),
(8, "Muscle Rupture / Strain / Tear / Cramps"),
(9, "Nerve Injury"),
(10, "Other Bone Injury"),
(11, "Sprain / Ligament Injury"),
(12, "Tendon Injury / Rupture / Tendinosis / Bursitis"),
)
INJURY_LOCATION_CHOICE = (
(0, "Abdomen"),
(1, "Ankle"),
(2, "Elbow"),
(3, "Foot / Toe"),
(4, "Hand / Finger / Thumb"),
(5, "Head / Face"),
(6, "Hip / Groin"),
(7, "Knee"),
(8, "Low back / Sacrum / Pelvis"),
(9, "Lower Leg / Achilles Tendon"),
(10, "Neck / Cervical Spine"),
(11, "Shoulder / Clavicula"),
(12, "Sternum / Ribs / Upper back"),
(13, "Thigh"),
(14, "Upper arm"),
(15, "Wrist"),
)
ROUTINE_TYPE_CHOICE = (
(0, "Other"),
(1, "Q1R1"),
(2, "Q1R2"),
(3, "Q2R1"),
(4, "SF"),
(5, "F"),
(6, "Q1R1S"),
(7, "Q1R2S"),
(8, "Q2R1S"),
(9, "SFS"),
(9, "FS"),
(99, "Other"),
)
LEARNING_STEP_CHOICES = (
(0, "No"),
(1, "With help"),
(2, "Without help"),
(3, "Chained"),
(4, "Masterised"),
)
CHRONO_TYPE_CHOICE = (
(0, "10 |"),
(1, "Q1R1"),
(2, "Q1R2"),
(3, "Q2R1"),
(4, "SF"),
(5, "F"),
(99, "Other"),
)
SCORE_TYPE_CHOICE = (
(0, "Chrono"),
(1, "ToF"),
)
CATEGORY_CHOICES = {
9: "I9",
10: "I10",
11: "A11",
12: "A12",
13: "A13-14",
15: "A Junior",
18: "A Senior",
21: "B11",
22: "B12",
23: "B13-14",
24: "B Junior",
25: "B Senior",
}
AGE_CATOGORY_CHOICES = (
(11, "11-12"),
(13, "13-14"),
(15, "15-16"),
(17, "17-21"),
(22, "Senior"),
)
NOTE_STATUS_CHOICES = (
(0, "Draft"),
(1, "Published"),
)
GENDER_CHOICES = (
(0, "Female"),
(1, "Male"),
)
ORIENTATION_CHOICES = (
(None, "Unknown"),
(1, "Left"),
(2, "Right"),
)
# MOD_THOMAS_TEST_CHOICES = (
# (0, "not evaluated"),
# (1, "tight psoas"),
# (2, "tight quadriceps"),
# (3, "tight TFL"),
# (4, "tight psoas en quadriceps"),
# (5, "tight quadriceps en TFL"),
# (6, "tight psoas en TFL"),
# (7, "tight psoas en quadriceps en TFL"),
# )
# LOMBO_PELVIC_AND_CERVICAL_CONTROL_CHOICES = (
# (0, "not evaluated"),
# (1, "good control, good mobility"),
# (2, "good control, bad mobility"),
# (3, "bad control, good mobility"),
# (4, "bad control, bad mobility"),
# )

View File

@ -3,6 +3,20 @@ from django.db import models
from django.contrib.auth import get_user_model
from django.core.validators import MaxValueValidator, MinValueValidator
from jarvis.core.global_vars import (
INJURY_MECHANISM_CHOICE,
INJURY_BODY_SIDE_CHOICE,
INJURY_TYPE_CHOICE,
INJURY_LOCATION_CHOICE,
ROUTINE_TYPE_CHOICE,
LEARNING_STEP_CHOICES,
CHRONO_TYPE_CHOICE,
SCORE_TYPE_CHOICE,
CATEGORY_CHOICES,
AGE_CATOGORY_CHOICES,
NOTE_STATUS_CHOICES,
)
from jarvis.tools.models import Markdownizable, Seasonisable
from jarvis.people.models import Gymnast, GENDER_CHOICES
from jarvis.planning.models import Event
@ -11,138 +25,6 @@ from jarvis.location.models import Club
User = get_user_model()
INJURY_MECHANISM_CHOICE = (
(0, "Overuse"),
(1, "Trauma"),
)
INJURY_BODY_SIDE_CHOICE = (
(0, "Not Applicable"),
(1, "Left"),
(2, "Right"),
(3, "Both"),
)
INJURY_TYPE_CHOICE = (
(0, "Abrasion"),
(1, "Dental Injury"),
(2, "Dislocation / Subluxation"),
(3, "Fracture"),
(4, "Haematoma / Contusion / Bruise"),
(5, "Head Concussion"),
(6, "Laceration"),
(7, "Lesion of Meniscus or Cartilage"),
(8, "Muscle Rupture / Strain / Tear / Cramps"),
(9, "Nerve Injury"),
(10, "Other Bone Injury"),
(11, "Sprain / Ligament Injury"),
(12, "Tendon Injury / Rupture / Tendinosis / Bursitis"),
)
INJURY_LOCATION_CHOICE = (
(0, "Abdomen"),
(1, "Ankle"),
(2, "Elbow"),
(3, "Foot / Toe"),
(4, "Hand / Finger / Thumb"),
(5, "Head / Face"),
(6, "Hip / Groin"),
(7, "Knee"),
(8, "Low back / Sacrum / Pelvis"),
(9, "Lower Leg / Achilles Tendon"),
(10, "Neck / Cervical Spine"),
(11, "Shoulder / Clavicula"),
(12, "Sternum / Ribs / Upper back"),
(13, "Thigh"),
(14, "Upper arm"),
(15, "Wrist"),
)
ROUTINE_TYPE_CHOICE = (
(0, "Other"),
(1, "Q1R1"),
(2, "Q1R2"),
(3, "Q2R1"),
(4, "SF"),
(5, "F"),
(6, "Q1R1S"),
(7, "Q1R2S"),
(8, "Q2R1S"),
(9, "SFS"),
(9, "FS"),
(99, "Other"),
)
LEARNING_STEP_CHOICES = (
(0, "No"),
(1, "With help"),
(2, "Without help"),
(3, "Chained"),
(4, "Masterised"),
)
CHRONO_TYPE_CHOICE = (
(0, "10 |"),
(1, "Q1R1"),
(2, "Q1R2"),
(3, "Q2R1"),
(4, "SF"),
(5, "F"),
(99, "Other"),
)
SCORE_TYPE_CHOICE = (
(0, "Chrono"),
(1, "ToF"),
)
CATEGORY_CHOICES = {
9: "I9",
10: "I10",
11: "A11",
12: "A12",
13: "A13-14",
15: "A Junior",
18: "A Senior",
21: "B11",
22: "B12",
23: "B13-14",
24: "B Junior",
25: "B Senior",
}
AGE_CATOGORY_CHOICES = (
(11, "11-12"),
(13, "13-14"),
(15, "15-16"),
(17, "17-21"),
(22, "Senior"),
)
NOTE_STATUS_CHOICES = (
(0, "Draft"),
(1, "Published"),
)
# MOD_THOMAS_TEST_CHOICES = (
# (0, "not evaluated"),
# (1, "tight psoas"),
# (2, "tight quadriceps"),
# (3, "tight TFL"),
# (4, "tight psoas en quadriceps"),
# (5, "tight quadriceps en TFL"),
# (6, "tight psoas en TFL"),
# (7, "tight psoas en quadriceps en TFL"),
# )
# LOMBO_PELVIC_AND_CERVICAL_CONTROL_CHOICES = (
# (0, "not evaluated"),
# (1, "good control, good mobility"),
# (2, "good control, bad mobility"),
# (3, "bad control, good mobility"),
# (4, "bad control, bad mobility"),
# )
class Chrono(Seasonisable):
"""

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2 on 2024-03-06 06:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("objective", "0019_alter_passe_options_trainingprogram_informations_and_more"),
]
operations = [
migrations.AlterField(
model_name="passe",
name="educatives",
field=models.ManyToManyField(blank=True, to="objective.educative"),
),
]

View File

@ -1,12 +1,16 @@
from django.db import models
from django.db.models import Q
import re
from jarvis.core.global_vars import ROUTINE_TYPE_CHOICE
from jarvis.tools.models import (
Markdownizable,
Seasonisable,
max_even_if_none,
)
# from jarvis.followup.models import ROUTINE_TYPE_CHOICE
class Educative(Markdownizable):
"""
@ -469,7 +473,7 @@ class Passe(Markdownizable):
ordering = ["label"]
label = models.CharField(max_length=30)
educatives = models.ManyToManyField(Educative)
educatives = models.ManyToManyField(Educative, blank=True)
regexp = models.CharField(max_length=50, null=True, blank=True)
number_of_skill = models.PositiveSmallIntegerField(default=0)
difficulty = models.DecimalField(max_digits=4, decimal_places=1, default=0.0)
@ -527,6 +531,62 @@ class Passe(Markdownizable):
def __str__(self):
return f"{self.label} ({self.number_of_skill} | {self.difficulty})"
@staticmethod
def check_regexp(regexp, label, educatives_list):
"""Vérifie le champ regexp
Type de string pris en compte :
- Toutes les valeurs de ROUTINE_TYPE_CHOICE (Educative vide !)
- avec [x-y] (avec X ou Y vide mais pas les deux en même temps)
- [x-y] (avec X ou Y vide mais pas les deux en même temps) (EDUCATIVE non vide !!!)
- WC
- x| (x entier)
Exemples :
- Q1R1 True (si educatives.count() vide)
- Q1R2 [2-8] True (si educatives.count() vide)
- Q1R1 [8-2] False
- Q2R3 [-5] True (si educatives.count() vide)
- SF [6-] True (si educatives.count() vide)
- FS [3-7] True (si educatives.count() vide)
- WC True (si educatives.count() >= 2)
- 1| True (si educatives.count() >= 2)
"""
if label is None and educatives_list is None and regexp is None:
return False
operation_list = regexp.split(" ")
if operation_list.count() >= 3:
return False
if operation_list.count() == 2:
if operation_list[0] in ROUTINE_TYPE_CHOICE:
if re.match(r"\[[1-9]*\-[1-9]*\]", operation_list[1]):
content = operation_list[1].replace("[", "").replace("]", "")
ranks = content.split("-")
if ranks.count() > 1:
if ranks[1] > ranks[1]:
return True
else:
return False
return True
else:
return False
else:
return False
else:
if operation_list[0] == "WC" and educatives_list.count() == 2:
return True
if (
re.match(r"[1-9]+\|", operation_list[0])
and educatives_list.count() >= 1
):
return True
return False
class TrainingProgram(Seasonisable, Markdownizable):
"""Classe représentant un entraînement (ensemble de passage)."""

View File

@ -1,5 +1,5 @@
from django.test import TestCase
from jarvis.objective.models import Educative
from jarvis.objective.models import Educative, Passe
class EducativeTestCase(TestCase):
@ -87,3 +87,52 @@ class EducativeTestCase(TestCase):
[educ_1, educ_2, educ_9],
],
)
class PasseTestCase(TestCase):
def setUp(self):
"""
Structure finale :
1 -> 2
1 -> 6
3 -> 4 -> 5 -> 6 -> 7
1 -> 2 -> 9
3 -> 4 -> 5 -> 6 -> 7 -> 9
"""
# 1 et 3 Eductative sans pre-requis
educ_1 = Educative.objects.create(
long_label="1/2 vrille", difficulty=0.1, level=1, rank=1
)
educ_3 = Educative.objects.create(
long_label="4 pattes", difficulty=0.1, level=1, rank=1
)
def test_check_regexp(self):
label = ""
regexp = ""
educatives_list = []
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
regexp = "Q1R1 [4-8] WC"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
regexp = "Q1R1"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
regexp = "Q1R1 [4-8"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
regexp = "Q1R1 [4-8]"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
regexp = "Q1R1 [4-]"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
regexp = "Q1R1 [-8]"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)
regexp = "Q1R1 [8-4]"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
regexp = "WC"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
educ_1 = Educative.objects.get(long_label="1/2 vrille")
educatives_list.append(educ_1)
regexp = "1|"
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), False)
educ_3 = Educative.objects.get(long_label="4 pattes")
educatives_list.append(educ_3)
self.assertEqual(Passe.check_regexp(regexp, label, educatives_list), True)

View File

@ -527,6 +527,7 @@ def passe_details(request, passe_id):
is_skill = False
passe = get_object_or_404(Passe, pk=passe_id)
educative_list = passe.educatives.all()
# TODO: décryptage de la regexp
number_of_educative = educative_list.count()
context = {

View File

@ -6,6 +6,8 @@ from django.db import models
import pendulum
from jarvis.core.global_vars import GENDER_CHOICES, ORIENTATION_CHOICES
from jarvis.objective.models import Skill
# from jarvis.profiles.models import TrainerGymnast
@ -20,8 +22,6 @@ from jarvis.tools.clean_name import clean_name
User = get_user_model()
GENDER_CHOICES = ((0, "Female"), (1, "Male"))
class Gymnast(Markdownizable):
"""Représente un gymnaste.
@ -32,8 +32,6 @@ class Gymnast(Markdownizable):
verbose_name = "Gymnast"
verbose_name_plural = "Gymnasts"
ORIENTATION_CHOICES = ((None, "Unknown"), (1, "Left"), (2, "Right"))
user = models.OneToOneField(
User, on_delete=models.SET_NULL, related_name="gymnast", blank=True, null=True
)

View File

@ -258,7 +258,7 @@ def gymnast_display_scores_chrono(request, gymnast_id):
base_queryset = chrono_list.values("date").annotate(score_avg=Avg("tof"))
today = pendulum.now().date()
date_list = (
TrainingProgram.objects.filter(gymnast=6, date__gte=today)
TrainingProgram.objects.filter(gymnast=gymnast_id, date__gte=today)
.values_list("date", flat=True)
.order_by("date")
.distinct()