diff --git a/tickettracker/pipeline.py b/tickettracker/pipeline.py index 36e2a96..500e11b 100644 --- a/tickettracker/pipeline.py +++ b/tickettracker/pipeline.py @@ -114,24 +114,34 @@ def _parse(file_path: Path, source: str): def _eml_to_html(file_path: Path) -> str: """Extrait la partie HTML d'un fichier .eml (email de confirmation Picnic). - Lit le .eml avec le module email stdlib, parcourt les parties MIME - et retourne le contenu de la première partie text/html trouvée. + Retourne le corps HTML brut, encore encodé en Quoted-Printable (QP), + exactement comme si on lisait un fichier .html sauvegardé depuis le mail. + Le parser Picnic (picnic._decode_and_parse) se charge lui-même du décodage QP. + + Pourquoi ne pas utiliser policy.default / get_content() ? + Parce que cette API décode déjà les accents (=C3=A9 → é), ce qui empêche + picnic.py de les retrouver via sa propre pipeline QP → UTF-8. Args: file_path: Chemin vers le fichier .eml. Returns: - Contenu HTML sous forme de chaîne. + Corps HTML brut (QP-encodé) sous forme de chaîne ASCII. Raises: ValueError: Si aucune partie HTML n'est trouvée dans le .eml. """ raw = file_path.read_bytes() - msg = email.message_from_bytes(raw, policy=policy.default) + # On utilise l'ancienne API (sans policy.default) pour garder le payload brut + msg = email.message_from_bytes(raw) for part in msg.walk(): if part.get_content_type() == "text/html": - return part.get_content() + # decode=False → payload brut, encore QP-encodé, en str ASCII + payload = part.get_payload(decode=False) + if isinstance(payload, bytes): + return payload.decode("ascii", errors="replace") + return payload # déjà une str raise ValueError( f"Aucune partie HTML trouvée dans le fichier .eml : {file_path.name}"