fix: _eml_to_html retourne le payload QP brut (accents non cassés)
Problème : email.policy.default + get_content() décode déjà les accents (=C3=A9 → é), puis picnic._decode_and_parse() les re-encode en ASCII avec errors="replace" → les accents devenaient "?" → date introuvable. Solution : utiliser l'ancienne API email.message_from_bytes() sans policy et get_payload(decode=False) pour récupérer le corps brut encore QP-encodé, exactement comme un fichier .html sauvegardé depuis le mail. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -114,24 +114,34 @@ def _parse(file_path: Path, source: str):
|
|||||||
def _eml_to_html(file_path: Path) -> str:
|
def _eml_to_html(file_path: Path) -> str:
|
||||||
"""Extrait la partie HTML d'un fichier .eml (email de confirmation Picnic).
|
"""Extrait la partie HTML d'un fichier .eml (email de confirmation Picnic).
|
||||||
|
|
||||||
Lit le .eml avec le module email stdlib, parcourt les parties MIME
|
Retourne le corps HTML brut, encore encodé en Quoted-Printable (QP),
|
||||||
et retourne le contenu de la première partie text/html trouvée.
|
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:
|
Args:
|
||||||
file_path: Chemin vers le fichier .eml.
|
file_path: Chemin vers le fichier .eml.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Contenu HTML sous forme de chaîne.
|
Corps HTML brut (QP-encodé) sous forme de chaîne ASCII.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: Si aucune partie HTML n'est trouvée dans le .eml.
|
ValueError: Si aucune partie HTML n'est trouvée dans le .eml.
|
||||||
"""
|
"""
|
||||||
raw = file_path.read_bytes()
|
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():
|
for part in msg.walk():
|
||||||
if part.get_content_type() == "text/html":
|
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(
|
raise ValueError(
|
||||||
f"Aucune partie HTML trouvée dans le fichier .eml : {file_path.name}"
|
f"Aucune partie HTML trouvée dans le fichier .eml : {file_path.name}"
|
||||||
|
|||||||
Reference in New Issue
Block a user