EDT: normalise identifiants pour améliorer correspondance ics/ScoDoc

This commit is contained in:
Emmanuel Viennet 2024-01-03 14:43:26 +01:00
parent 85f0323a80
commit 96aaca9746
6 changed files with 44 additions and 18 deletions

View File

@ -280,7 +280,10 @@ class FormSemestre(db.Model):
raise ScoValueError("Le semestre n'a pas de groupe par défaut")
def get_edt_ids(self) -> list[str]:
"l'ids pour l'emploi du temps: à défaut, les codes étape Apogée"
"""Les ids pour l'emploi du temps: à défaut, les codes étape Apogée.
Les edt_id de formsemestres ne sont pas normalisés afin de contrôler
précisément l'accès au fichier ics.
"""
return (
scu.split_id(self.edt_id)
or [e.etape_apo.strip() for e in self.etapes if e.etape_apo]

View File

@ -251,8 +251,11 @@ class GroupDescr(ScoDocModel):
return d
def get_edt_ids(self) -> list[str]:
"les ids pour l'emploi du temps: à défaut, le nom scodoc du groupe"
return scu.split_id(self.edt_id) or [self.group_name] or []
"les ids normalisés pour l'emploi du temps: à défaut, le nom scodoc du groupe"
return [
scu.normalize_edt_id(x)
for x in scu.split_id(self.edt_id) or [self.group_name] or []
]
def get_nb_inscrits(self) -> int:
"""Nombre inscrits à ce group et au formsemestre.

View File

@ -67,11 +67,10 @@ class ModuleImpl(db.Model):
def get_edt_ids(self) -> list[str]:
"les ids pour l'emploi du temps: à défaut, les codes Apogée"
return (
scu.split_id(self.edt_id)
or scu.split_id(self.code_apogee)
or self.module.get_edt_ids()
)
return [
scu.normalize_edt_id(x)
for x in scu.split_id(self.edt_id) or scu.split_id(self.code_apogee)
] or self.module.get_edt_ids()
def get_evaluations_poids(self) -> pd.DataFrame:
"""Les poids des évaluations vers les UE (accès via cache)"""

View File

@ -292,7 +292,10 @@ class Module(db.Model):
def get_edt_ids(self) -> list[str]:
"les ids pour l'emploi du temps: à défaut, le 1er code Apogée"
return scu.split_id(self.edt_id) or scu.split_id(self.code_apogee) or []
return [
scu.normalize_edt_id(x)
for x in scu.split_id(self.edt_id) or scu.split_id(self.code_apogee) or []
]
def get_parcours(self) -> list[ApcParcours]:
"""Les parcours utilisant ce module.

View File

@ -343,7 +343,7 @@ def load_and_convert_ics(formsemestre: FormSemestre) -> tuple[list[dict], list[s
group_name: _COLOR_PALETTE[i % (len(_COLOR_PALETTE) - 1) + 1]
for i, group_name in enumerate(edt2group)
}
edt_groups_ids = set() # les ids de groupes tels que dans l'ics
edt_groups_ids = set() # les ids de groupes normalisés tels que dans l'ics
default_group = formsemestre.get_default_group()
edt2modimpl = formsemestre_retreive_modimpls_from_edt_id(formsemestre)
edt2user: dict[str, User | None] = {} # construit au fur et à mesure (cache)
@ -442,14 +442,17 @@ def extract_event_data(
ics_field: str,
pattern: re.Pattern,
none_if_no_match=False,
) -> str:
"""Extrait la chaine (id) de l'évènement."""
) -> str | None:
"""Extrait la chaine (id) de l'évènement et la normalise.
Si l'event n'a pas le champs: "-"
Si pas de match: None
"""
if not event.has_key(ics_field):
return "-"
data = event.decoded(ics_field).decode("utf-8") # assume ics in utf8
m = pattern.search(data)
if m and len(m.groups()) > 0:
return m.group(1)
return scu.normalize_edt_id(m.group(1))
# fallback: if not none_if_no_match, ics field complete
return None if none_if_no_match else data
@ -457,7 +460,7 @@ def extract_event_data(
def formsemestre_retreive_modimpls_from_edt_id(
formsemestre: FormSemestre,
) -> dict[str, ModuleImpl]:
"""Construit un dict donnant le moduleimpl de chaque edt_id"""
"""Construit un dict donnant le moduleimpl de chaque edt_id (normalisé)"""
edt2modimpl = {}
for modimpl in formsemestre.modimpls:
for edt_id in modimpl.get_edt_ids():
@ -469,10 +472,13 @@ def formsemestre_retreive_modimpls_from_edt_id(
def formsemestre_retreive_groups_from_edt_id(
formsemestre: FormSemestre,
) -> dict[str, GroupDescr]:
"""Construit un dict donnant le groupe de chaque edt_id"""
"""Construit un dict donnant le groupe de chaque edt_id
La clé edt_id est sans accents, lowercase.
"""
edt2group = {}
group: GroupDescr
for partition in formsemestre.partitions:
for g in partition.groups:
for edt_id in g.get_edt_ids():
edt2group[edt_id] = g
for group in partition.groups:
for edt_id in group.get_edt_ids():
edt2group[edt_id] = group
return edt2group

View File

@ -841,6 +841,18 @@ def suppress_accents(s):
return s # may be int
def normalize_edt_id(edt_id: str) -> str:
"""Normalize les identifiants edt pour faciliter la correspondance
entre les identifiants ScoDoc et ceux dans l'ics:
Passe tout en majuscules sans accents ni espaces.
"""
return (
None
if edt_id is None
else suppress_accents(edt_id or "").upper().replace(" ", "")
)
class PurgeChars:
"""delete all chars except those belonging to the specified string"""