#!/usr/bin/env python3 """ Serveur SMTP de débogage pour Notytex ====================================== Serveur SMTP de développement qui affiche les emails en console au lieu de les envoyer. Idéal pour tester l'envoi de bilans sans configuration SMTP réelle. Usage: python debug_smtp_server.py Configuration dans l'interface web: - Serveur SMTP: localhost - Port: 1025 - Utilisateur/Mot de passe: (laisser vides) - TLS: Désactivé """ import asyncio import email from email.policy import default from datetime import datetime from aiosmtpd.controller import Controller from aiosmtpd.smtp import SMTP as SMTPServer class DebugSMTPHandler: """Gestionnaire personnalisé pour afficher les emails en console.""" async def handle_DATA(self, server, session, envelope): """ Traite les emails reçus et les affiche en console. Args: server: Instance du serveur SMTP session: Session SMTP courante envelope: Envelope contenant les données de l'email Returns: str: Code de statut SMTP """ print("\n" + "=" * 80) print("📧 NOUVEL EMAIL REÇU") print("=" * 80) # Informations de l'envelope print(f"\n🔹 De: {envelope.mail_from}") print(f"🔹 À: {', '.join(envelope.rcpt_tos)}") print(f"🔹 Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") # Parse le contenu de l'email try: msg = email.message_from_bytes(envelope.content, policy=default) # En-têtes principaux print(f"\n📋 HEADERS:") print(f" Subject: {msg.get('Subject', '(sans sujet)')}") print(f" From: {msg.get('From', '(inconnu)')}") print(f" To: {msg.get('To', '(inconnu)')}") print(f" Date: {msg.get('Date', '(inconnue)')}") # Parcourir les parties du message if msg.is_multipart(): print(f"\n📦 MESSAGE MULTIPART ({len(msg.get_payload())} parties)") for idx, part in enumerate(msg.iter_parts(), 1): content_type = part.get_content_type() print(f"\n Partie {idx}: {content_type}") # Afficher le contenu texte if content_type == 'text/plain': text_content = part.get_content() print(f"\n 📄 CONTENU TEXTE:") print(" " + "-" * 76) for line in text_content.split('\n')[:20]: # Limiter à 20 lignes print(f" {line}") if len(text_content.split('\n')) > 20: print(f" ... ({len(text_content.split('\n')) - 20} lignes supplémentaires)") print(" " + "-" * 76) # Afficher un aperçu du contenu HTML elif content_type == 'text/html': html_content = part.get_content() print(f"\n 🎨 CONTENU HTML ({len(html_content)} caractères)") print(" " + "-" * 76) # Extraire et afficher le titre si présent if '' in html_content: import re title_match = re.search(r'<title>(.*?)', html_content, re.IGNORECASE) if title_match: print(f" Titre: {title_match.group(1)}") # Afficher un extrait du HTML lines = html_content.split('\n') preview_lines = [l.strip() for l in lines if l.strip() and not l.strip().startswith(' 1000: print(f"... ({len(content) - 1000} caractères supplémentaires)") print("-" * 80) except Exception as e: print(f"\n❌ ERREUR lors du parsing de l'email: {e}") print("\n📋 CONTENU BRUT:") print("-" * 80) print(envelope.content.decode('utf-8', errors='replace')[:2000]) print("-" * 80) print("\n" + "=" * 80) print("✅ Email traité avec succès") print("=" * 80 + "\n") return '250 Message accepted for delivery' async def run_server(): """Lance le serveur SMTP et attend indéfiniment.""" handler = DebugSMTPHandler() controller = Controller(handler, hostname='localhost', port=1025) controller.start() print("✅ Serveur démarré avec succès!") print("📬 En attente d'emails... (Ctrl+C pour arrêter)\n") try: # Attendre indéfiniment while True: await asyncio.sleep(3600) finally: controller.stop() def main(): """Lance le serveur SMTP de débogage.""" print("\n" + "=" * 80) print("🚀 SERVEUR SMTP DE DÉBOGAGE NOTYTEX") print("=" * 80) print("\nConfiguration recommandée dans l'interface web:") print(" • Serveur SMTP: localhost") print(" • Port: 1025") print(" • Utilisateur: (laisser vide)") print(" • Mot de passe: (laisser vide)") print(" • TLS: Désactivé") print("\n" + "-" * 80) print("📡 Démarrage du serveur sur localhost:1025...") print("-" * 80 + "\n") try: asyncio.run(run_server()) except KeyboardInterrupt: print("\n\n" + "=" * 80) print("🛑 Arrêt du serveur...") print("=" * 80) print("✅ Serveur arrêté proprement\n") except Exception as e: print(f"\n❌ ERREUR: {e}") raise if __name__ == "__main__": main()