#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Fonctions utilitaires pour nettoyer le HTML et formater les dates. Version consolidée : intègre la fonctionnalité de base avec des améliorations pour le traitement des messages transférés. """ import re from datetime import datetime def clean_html(html_content, is_description=False): """ Nettoie le contenu HTML pour le Markdown. Supprime les balises, les bas de page, les messages automatiques et les sections vides. """ if not html_content: return "" # NOUVEAU: Supprimer directement tout le texte après un crochet isolé suivi d'une ligne vide # Cette méthode plus directe devrait capturer le cas du ticket T0282 isolated_bracket_pattern = r'\n\s*\[\s*\n\s*\n' bracket_match = re.search(isolated_bracket_pattern, html_content) if bracket_match: # Prendre uniquement la partie avant le crochet isolé html_content = html_content[:bracket_match.start()].strip() # Traitement spécifique pour les descriptions if is_description: # Suppression complète des balises font et autres balises de formatage html_content = re.sub(r']*>|', '', html_content) html_content = re.sub(r']*>|

', '\n', html_content) html_content = re.sub(r']*>', '\n', html_content) # Suppression des balises HTML restantes html_content = re.sub(r'<[^>]+>', '', html_content) # Nettoyage des sauts de ligne multiples html_content = re.sub(r'\n\s*\n', '\n\n', html_content) # Suppression des espaces inutiles html_content = re.sub(r'^\s+', '', html_content, flags=re.MULTILINE) html_content = re.sub(r'\s+$', '', html_content, flags=re.MULTILINE) # Nettoyage final html_content = html_content.strip() return html_content # Traitement spécifique pour les messages transférés if "\\-------- Message transféré --------" in html_content: # Le code existant reste inchangé match = re.search(r'Bonjour.*?(?=\n\s*_+Ce message)', html_content, re.DOTALL) if match: html_content = match.group(0).strip() else: match = re.search(r'Copie à :.*?\n\s*\n(.*?)(?=\n\s*_+|\Z)', html_content, re.DOTALL) if match: html_content = match.group(1).strip() # Traitement spécifique pour les notifications d'appel if "Notification d'appel" in html_content: # Le code existant reste inchangé match = re.search(r'(?:Sujet d\'appel:[^\n]*\n[^\n]*\n[^\n]*\n[^\n]*\n)[^\n]*\n[^\n]*([^|]+)', html_content, re.DOTALL) if match: message_content = match.group(1).strip() # Construire un message formaté avec les informations essentielles infos = {} date_match = re.search(r'Date:.*?\|(.*?)(?:\n|$)', html_content) appelant_match = re.search(r'\*\*Appel de:\*\*.*?\|(.*?)(?:\n|$)', html_content) telephone_match = re.search(r'Téléphone principal:.*?\|(.*?)(?:\n|$)', html_content) mobile_match = re.search(r'Mobile:.*?\|(.*?)(?:\n|$)', html_content) sujet_match = re.search(r'Sujet d\'appel:.*?\|(.*?)(?:\n|$)', html_content) if date_match: infos["date"] = date_match.group(1).strip() if appelant_match: infos["appelant"] = appelant_match.group(1).strip() if telephone_match: infos["telephone"] = telephone_match.group(1).strip() if mobile_match: infos["mobile"] = mobile_match.group(1).strip() if sujet_match: infos["sujet"] = sujet_match.group(1).strip() # Construire le message formaté formatted_message = f"**Notification d'appel**\n\n" if "appelant" in infos: formatted_message += f"De: {infos['appelant']}\n" if "date" in infos: formatted_message += f"Date: {infos['date']}\n" if "telephone" in infos: formatted_message += f"Téléphone: {infos['telephone']}\n" if "mobile" in infos: formatted_message += f"Mobile: {infos['mobile']}\n" if "sujet" in infos: formatted_message += f"Sujet: {infos['sujet']}\n\n" formatted_message += f"Message: {message_content}" html_content = formatted_message # Le reste du code reste inchangé # Transformer les balises h1 en titres Markdown html_content = re.sub(r'

(.*?)

', r'### \1', html_content) # Transformer les listes à puces html_content = re.sub(r'
    (.*?)
', r'\1', html_content, flags=re.DOTALL) html_content = re.sub(r'
  • (.*?)
  • ', r'- **\1**\n', html_content) html_content = re.sub(r'
  • (.*?)
  • ', r'- \1\n', html_content) # Supprimer les balises simples html_content = re.sub(r'|

    |

    |
    |
    ', '\n', html_content) # Supprimer les bas de page et messages automatiques du support html_content = re.sub(r'Droit à la déconnexion :.*?(?=\n\n|\Z)', '', html_content, flags=re.DOTALL) html_content = re.sub(r'\*\s*\*\s*\*.*?(?=\n\n|\Z)', '', html_content, flags=re.DOTALL) html_content = re.sub(r'Ce message électronique et tous les fichiers.*?(?=\n\n|\Z)', '', html_content, flags=re.DOTALL) html_content = re.sub(r'Afin d\'assurer une meilleure traçabilité.*?(?=\n\n|\Z)', '', html_content, flags=re.IGNORECASE | re.DOTALL) html_content = re.sub(r'Affin d\'assurer une meilleure traçabilité.*?(?=\n\n|\Z)', '', html_content, flags=re.IGNORECASE | re.DOTALL) html_content = re.sub(r'_Confidentialité :.*?(?=\n\n|\Z)', '', html_content, flags=re.DOTALL) html_content = re.sub(r'Support technique.*?(?=\n\n|\Z)', '', html_content, flags=re.DOTALL) # Suppression de l'image signature CBAO et autres images html_content = re.sub(r'!\[CBAO - développeur de rentabilité.*?(?=\n\n|\Z)', '', html_content, flags=re.DOTALL) html_content = re.sub(r'!\[.*?\]\(/web/image/.*?\)', '', html_content) html_content = re.sub(r'!\[cid:.*?\]\(/web/image/.*?\)', '', html_content) # Supprimer les balises HTML restantes html_content = re.sub(r'<.*?>', '', html_content) # Remplacer les entités HTML courantes html_content = html_content.replace(' ', ' ') html_content = html_content.replace('<', '<') html_content = html_content.replace('>', '>') html_content = html_content.replace('&', '&') html_content = html_content.replace('"', '"') # Supprimer les lignes avec uniquement des ** html_content = re.sub(r'^\s*\*\*\s*\*\*\s*$', '', html_content, flags=re.MULTILINE) html_content = re.sub(r'^\s*\*\*\s*$', '', html_content, flags=re.MULTILINE) # Supprimer le \--- à la fin des messages html_content = re.sub(r'\\---\s*$', '', html_content) # Supprimer les crochets isolés html_content = re.sub(r'\[\s*$', '', html_content) html_content = re.sub(r'^\s*\[\s*$', '', html_content, flags=re.MULTILINE) # Supprimer les lignes vides multiples html_content = re.sub(r'\n\s*\n', '\n\n', html_content) # Nettoyer au début et à la fin html_content = html_content.strip() # Supprimer les sections vides (comme "*Contenu vide*") if not html_content or html_content.lower() == "*contenu vide*": return "*Contenu vide*" return html_content def format_date(date_str): """ Formate une date ISO en format lisible. """ # Code inchangé if not date_str: return "" try: dt = datetime.fromisoformat(date_str.replace('Z', '+00:00')) return dt.strftime("%d/%m/%Y %H:%M:%S") except (ValueError, TypeError): return date_str if __name__ == "__main__": # Tests html = """

    Bonjour,

    Voici un message avec du HTML et une signature.

    Cordialement,

    John Doe

    Support technique

    Afin d'assurer une meilleure traçabilité et vous garantir une prise en charge optimale, nous vous invitons à envoyer vos demandes d'assistance technique à support@exemple.fr

    ![CBAO - développeur de rentabilité - www.exemple.fr](data:image/png;base64,ABC123)

    """ cleaned = clean_html(html) print("HTML nettoyé :\n", cleaned) # Test avec un message transféré forwarded = """\\-------- Message transféré -------- Sujet : | Test message ---|--- Date : | Mon, 30 Mar 2020 11:18:20 +0200 De : | [test@example.com](mailto:test@example.com) Pour : | John Doe [](mailto:john@example.com) Copie à : | [other@example.com](mailto:other@example.com) Bonjour John, Voici un message de test. Cordialement, Test User __________________________________________________________________ Ce message et toutes les pièces jointes sont confidentiels et établis à l'intention exclusive de ses destinataires. __________________________________________________________________""" cleaned_forwarded = clean_html(forwarded) print("\nMessage transféré nettoyé :\n", cleaned_forwarded) # Test avec le cas problématique du ticket T0282 test_t0282 = """Bonjour, Je reviens vers vous pour savoir si vous souhaitez toujours renommer le numéro d'identification de certaines formules dans BCN ou si vous avez trouvé une solution alternative ? En vous remerciant par avance, je reste à votre disposition pour tout complément d'information. Cordialement. **Youness BENDEQ** [ Affin d'assurer une meilleure traçabilité et vous garantir une prise en charge optimale, nous vous invitons à envoyer vos demandes d'assistance technique à support@cbao.fr Notre service est ouvert du lundi au vendredi de 9h à 12h et de 14h à 18h. Dès réception, un technicien prendra en charge votre demande et au besoin vous rappellera.""" cleaned_t0282 = clean_html(test_t0282) print("\nTest ticket T0282 nettoyé :\n", cleaned_t0282)