Merge branch 'v20260209-07-synology-drive-health-parser' into main

This commit is contained in:
Ivo Oskamp 2026-02-09 17:26:04 +01:00
commit 49f24595c3
4 changed files with 103 additions and 1 deletions

View File

@ -1 +1 @@
v20260209-06-synology-firmware-update-parser v20260209-07-synology-drive-health-parser

View File

@ -113,6 +113,32 @@ PARSER_DEFINITIONS = [
}, },
}, },
}, },
{
"name": "synology_drive_health",
"backup_software": "Synology",
"backup_types": ["Health Report"],
"order": 237,
"enabled": True,
"match": {
"subject_contains_any": ["schijfintegriteitsrapport", "Drive Health Report"],
"body_contains_any": ["health of the drives", "integriteitsrapport van de schijven"],
},
"description": "Parses Synology monthly drive health reports (informational; excluded from reporting and missing logic).",
"example": {
"subject": "[NAS-HOSTNAME] Monthly Drive Health Report on NAS-HOSTNAME - Healthy",
"from_address": "nas@example.local",
"body_snippet": "The following is your monthly report regarding the health of the drives on NAS-HOSTNAME. No problem detected with the drives in DSM.",
"parsed_result": {
"backup_software": "Synology",
"backup_type": "Health Report",
"job_name": "Monthly Drive Health",
"overall_status": "Success",
"objects": [
{"name": "NAS-HOSTNAME", "status": "Success"}
],
},
},
},
{ {
"name": "veeam_replication_job", "name": "veeam_replication_job",
"backup_software": "Veeam", "backup_software": "Veeam",

View File

@ -73,6 +73,75 @@ def _parse_synology_dsm_update_cancelled(subject: str, text: str) -> Tuple[bool,
return True, result, objects return True, result, objects
# --- Synology Drive Health Report (informational, excluded from reporting) ---
DRIVE_HEALTH_PATTERNS = [
"schijfintegriteitsrapport",
"Drive Health Report",
"Monthly Drive Health",
"health of the drives",
"integriteitsrapport van de schijven",
]
_DRIVE_HEALTH_SUBJECT_RE = re.compile(
r"\b(?:schijfintegriteitsrapport\s+over|Drive\s+Health\s+Report\s+on)\s+(?P<host>[A-Za-z0-9._-]+)",
re.I,
)
_DRIVE_HEALTH_FROM_RE = re.compile(r"\b(?:Van|From)\s+(?P<host>[A-Za-z0-9._-]+)\b", re.I)
_DRIVE_HEALTH_STATUS_HEALTHY_RE = re.compile(
r"\b(?:Gezond|Healthy|geen\s+problemen\s+gedetecteerd|No\s+problem\s+detected)\b",
re.I,
)
def _is_synology_drive_health(subject: str, text: str) -> bool:
haystack = f"{subject}\n{text}".lower()
return any(p.lower() in haystack for p in DRIVE_HEALTH_PATTERNS)
def _parse_synology_drive_health(subject: str, text: str) -> Tuple[bool, Dict, List[Dict]]:
haystack = f"{subject}\n{text}"
host = ""
# Try to extract hostname from subject first
m = _DRIVE_HEALTH_SUBJECT_RE.search(subject or "")
if m:
host = (m.group("host") or "").strip()
# Fallback: extract from body "Van/From NAS-NAME"
if not host:
m = _DRIVE_HEALTH_FROM_RE.search(text or "")
if m:
host = (m.group("host") or "").strip()
# Determine status based on health indicators
overall_status = "Success"
overall_message = "Healthy"
if not _DRIVE_HEALTH_STATUS_HEALTHY_RE.search(haystack):
# If we don't find healthy indicators, mark as Warning
overall_status = "Warning"
overall_message = "Drive health issue detected"
# Informational job: show in Run Checks, but do not participate in schedules / reporting.
result: Dict = {
"backup_software": "Synology",
"backup_type": "Health Report",
"job_name": "Monthly Drive Health",
"overall_status": overall_status,
"overall_message": overall_message + (f" ({host})" if host else ""),
}
objects: List[Dict] = []
if host:
objects.append({"name": host, "status": overall_status})
return True, result, objects
_BR_RE = re.compile(r"<\s*br\s*/?\s*>", re.I) _BR_RE = re.compile(r"<\s*br\s*/?\s*>", re.I)
_TAG_RE = re.compile(r"<[^>]+>") _TAG_RE = re.compile(r"<[^>]+>")
_WS_RE = re.compile(r"[\t\r\f\v ]+") _WS_RE = re.compile(r"[\t\r\f\v ]+")
@ -509,6 +578,12 @@ def try_parse_synology(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
if ok: if ok:
return True, result, objects return True, result, objects
# Drive Health Report (informational; no schedule; excluded from reporting)
if _is_synology_drive_health(subject, text):
ok, result, objects = _parse_synology_drive_health(subject, text)
if ok:
return True, result, objects
# DSM Account Protection (informational; no schedule) # DSM Account Protection (informational; no schedule)
if _is_synology_account_protection(subject, text): if _is_synology_account_protection(subject, text):
ok, result, objects = _parse_account_protection(subject, text) ok, result, objects = _parse_account_protection(subject, text)

View File

@ -5,6 +5,7 @@ This file documents all changes made to this project via Claude Code.
## [2026-02-09] ## [2026-02-09]
### Added ### Added
- Added parser for Synology monthly drive health reports (backup software: Synology, backup type: Health Report, job name: Monthly Drive Health, informational only, no schedule learning) with support for both Dutch and English notifications ("schijfintegriteitsrapport"/"Drive Health Report") and automatic status detection (Healthy/Gezond → Success, problems → Warning)
- Added "Cleanup orphaned jobs" maintenance option in Settings → Maintenance to delete jobs without valid customer links and their associated emails/runs permanently from database (useful when customers are removed) - Added "Cleanup orphaned jobs" maintenance option in Settings → Maintenance to delete jobs without valid customer links and their associated emails/runs permanently from database (useful when customers are removed)
- Added "Preview orphaned jobs" button to show detailed list of jobs to be deleted with run/email counts before confirming deletion (verification step for safety) - Added "Preview orphaned jobs" button to show detailed list of jobs to be deleted with run/email counts before confirming deletion (verification step for safety)
- Added "Generate test emails" feature in Settings → Maintenance with three separate buttons to create fixed test email sets (success/warning/error) in inbox for testing parsers and maintenance operations (each set contains exactly 3 Veeam Backup Job emails with the same job name "Test-Backup-Job" and different dates/objects/statuses for reproducible testing and proper status flow testing) - Added "Generate test emails" feature in Settings → Maintenance with three separate buttons to create fixed test email sets (success/warning/error) in inbox for testing parsers and maintenance operations (each set contains exactly 3 Veeam Backup Job emails with the same job name "Test-Backup-Job" and different dates/objects/statuses for reproducible testing and proper status flow testing)