diff --git a/pronote_sync/sources/theoretical/file.py b/pronote_sync/sources/theoretical/file.py index 0da9218..633b077 100644 --- a/pronote_sync/sources/theoretical/file.py +++ b/pronote_sync/sources/theoretical/file.py @@ -10,8 +10,6 @@ plage de dates. Le filtrage tient compte du jour de la semaine, de la parité de from __future__ import annotations import logging -import re -import unicodedata from datetime import date, time, timedelta from pathlib import Path from typing import Literal @@ -22,29 +20,11 @@ from pronote_sync.sources.theoretical.holidays import SchoolHolidayCalendar from pronote_sync.sources.theoretical.model import TheoreticalAgendaFile, TheoreticalLessonEntry from pronote_sync.sources.theoretical.parity import WeekParityService from pronote_sync.utils.redaction import redact_exception, redact_secrets +from pronote_sync.utils.text import normalize_subject as normalize_subject logger = logging.getLogger(__name__) -def normalize_subject(subject: str) -> str: - """Normalise une matière pour le matching déterministe. - - Applique la normalisation Unicode NFKC, unifie les espaces (y compris - tabulations et espaces insécables), supprime la ponctuation et met la - chaîne en minuscules. Deux représentations visuellement identiques d'une - même matière produisent ainsi la même forme normalisée. - - :param subject: La matière brute. - :return: La forme normalisée (NFKC, espaces unifiés, sans ponctuation, minuscule). - :rtype: str - """ - normalized = unicodedata.normalize("NFKC", subject) - normalized = re.sub(r"\s+", " ", normalized).strip() - normalized = re.sub(r"[^\w\s]", "", normalized) - normalized = re.sub(r"\s+", " ", normalized).strip() - return normalized.lower() - - def _generate_id(entry: TheoreticalLessonEntry) -> str: """Génère un identifiant déterministe pour une entrée de cours. diff --git a/pronote_sync/utils/text.py b/pronote_sync/utils/text.py new file mode 100644 index 0000000..199091b --- /dev/null +++ b/pronote_sync/utils/text.py @@ -0,0 +1,32 @@ +"""Utilitaires de normalisation et de traitement du texte. + +Ce module centralise les transformations de texte partagées par plusieurs +couches du pipeline ``pronote-sync`` (sources, synchronisation) afin que les +modules de logique de domaine ne dépendent pas d'adaptateurs concrets. +""" + +from __future__ import annotations + +import re +import unicodedata + +__all__ = ["normalize_subject"] + + +def normalize_subject(subject: str) -> str: + """Normalise une matière pour le matching déterministe. + + Applique la normalisation Unicode NFKC, unifie les espaces (y compris + tabulations et espaces insécables), supprime la ponctuation et met la + chaîne en minuscules. Deux représentations visuellement identiques d'une + même matière produisent ainsi la même forme normalisée. + + :param subject: La matière brute. + :return: La forme normalisée (NFKC, espaces unifiés, sans ponctuation, minuscule). + :rtype: str + """ + normalized = unicodedata.normalize("NFKC", subject) + normalized = re.sub(r"\s+", " ", normalized).strip() + normalized = re.sub(r"[^\w\s]", "", normalized) + normalized = re.sub(r"\s+", " ", normalized).strip() + return normalized.lower()