Auto-commit local changes before build (2026-01-06 10:11:59) #37

Merged
ivooskamp merged 1 commits from v20260106-03-veeam-full-job-name-merge into main 2026-01-13 11:06:25 +01:00
3 changed files with 28 additions and 2 deletions
Showing only changes of commit 13c4c5950d - Show all commits

View File

@ -1 +1 @@
v20260106-02-inbox-bulk-delete v20260106-03-veeam-full-job-name-merge

View File

@ -711,6 +711,20 @@ def _strip_m365_combined_suffix(job_name: Optional[str]) -> Optional[str]:
return cleaned or None return cleaned or None
def _strip_full_suffix(job_name: Optional[str]) -> Optional[str]:
"""Remove a trailing "(Full)" suffix from a Veeam job name.
Some Veeam installations create separate emails where the job name is
suffixed with "(Full)" (e.g. "Backup VM DC01 (Full)"). Those should be
treated as the same logical job as the non-suffixed name.
"""
if not job_name:
return job_name
cleaned = re.sub(r"\s*\(\s*Full\s*\)\s*$", "", job_name, flags=re.IGNORECASE).strip()
return cleaned or None
def try_parse_veeam(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]: def try_parse_veeam(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
"""Try to parse a Veeam backup report mail. """Try to parse a Veeam backup report mail.
@ -866,6 +880,10 @@ def try_parse_veeam(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
# Do not let retry counters create distinct job names. # Do not let retry counters create distinct job names.
job_name = _strip_retry_suffix(job_name) job_name = _strip_retry_suffix(job_name)
# Veeam can append a "(Full)" suffix to the job name in some reports.
# Strip it so full/non-full mails map to the same logical job.
job_name = _strip_full_suffix(job_name)
# Veeam Backup for Microsoft 365 reports can add a "(Combined)" suffix. # Veeam Backup for Microsoft 365 reports can add a "(Combined)" suffix.
# Strip it so combined/non-combined mails map to the same job. # Strip it so combined/non-combined mails map to the same job.
if (backup_type or "") == "Veeam Backup for Microsoft 365": if (backup_type or "") == "Veeam Backup for Microsoft 365":
@ -885,7 +903,7 @@ def try_parse_veeam(msg: MailMessage) -> Tuple[bool, Dict, List[Dict]]:
result: Dict = { result: Dict = {
"backup_software": "Veeam", "backup_software": "Veeam",
"backup_type": backup_type, "backup_type": backup_type,
"job_name": _strip_retry_suffix(job_name), "job_name": job_name,
"overall_status": status_word, "overall_status": status_word,
} }

View File

@ -12,6 +12,14 @@
- Added a “Delete selected” bulk action that soft-deletes selected inbox messages (moves them to Deleted), including select-all support and a selected-count indicator. - Added a “Delete selected” bulk action that soft-deletes selected inbox messages (moves them to Deleted), including select-all support and a selected-count indicator.
- Implemented a new POST API endpoint to bulk delete inbox messages with proper validation, skip/missing counts, and admin event logging. - Implemented a new POST API endpoint to bulk delete inbox messages with proper validation, skip/missing counts, and admin event logging.
---
## v20260106-03-veeam-full-job-name-merge
- Updated Veeam parser to normalize job names.
- Jobs containing "(Full)" are now treated as the same job as those without "(Full)".
- This prevents duplicate job entries and ensures correct aggregation and reporting.
================================================================================================================================================ ================================================================================================================================================
## v0.1.16 ## v0.1.16