From 4a41e40592dc1f83bce724b541fdc3179fb88b1d Mon Sep 17 00:00:00 2001 From: MacRimi Date: Tue, 3 Mar 2026 20:59:43 +0100 Subject: [PATCH] Update notification_channels.py --- AppImage/scripts/notification_channels.py | 118 ++++++++-------------- 1 file changed, 40 insertions(+), 78 deletions(-) diff --git a/AppImage/scripts/notification_channels.py b/AppImage/scripts/notification_channels.py index 5caf5907..55569d9c 100644 --- a/AppImage/scripts/notification_channels.py +++ b/AppImage/scripts/notification_channels.py @@ -414,65 +414,21 @@ class EmailChannel(NotificationChannel): return self._send_with_retry(_do_send) - @staticmethod - def _get_logo_path() -> str: - """Locate the ProxMenux logo PNG for email embedding.""" - import os - candidates = [ - os.path.join(os.path.dirname(__file__), '..', 'public', 'images', 'proxmenux-logo.png'), - '/opt/proxmenux-monitor/public/images/proxmenux-logo.png', - os.path.join(os.path.dirname(__file__), 'proxmenux-logo.png'), - ] - for p in candidates: - real = os.path.realpath(p) - if os.path.isfile(real): - return real - return '' - - def _build_mime_message(self, subject: str, body: str, severity: str, - data: Optional[Dict] = None): - """Build a MIMEMultipart email with embedded logo.""" - from email.mime.multipart import MIMEMultipart - from email.mime.text import MIMEText - from email.mime.image import MIMEImage - - msg = MIMEMultipart('related') - msg['Subject'] = subject - msg['From'] = self.from_address - msg['To'] = ', '.join(self.to_addresses) - - # Create alternative container (plain text + HTML) - alt = MIMEMultipart('alternative') - msg.attach(alt) - - # Plain text version - alt.attach(MIMEText(body, 'plain', 'utf-8')) - - # HTML version - html_body = self._format_html(subject, body, severity, data) - if html_body: - alt.attach(MIMEText(html_body, 'html', 'utf-8')) - - # Embed logo as CID attachment - logo_path = self._get_logo_path() - if logo_path: - try: - with open(logo_path, 'rb') as f: - logo_data = f.read() - logo_img = MIMEImage(logo_data, _subtype='png') - logo_img.add_header('Content-ID', '') - logo_img.add_header('Content-Disposition', 'inline', filename='proxmenux-logo.png') - msg.attach(logo_img) - except Exception: - pass # Logo not found -- email still works without it - - return msg - def _send_smtp(self, subject: str, body: str, severity: str, data: Optional[Dict] = None) -> Tuple[int, str]: import smtplib + from email.message import EmailMessage - msg = self._build_mime_message(subject, body, severity, data) + msg = EmailMessage() + msg['Subject'] = subject + msg['From'] = self.from_address + msg['To'] = ', '.join(self.to_addresses) + msg.set_content(body) + + # Add HTML alternative + html_body = self._format_html(subject, body, severity, data) + if html_body: + msg.add_alternative(html_body, subtype='html') server = None try: @@ -523,13 +479,22 @@ class EmailChannel(NotificationChannel): data: Optional[Dict] = None) -> Tuple[int, str]: import os import subprocess + from email.message import EmailMessage sendmail = '/usr/sbin/sendmail' if not os.path.exists(sendmail): return 0, 'sendmail not found at /usr/sbin/sendmail' - msg = self._build_mime_message(subject, body, severity, data) - msg.replace_header('From', self.from_address or 'proxmenux@localhost') + msg = EmailMessage() + msg['Subject'] = subject + msg['From'] = self.from_address or 'proxmenux@localhost' + msg['To'] = ', '.join(self.to_addresses) + msg.set_content(body) + + # Add HTML alternative + html_body = self._format_html(subject, body, severity, data) + if html_body: + msg.add_alternative(html_body, subtype='html') try: proc = subprocess.run( @@ -607,13 +572,13 @@ class EmailChannel(NotificationChannel): for label, value in detail_rows: if label: rows_html += f''' - {label} - {value} + {label} + {value} ''' else: # Full-width row (no label, just description text) rows_html += f''' - {value} + {value} ''' # ── Reason / details block (long text, displayed separately) ── @@ -621,9 +586,9 @@ class EmailChannel(NotificationChannel): reason_html = '' if reason and len(reason) > 80: reason_html = f''' -
-

Details

-

{html_mod.escape(reason)}

+
+

Details

+

{html_mod.escape(reason)}

''' # ── Clean subject for display (remove prefix if present) ── @@ -635,18 +600,15 @@ class EmailChannel(NotificationChannel): -
+
-
+
- -
- M - -

ProxMenux Monitor

-

{html_mod.escape(section_label)} Report

+
+

ProxMenux Monitor

+

{html_mod.escape(section_label)} Report

{sev['label'].upper()} @@ -665,17 +627,17 @@ class EmailChannel(NotificationChannel): - -
- Host: {html_mod.escape(data.get('hostname', ''))} + + Host: {html_mod.escape(data.get('hostname', ''))} + {html_mod.escape(ts)}
- +
{rows_html}
@@ -683,11 +645,11 @@ class EmailChannel(NotificationChannel): -
+
- - + +
ProxMenux Notification Serviceproxmenux.comProxMenux Notification Serviceproxmenux.com