feat: support .eml Picnic + correction fuzzy matching
Support .eml : - pipeline._eml_to_html() extrait le HTML des emails Picnic - Déposer un .eml dans inbox/picnic/ fonctionne comme un .html - Pas de nouvelle dépendance (module email stdlib) - 5 tests ajoutés (test_eml.py) Correction fuzzy matching : - Le score est maintenant calculé sur le nom seul (avant " | ") - Évite que les différences de marque/poids pénalisent le score - Résultat : 8 paires trouvées vs 0 avant la correction Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,9 @@ Usage :
|
||||
inserted = import_receipt("samples/picnic_sample.html", source="picnic")
|
||||
"""
|
||||
|
||||
import email
|
||||
import logging
|
||||
from email import policy
|
||||
from pathlib import Path
|
||||
|
||||
from tickettracker.db import schema, repository
|
||||
@@ -95,7 +97,10 @@ def _parse(file_path: Path, source: str):
|
||||
"""
|
||||
if source == "picnic":
|
||||
from tickettracker.parsers import picnic
|
||||
html_content = file_path.read_text(encoding="utf-8", errors="replace")
|
||||
if file_path.suffix.lower() == ".eml":
|
||||
html_content = _eml_to_html(file_path)
|
||||
else:
|
||||
html_content = file_path.read_text(encoding="utf-8", errors="replace")
|
||||
return picnic.parse(html_content)
|
||||
|
||||
if source == "leclerc":
|
||||
@@ -104,3 +109,30 @@ def _parse(file_path: Path, source: str):
|
||||
|
||||
# Jamais atteint grâce à la validation en amont, mais satisfait mypy
|
||||
raise ValueError(f"Source inconnue : '{source}'")
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Args:
|
||||
file_path: Chemin vers le fichier .eml.
|
||||
|
||||
Returns:
|
||||
Contenu HTML sous forme de chaîne.
|
||||
|
||||
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)
|
||||
|
||||
for part in msg.walk():
|
||||
if part.get_content_type() == "text/html":
|
||||
return part.get_content()
|
||||
|
||||
raise ValueError(
|
||||
f"Aucune partie HTML trouvée dans le fichier .eml : {file_path.name}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user