Auto-commit local changes before build (2026-01-08 15:26:35) #70
@ -1 +1 @@
|
|||||||
v20260108-34-runchecks-popup-mail-body
|
v20260108-35-3cx-ssl-certificate-tracking
|
||||||
|
|||||||
@ -39,6 +39,18 @@ def parsers_overview():
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "3CX SSL certificate renewal",
|
||||||
|
"backup_software": "3CX",
|
||||||
|
"backup_types": ["SSL Certificate"],
|
||||||
|
"order": 11,
|
||||||
|
"enabled": True,
|
||||||
|
"match": {
|
||||||
|
"subject_regex": r"^3CX Notification:\\s*SSL Certificate Renewal\\s*-\\s*(.+)$",
|
||||||
|
},
|
||||||
|
"description": "Parses 3CX SSL certificate renewal notifications (informational) so they are tracked and included in reporting.",
|
||||||
|
"examples": [],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Veeam status mails",
|
"name": "Veeam status mails",
|
||||||
"backup_software": "Veeam",
|
"backup_software": "Veeam",
|
||||||
|
|||||||
@ -6,28 +6,61 @@ from typing import Dict, Tuple, List
|
|||||||
from ..models import MailMessage
|
from ..models import MailMessage
|
||||||
|
|
||||||
|
|
||||||
def try_parse_3cx(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
|
def _normalize_text(text: str) -> str:
|
||||||
"""Parse 3CX backup notification e-mails.
|
text = (text or "").replace("\r\n", "\n").replace("\r", "\n")
|
||||||
|
# Collapse excessive blank lines while keeping readability
|
||||||
|
text = re.sub(r"\n{4,}", "\n\n\n", text)
|
||||||
|
return text.strip()
|
||||||
|
|
||||||
Expected:
|
|
||||||
Subject: '3CX Notification: Backup Complete - <host>'
|
def try_parse_3cx(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
|
||||||
Body contains: 'Backup name: <file>'
|
"""Parse 3CX notification e-mails.
|
||||||
|
|
||||||
|
Supported:
|
||||||
|
- Backup Complete
|
||||||
|
Subject: '3CX Notification: Backup Complete - <host>'
|
||||||
|
Body contains: 'Backup name: <file>'
|
||||||
|
|
||||||
|
- SSL Certificate Renewal (informational)
|
||||||
|
Subject: '3CX Notification: SSL Certificate Renewal - <host>'
|
||||||
|
Body contains an informational message about the renewal.
|
||||||
"""
|
"""
|
||||||
subject = (msg.subject or "").strip()
|
subject = (msg.subject or "").strip()
|
||||||
if not subject:
|
if not subject:
|
||||||
return False, {}, []
|
return False, {}, []
|
||||||
|
|
||||||
m = re.match(r"^3CX Notification:\s*Backup Complete\s*-\s*(.+)$", subject, flags=re.IGNORECASE)
|
# Backup complete
|
||||||
if not m:
|
m_backup = re.match(r"^3CX Notification:\s*Backup Complete\s*-\s*(.+)$", subject, flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
# SSL certificate renewal (informational)
|
||||||
|
m_ssl = re.match(
|
||||||
|
r"^3CX Notification:\s*SSL Certificate Renewal\s*-\s*(.+)$",
|
||||||
|
subject,
|
||||||
|
flags=re.IGNORECASE,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not m_backup and not m_ssl:
|
||||||
return False, {}, []
|
return False, {}, []
|
||||||
|
|
||||||
job_name = m.group(1).strip()
|
job_name = (m_backup or m_ssl).group(1).strip()
|
||||||
|
|
||||||
body = (getattr(msg, "text_body", None) or getattr(msg, "body", None) or "")
|
body = (getattr(msg, "text_body", None) or getattr(msg, "body", None) or "")
|
||||||
# Some sources store plain text in html_body; fall back if needed.
|
|
||||||
if not body:
|
if not body:
|
||||||
body = getattr(msg, "html_body", None) or ""
|
body = getattr(msg, "html_body", None) or ""
|
||||||
|
body = _normalize_text(body)
|
||||||
|
|
||||||
|
# SSL certificate renewal: store as a tracked informational run
|
||||||
|
if m_ssl:
|
||||||
|
result = {
|
||||||
|
"backup_software": "3CX",
|
||||||
|
"backup_type": "SSL Certificate",
|
||||||
|
"job_name": job_name,
|
||||||
|
"overall_status": "Success",
|
||||||
|
"overall_message": body or None,
|
||||||
|
}
|
||||||
|
return True, result, []
|
||||||
|
|
||||||
|
# Backup complete
|
||||||
backup_file = None
|
backup_file = None
|
||||||
m_file = re.search(r"^\s*Backup\s+name\s*:\s*(.+?)\s*$", body, flags=re.IGNORECASE | re.MULTILINE)
|
m_file = re.search(r"^\s*Backup\s+name\s*:\s*(.+?)\s*$", body, flags=re.IGNORECASE | re.MULTILINE)
|
||||||
if m_file:
|
if m_file:
|
||||||
|
|||||||
@ -70,6 +70,15 @@
|
|||||||
- Added support to extract HTML content from stored EML when both html_body and text_body are blank (consistent with Inbox).
|
- Added support to extract HTML content from stored EML when both html_body and text_body are blank (consistent with Inbox).
|
||||||
- Updated Run Checks details API to return a safe HTML body for plain-text emails using <pre> wrapping.
|
- Updated Run Checks details API to return a safe HTML body for plain-text emails using <pre> wrapping.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v20260108-35-3cx-ssl-certificate-info-tracking
|
||||||
|
|
||||||
|
- Added parser support for 3CX SSL Certificate notifications.
|
||||||
|
- Classified these emails as Backup: 3CX, Type: SSL Certificate.
|
||||||
|
- Parsed the message content and displayed it in the Run Checks popup.
|
||||||
|
- Stored the message as a successful run so it could be tracked over time.
|
||||||
|
|
||||||
================================================================================================================================================
|
================================================================================================================================================
|
||||||
## v0.1.18
|
## v0.1.18
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user