forked from ScoDoc/ScoDoc
EDT: améliore apparence + accepote plusieurs codes edt par modimpl
This commit is contained in:
parent
093ab253f3
commit
77c9a48d02
@ -269,10 +269,12 @@ class FormSemestre(db.Model):
|
||||
return default_partition.groups.first()
|
||||
raise ScoValueError("Le semestre n'a pas de groupe par défaut")
|
||||
|
||||
def get_edt_id(self) -> str:
|
||||
"l'id pour l'emploi du temps: à défaut, le 1er code étape Apogée"
|
||||
def get_edt_ids(self) -> list[str]:
|
||||
"l'ids pour l'emploi du temps: à défaut, les codes étape Apogée"
|
||||
return (
|
||||
self.edt_id or "" or (self.etapes[0].etape_apo if len(self.etapes) else "")
|
||||
scu.split_id(self.edt_id)
|
||||
or [e.etape_apo.strip() for e in self.etapes if e.etape_apo]
|
||||
or []
|
||||
)
|
||||
|
||||
def get_infos_dict(self) -> dict:
|
||||
|
@ -58,12 +58,12 @@ class ModuleImpl(db.Model):
|
||||
return {x.strip() for x in self.code_apogee.split(",") if x}
|
||||
return self.module.get_codes_apogee()
|
||||
|
||||
def get_edt_id(self) -> str:
|
||||
"l'id pour l'emploi du temps: à défaut, le 1er code Apogée"
|
||||
def get_edt_ids(self) -> list[str]:
|
||||
"les ids pour l'emploi du temps: à défaut, les codes Apogée"
|
||||
return (
|
||||
self.edt_id
|
||||
or (self.code_apogee.split(",")[0] if self.code_apogee else "")
|
||||
or self.module.get_edt_id()
|
||||
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:
|
||||
|
@ -285,13 +285,9 @@ class Module(db.Model):
|
||||
return {x.strip() for x in self.code_apogee.split(",") if x}
|
||||
return set()
|
||||
|
||||
def get_edt_id(self) -> str:
|
||||
"l'id pour l'emploi du temps: à défaut, le 1er code Apogée"
|
||||
return (
|
||||
self.edt_id
|
||||
or (self.code_apogee.split(",")[0] if self.code_apogee else "")
|
||||
or ""
|
||||
)
|
||||
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 []
|
||||
|
||||
def get_parcours(self) -> list[ApcParcours]:
|
||||
"""Les parcours utilisant ce module.
|
||||
|
@ -34,7 +34,7 @@ from datetime import timezone
|
||||
import re
|
||||
import icalendar
|
||||
|
||||
from flask import flash, g, url_for
|
||||
from flask import g, url_for
|
||||
from app import log
|
||||
from app.models import FormSemestre, GroupDescr, ModuleImpl, ScoDocSiteConfig
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
@ -56,12 +56,14 @@ def formsemestre_load_calendar(
|
||||
Raises ScoValueError if not configured or not available or invalid format.
|
||||
"""
|
||||
if edt_id is None and formsemestre:
|
||||
edt_id = formsemestre.get_edt_id()
|
||||
if not edt_id:
|
||||
edt_ids = formsemestre.get_edt_ids()
|
||||
if not edt_ids:
|
||||
raise ScoValueError(
|
||||
"accès aux emplois du temps non configuré pour ce semestre (pas d'edt_id)"
|
||||
)
|
||||
ics_filename = get_ics_filename(edt_id)
|
||||
# Ne charge qu'un seul ics pour le semestre, prend uniquement
|
||||
# le premier edt_id
|
||||
ics_filename = get_ics_filename(edt_ids[0])
|
||||
if ics_filename is None:
|
||||
raise ScoValueError("accès aux emplois du temps non configuré (pas de chemin)")
|
||||
try:
|
||||
@ -147,24 +149,9 @@ def formsemestre_edt_dict(
|
||||
if group and group_ids_set and group.id not in group_ids_set:
|
||||
continue # ignore cet évènement
|
||||
modimpl: ModuleImpl | bool = event["modimpl"]
|
||||
if modimpl is False:
|
||||
mod_disp = f"""<div class="module-edt"
|
||||
title="extraction emploi du temps non configurée">
|
||||
{scu.EMO_WARNING} non configuré
|
||||
</div>"""
|
||||
else:
|
||||
mod_disp = (
|
||||
f"""<div class="module-edt mod-name" title="{modimpl.module.abbrev or ""}">{
|
||||
modimpl.module.code}</div>"""
|
||||
if modimpl
|
||||
else f"""<div class="module-edt mod-etd" title="code module non trouvé dans ScoDoc.
|
||||
Vérifier configuration.">{
|
||||
scu.EMO_WARNING} {event['edt_module']}</div>"""
|
||||
)
|
||||
# --- Lien saisie abs
|
||||
link_abs = (
|
||||
f"""<div class="module-edt link-abs"><a class="stdlink" href="{
|
||||
url_for("assiduites.signal_assiduites_group",
|
||||
url_abs = (
|
||||
url_for(
|
||||
"assiduites.signal_assiduites_group",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre.id,
|
||||
group_ids=group.id,
|
||||
@ -172,15 +159,41 @@ def formsemestre_edt_dict(
|
||||
heure_fin=event["heure_fin"],
|
||||
moduleimpl_id=modimpl.id,
|
||||
jour=event["jour"],
|
||||
)}">absences</a>
|
||||
</div>"""
|
||||
)
|
||||
if modimpl and group
|
||||
else None
|
||||
)
|
||||
match modimpl:
|
||||
case False: # EDT non configuré
|
||||
mod_disp = f"""<span>{scu.EMO_WARNING} non configuré</span>"""
|
||||
bubble = "extraction emploi du temps non configurée"
|
||||
case None: # Module edt non trouvé dans ScoDoc
|
||||
mod_disp = f"""<span class="mod-etd">{
|
||||
scu.EMO_WARNING} {event['edt_module']}</span>"""
|
||||
bubble = "code module non trouvé dans ScoDoc. Vérifier configuration."
|
||||
case _: # module EDT bien retrouvé dans ScoDoc
|
||||
mod_disp = f"""<span class="mod-name mod-code" title="{
|
||||
modimpl.module.abbrev or ""} ({event['edt_module']})">{
|
||||
modimpl.module.code}</span>"""
|
||||
bubble = f"{modimpl.module.abbrev or ''} ({event['edt_module']})"
|
||||
|
||||
title = f"""<div class = "module-edt" title="{bubble} {event['title_edt']}">
|
||||
<a class="discretelink" href="{url_abs or ''}">{mod_disp} <span>{event['title']}</span></a>
|
||||
</div>
|
||||
"""
|
||||
|
||||
# --- Lien saisie abs
|
||||
link_abs = (
|
||||
f"""<div class="module-edt link-abs"><a class="stdlink" href="{
|
||||
url_abs}">absences</a>
|
||||
</div>"""
|
||||
if url_abs
|
||||
else ""
|
||||
)
|
||||
d = {
|
||||
# Champs utilisés par tui.calendar
|
||||
"calendarId": "cal1",
|
||||
"title": event["title"] + group_disp + mod_disp + link_abs,
|
||||
"title": f"""{title} {group_disp} {link_abs}""",
|
||||
"start": event["start"],
|
||||
"end": event["end"],
|
||||
"backgroundColor": event["group_bg_color"],
|
||||
@ -245,11 +258,13 @@ def _load_and_convert_ics(formsemestre: FormSemestre) -> list[dict]:
|
||||
for event in events:
|
||||
if "DESCRIPTION" in event:
|
||||
# --- Titre de l'évènement
|
||||
title = (
|
||||
title_edt = (
|
||||
extract_event_data(event, edt_ics_title_field, edt_ics_title_pattern)
|
||||
if edt_ics_title_pattern
|
||||
else "non configuré"
|
||||
)
|
||||
# title remplacé par le nom du module scodoc quand il est trouvé
|
||||
title = title_edt
|
||||
# --- Group
|
||||
if edt_ics_group_pattern:
|
||||
edt_group = extract_event_data(
|
||||
@ -278,6 +293,8 @@ def _load_and_convert_ics(formsemestre: FormSemestre) -> list[dict]:
|
||||
event, edt_ics_mod_field, edt_ics_mod_pattern
|
||||
)
|
||||
modimpl: ModuleImpl = edt2modimpl.get(edt_module, None)
|
||||
if modimpl:
|
||||
title = modimpl.module.titre_str()
|
||||
else:
|
||||
modimpl = False
|
||||
edt_module = ""
|
||||
@ -285,7 +302,8 @@ def _load_and_convert_ics(formsemestre: FormSemestre) -> list[dict]:
|
||||
#
|
||||
events_sco.append(
|
||||
{
|
||||
"title": title,
|
||||
"title": title, # titre event ou nom module
|
||||
"title_edt": title_edt, # titre event
|
||||
"edt_group": edt_group, # id group edt non traduit
|
||||
"group": group, # False si extracteur non configuré
|
||||
"group_bg_color": group_bg_color, # associée au groupe
|
||||
@ -376,8 +394,11 @@ def formsemestre_retreive_modimpls_from_edt_id(
|
||||
formsemestre: FormSemestre,
|
||||
) -> dict[str, ModuleImpl]:
|
||||
"""Construit un dict donnant le moduleimpl de chaque edt_id"""
|
||||
edt2modimpl = {modimpl.get_edt_id(): modimpl for modimpl in formsemestre.modimpls}
|
||||
edt2modimpl.pop("", None)
|
||||
edt2modimpl = {}
|
||||
for modimpl in formsemestre.modimpls:
|
||||
for edt_id in modimpl.get_edt_ids():
|
||||
if edt_id:
|
||||
edt2modimpl[edt_id] = modimpl
|
||||
return edt2modimpl
|
||||
|
||||
|
||||
|
@ -764,13 +764,23 @@ FORBIDDEN_CHARS_EXP = re.compile(r"[*\|~\(\)\\]")
|
||||
ALPHANUM_EXP = re.compile(r"^[\w-]+$", re.UNICODE)
|
||||
|
||||
|
||||
def is_valid_code_nip(s):
|
||||
def is_valid_code_nip(s: str) -> bool:
|
||||
"""True si s peut être un code NIP: au moins 6 chiffres décimaux"""
|
||||
if not s:
|
||||
return False
|
||||
return re.match(r"^[0-9]{6,32}$", s)
|
||||
|
||||
|
||||
def split_id(ident: str) -> list[str]:
|
||||
"""ident est une chaine 'X, Y, Z'
|
||||
Renvoie ['X','Y', 'Z']
|
||||
"""
|
||||
if ident:
|
||||
ident = ident.strip()
|
||||
return [x.strip() for x in ident.strip().split(",")] if ident else []
|
||||
return []
|
||||
|
||||
|
||||
def strnone(s):
|
||||
"convert s to string, '' if s is false"
|
||||
if s:
|
||||
|
@ -6,8 +6,17 @@
|
||||
font-size: 12pt;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
.module-edt {
|
||||
display: inline;
|
||||
}
|
||||
.mod-code {
|
||||
font-weight: bold;
|
||||
color: rgb(21, 21, 116);
|
||||
font-size: 110%;
|
||||
}
|
||||
.group-name {
|
||||
color: rgb(25, 113, 25);
|
||||
display: inline;
|
||||
}
|
||||
.group-edt {
|
||||
color: red;
|
||||
|
Loading…
Reference in New Issue
Block a user