|
|
@@ -0,0 +1,102 @@
|
|
|
+import smtplib
|
|
|
+import ssl
|
|
|
+from email.mime.text import MIMEText
|
|
|
+
|
|
|
+from flask import current_app
|
|
|
+
|
|
|
+
|
|
|
+def _get(key, default=""):
|
|
|
+ from db import Setting
|
|
|
+ s = Setting.query.filter_by(key=key).first()
|
|
|
+ return s.value if s else default
|
|
|
+
|
|
|
+
|
|
|
+def send_job_notification(run, job):
|
|
|
+ """Envoie une notification email après un job. Silencieux si non configuré."""
|
|
|
+ if run.status == "success" and _get("notify_on_success", "0") != "1":
|
|
|
+ return
|
|
|
+ if run.status == "error" and _get("notify_on_error", "1") != "1":
|
|
|
+ return
|
|
|
+
|
|
|
+ smtp_host = _get("smtp_host")
|
|
|
+ smtp_to = _get("smtp_to")
|
|
|
+ if not smtp_host or not smtp_to:
|
|
|
+ return
|
|
|
+
|
|
|
+ instance = current_app.config.get("INSTANCE_NAME", "backupmanager")
|
|
|
+
|
|
|
+ if run.status == "success":
|
|
|
+ subject = f"[{instance}] ✓ {run.archive_name or job.name} — sauvegarde réussie"
|
|
|
+ d = run.duration_seconds or 0
|
|
|
+ duration = f"{d // 60}min {d % 60}s" if d >= 60 else f"{d}s"
|
|
|
+ body = (
|
|
|
+ f"Sauvegarde réussie\n\n"
|
|
|
+ f"Job : {job.name}\n"
|
|
|
+ f"Type : {job.type}\n"
|
|
|
+ f"Archive : {run.archive_name}\n"
|
|
|
+ f"Taille : {run.size_human}\n"
|
|
|
+ f"Durée : {duration}\n"
|
|
|
+ f"Instance : {instance}\n"
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ subject = f"[{instance}] ✗ {job.name} — ERREUR de sauvegarde"
|
|
|
+ body = (
|
|
|
+ f"Erreur lors de la sauvegarde\n\n"
|
|
|
+ f"Job : {job.name}\n"
|
|
|
+ f"Type : {job.type}\n"
|
|
|
+ f"Instance : {instance}\n\n"
|
|
|
+ f"Détail :\n{run.log_text or '(aucun log)'}\n"
|
|
|
+ )
|
|
|
+
|
|
|
+ try:
|
|
|
+ _send(
|
|
|
+ host=smtp_host,
|
|
|
+ port=int(_get("smtp_port", "587")),
|
|
|
+ user=_get("smtp_user"),
|
|
|
+ password=_get("smtp_password"),
|
|
|
+ from_addr=_get("smtp_from") or _get("smtp_user"),
|
|
|
+ to_addr=smtp_to,
|
|
|
+ subject=subject,
|
|
|
+ body=body,
|
|
|
+ use_ssl=_get("smtp_ssl", "0") == "1",
|
|
|
+ use_tls=_get("smtp_tls", "1") == "1",
|
|
|
+ )
|
|
|
+ except Exception as exc:
|
|
|
+ current_app.logger.warning(f"Notification email échouée : {exc}")
|
|
|
+
|
|
|
+
|
|
|
+def send_test_email(host, port, user, password, from_addr, to_addr, use_ssl, use_tls):
|
|
|
+ """Envoie un email de test. Lève une exception si ça échoue."""
|
|
|
+ _send(
|
|
|
+ host=host,
|
|
|
+ port=int(port),
|
|
|
+ user=user,
|
|
|
+ password=password,
|
|
|
+ from_addr=from_addr or user,
|
|
|
+ to_addr=to_addr,
|
|
|
+ subject="Test SMTP — Backup Manager",
|
|
|
+ body="Si vous recevez cet email, la configuration SMTP est correcte.",
|
|
|
+ use_ssl=use_ssl,
|
|
|
+ use_tls=use_tls,
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+def _send(host, port, user, password, from_addr, to_addr, subject, body, use_ssl, use_tls):
|
|
|
+ msg = MIMEText(body, "plain", "utf-8")
|
|
|
+ msg["Subject"] = subject
|
|
|
+ msg["From"] = from_addr
|
|
|
+ msg["To"] = to_addr
|
|
|
+
|
|
|
+ ctx = ssl.create_default_context()
|
|
|
+ if use_ssl:
|
|
|
+ with smtplib.SMTP_SSL(host, port, context=ctx) as smtp:
|
|
|
+ if user:
|
|
|
+ smtp.login(user, password)
|
|
|
+ smtp.sendmail(from_addr, [to_addr], msg.as_string())
|
|
|
+ else:
|
|
|
+ with smtplib.SMTP(host, port, timeout=15) as smtp:
|
|
|
+ if use_tls:
|
|
|
+ smtp.starttls(context=ctx)
|
|
|
+ if user:
|
|
|
+ smtp.login(user, password)
|
|
|
+ smtp.sendmail(from_addr, [to_addr], msg.as_string())
|