diff --git a/app/forms/main/config_assiduites.py b/app/forms/main/config_assiduites.py index d4adb0571..bb1e89205 100644 --- a/app/forms/main/config_assiduites.py +++ b/app/forms/main/config_assiduites.py @@ -139,7 +139,7 @@ class ConfigAssiduitesForm(FlaskForm): ) edt_ics_title_field = StringField( - label="Champs contenant le titre", + label="Champ contenant le titre", description="""champ de l'évènement calendrier: DESCRIPTION, SUMMARY, ...""", validators=[Optional(), check_ics_field], ) @@ -152,7 +152,7 @@ class ConfigAssiduitesForm(FlaskForm): validators=[Optional(), check_ics_regexp], ) edt_ics_group_field = StringField( - label="Champs contenant le groupe", + label="Champ contenant le groupe", description="""champ de l'évènement calendrier: DESCRIPTION, SUMMARY, ...""", validators=[Optional(), check_ics_field], ) @@ -165,7 +165,7 @@ class ConfigAssiduitesForm(FlaskForm): validators=[Optional(), check_ics_regexp], ) edt_ics_mod_field = StringField( - label="Champs contenant le module", + label="Champ contenant le module", description="""champ de l'évènement calendrier: DESCRIPTION, SUMMARY, ...""", validators=[Optional(), check_ics_field], ) @@ -177,6 +177,18 @@ class ConfigAssiduitesForm(FlaskForm): """, validators=[Optional(), check_ics_regexp], ) - + edt_ics_uid_field = StringField( + label="Champ contenant l'enseignant", + description="""champ de l'évènement calendrier: DESCRIPTION, SUMMARY, ...""", + validators=[Optional(), check_ics_field], + ) + edt_ics_uid_regexp = StringField( + label="Extraction de l'enseignant", + description=r"""expression régulière python dont le premier groupe doit + correspondre à l'identifiant (edt_id) de l'enseignant associé à l'évènement. + Exemple: Enseignant : ([0-9]+) + """, + validators=[Optional(), check_ics_regexp], + ) submit = SubmitField("Valider") cancel = SubmitField("Annuler", render_kw={"formnovalidate": True}) diff --git a/app/scodoc/sco_edt_cal.py b/app/scodoc/sco_edt_cal.py index cf3904382..e0a94e7d2 100644 --- a/app/scodoc/sco_edt_cal.py +++ b/app/scodoc/sco_edt_cal.py @@ -36,6 +36,7 @@ import icalendar from flask import g, url_for from app import log +from app.auth.models import User from app.models import FormSemestre, GroupDescr, ModuleImpl, ScoDocSiteConfig from app.scodoc.sco_exceptions import ScoValueError import app.scodoc.sco_utils as scu @@ -56,8 +57,11 @@ def formsemestre_load_calendar( Raises ScoValueError if not configured or not available or invalid format. """ edt_ids = [] - if edt_id is None and formsemestre: - edt_ids = formsemestre.get_edt_ids() + if edt_id is None: + if formsemestre: + edt_ids = formsemestre.get_edt_ids() + else: + edt_ids = [edt_id] if not edt_ids: raise ScoValueError( "accès aux emplois du temps non configuré pour ce semestre (pas d'edt_id)" @@ -132,8 +136,10 @@ def formsemestre_edt_dict( except ScoValueError as exc: return exc.args[0] # Génération des événements pour le calendrier html - promo_icon = f"""promotion""" + abs_icon = f"""saisir absences""" events_cal = [] for event in events_scodoc: group: GroupDescr | bool = event["group"] @@ -191,19 +197,26 @@ def formsemestre_edt_dict( # --- Lien saisie abs link_abs = ( f"""""" if url_abs else "" ) + + ens_user_name = event["ens"].user_name if event["ens"] else None + ens_nomprenom = event["ens"].get_nomprenom() if event["ens"] else None d = { # Champs utilisés par tui.calendar "calendarId": "cal1", - "title": f"""{title} {group_disp} {link_abs}""", + "title": f"""{title} {group_disp} { + '('+ens_nomprenom+')' if ens_nomprenom else '' + } {link_abs}""", "start": event["start"], "end": event["end"], "backgroundColor": event["group_bg_color"], # Infos brutes pour usage API éventuel + "ens_edt": event["edt_ens"], + "ens_user_name": ens_user_name, "group_id": group.id if group else None, "group_edt_id": event["edt_group"], "moduleimpl_id": modimpl.id if modimpl else None, @@ -257,6 +270,16 @@ def load_and_convert_ics(formsemestre: FormSemestre) -> tuple[list[dict], list[s raise ScoValueError( "expression d'extraction du module depuis l'emploi du temps invalide" ) from exc + edt_ics_uid_field = ScoDocSiteConfig.get("edt_ics_uid_field") + edt_ics_uid_regexp = ScoDocSiteConfig.get("edt_ics_uid_regexp") + try: + edt_ics_uid_pattern = ( + re.compile(edt_ics_uid_regexp) if edt_ics_uid_regexp else None + ) + except re.error as exc: + raise ScoValueError( + "expression d'extraction de l'enseignant depuis l'emploi du temps invalide" + ) from exc # --- Correspondances id edt -> id scodoc pour groupes, modules et enseignants edt2group = formsemestre_retreive_groups_from_edt_id(formsemestre) group_colors = { @@ -266,6 +289,7 @@ def load_and_convert_ics(formsemestre: FormSemestre) -> tuple[list[dict], list[s edt_groups_ids = set() # les ids de groupes 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) # --- events = [e for e in calendar.walk() if e.name == "VEVENT"] events_sco = [] @@ -313,7 +337,19 @@ def load_and_convert_ics(formsemestre: FormSemestre) -> tuple[list[dict], list[s else: modimpl = False edt_module = "" - # --- TODO: enseignant + # --- Enseignant + if edt_ics_uid_pattern: + edt_ens = extract_event_data( + event, edt_ics_uid_field, edt_ics_uid_pattern + ) + if edt_ens in edt2user: + ens = edt2user[edt_ens] + else: + ens = User.query.filter_by(edt_id=edt_ens).first() + edt2user[edt_ens] = ens + else: + ens = None + edt_ens = "" # events_sco.append( { @@ -324,6 +360,9 @@ def load_and_convert_ics(formsemestre: FormSemestre) -> tuple[list[dict], list[s "group_bg_color": group_bg_color, # associée au groupe "modimpl": modimpl, # False si extracteur non configuré "edt_module": edt_module, # id module edt non traduit + # Enseignant + "edt_ens": edt_ens, # id ens edt, non traduit + "ens": ens, # heures pour saisie abs: en heure LOCALE DU SERVEUR "heure_deb": event.decoded("dtstart") .replace(tzinfo=timezone.utc) diff --git a/app/static/icons/absences.svg b/app/static/icons/absences.svg new file mode 100644 index 000000000..9a665ebb1 --- /dev/null +++ b/app/static/icons/absences.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/templates/assiduites/pages/config_assiduites.j2 b/app/templates/assiduites/pages/config_assiduites.j2 index 7d2ae0a52..f1462cd7c 100644 --- a/app/templates/assiduites/pages/config_assiduites.j2 +++ b/app/templates/assiduites/pages/config_assiduites.j2 @@ -96,7 +96,7 @@ affectent notamment les comptages d'absences de tous les bulletins des
-
Voici un évènement chargé au milieu de ce calendrier. +
Voici un évènement chargé, pris au hasard au milieu de ce calendrier. Utilisez cet exemple pour configurer les expressions d'extraction en bas de ce formulaire.
@@ -121,7 +121,10 @@ affectent notamment les comptages d'absences de tous les bulletins des {{ wtf.form_field(form.edt_ics_mod_field) }} {{ wtf.form_field(form.edt_ics_mod_regexp) }}
- +
+ {{ wtf.form_field(form.edt_ics_uid_field) }} + {{ wtf.form_field(form.edt_ics_uid_regexp) }} +
{{ wtf.form_field(form.submit) }} diff --git a/app/templates/base.j2 b/app/templates/base.j2 index 717a6af0d..eace4df92 100644 --- a/app/templates/base.j2 +++ b/app/templates/base.j2 @@ -93,6 +93,6 @@ {% endblock %} \ No newline at end of file diff --git a/app/templates/formsemestre/edit_modimpls_codes.j2 b/app/templates/formsemestre/edit_modimpls_codes.j2 index a663207d3..b1be99b12 100644 --- a/app/templates/formsemestre/edit_modimpls_codes.j2 +++ b/app/templates/formsemestre/edit_modimpls_codes.j2 @@ -4,6 +4,9 @@ {% block styles %} {{super()}}