From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 799F21FF168 for ; Mon, 14 Oct 2024 20:05:41 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 1BD6E9B96; Mon, 14 Oct 2024 20:06:11 +0200 (CEST) From: Stoiko Ivanov To: pmg-devel@lists.proxmox.com Date: Mon, 14 Oct 2024 20:05:47 +0200 Message-Id: <20241014180549.27671-2-s.ivanov@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241014180549.27671-1-s.ivanov@proxmox.com> References: <20241014180549.27671-1-s.ivanov@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.070 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pmg-devel] [PATCH pmg-api v4 1/2] utils: allow specifying plain and/or html for finalize_report() X-BeenThere: pmg-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Mail Gateway development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pmg-devel-bounces@lists.proxmox.com Sender: "pmg-devel" To support both plain-text and HTML emails when sending reports, PMG::Utils::finalize_report() now checks if a template has a plain-text equivalent - (`.plain.tt` instead of `.tt` as suffix). if either template file is empty (or non-existant) the corresponding part is simply left-out. This should enable admins top optionally send plain-text only reports, or multipart mails with both text/plain and text/html, while not changing the current behavior Co-developed-by: Christoph Heiss Signed-off-by: Stoiko Ivanov --- src/PMG/Backup.pm | 2 +- src/PMG/CLI/pmgqm.pm | 6 ++-- src/PMG/CLI/pmgreport.pm | 2 +- src/PMG/Utils.pm | 77 +++++++++++++++++++++++++++++++++------- 4 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/PMG/Backup.pm b/src/PMG/Backup.pm index ab7e628..c820d6b 100644 --- a/src/PMG/Backup.pm +++ b/src/PMG/Backup.pm @@ -418,7 +418,7 @@ sub send_backup_notification { my $tt = PMG::Config::get_template_toolkit(); my $mailfrom = "Proxmox Mail Gateway "; - PMG::Utils::finalize_report($tt, 'backup-notification.tt', $vars, $mailfrom, $email); + PMG::Utils::finalize_report($tt, 'backup-notification', $vars, $mailfrom, $email); } diff --git a/src/PMG/CLI/pmgqm.pm b/src/PMG/CLI/pmgqm.pm index 987ddc9..7016161 100755 --- a/src/PMG/CLI/pmgqm.pm +++ b/src/PMG/CLI/pmgqm.pm @@ -261,14 +261,14 @@ __PACKAGE__->register_method ({ my $domains = PVE::INotify::read_file('domains'); my $domainregex = PMG::Utils::domain_regex([keys %$domains]); - my $template = "spamreport-${reportstyle}.tt"; + my $template = "spamreport-${reportstyle}"; my $found = 0; foreach my $path (@$PMG::Config::tt_include_path) { - if (-f "$path/$template") { $found = 1; last; } + if (-f "$path/$template.tt") { $found = 1; last; } } if (!$found) { warn "unable to find template '$template' - using default\n"; - $template = "spamreport-verbose.tt"; + $template = "spamreport-verbose"; } my $sth = $dbh->prepare( diff --git a/src/PMG/CLI/pmgreport.pm b/src/PMG/CLI/pmgreport.pm index 3403e44..99adfd2 100644 --- a/src/PMG/CLI/pmgreport.pm +++ b/src/PMG/CLI/pmgreport.pm @@ -359,7 +359,7 @@ __PACKAGE__->register_method ({ } my $mailfrom = "Proxmox Mail Gateway "; - PMG::Utils::finalize_report($tt, 'pmgreport.tt', $vars, $mailfrom, $email, $param->{debug}); + PMG::Utils::finalize_report($tt, 'pmgreport', $vars, $mailfrom, $email, $param->{debug}); return undef; }}); diff --git a/src/PMG/Utils.pm b/src/PMG/Utils.pm index 5d9ded4..9069f81 100644 --- a/src/PMG/Utils.pm +++ b/src/PMG/Utils.pm @@ -1248,32 +1248,85 @@ sub format_uptime { } } +# Sends a report to the given receiver, building the body from templates. +# if either html or plain template is empty that part is not added. +# The subject of the mail is derived from the title tag of the HTML template, with a fallback to +# the value after `subject:` on a line of its own in the plaintext template. +# +# The resulting mail is then reinjected with an empty envelope sender. +# +# Parameters: +# * `tt` - The template toolkit instance to use +# * `template_base` - base name of the template. suffixed with 'tt' yields the HTML template. +# suffixed with 'plain.tt' yields the plain text template +# * `data` - Template variables to pass to the template processor +# * `mailfrom` - Sender address +# * `receiver` - Recipient address +# * `debug` - whether to enable debug mode, resulting mail is only printed, not reinjected sub finalize_report { - my ($tt, $template, $data, $mailfrom, $receiver, $debug) = @_; + my ($tt, $template_base, $data, $mailfrom, $receiver, $debug) = @_; + + my $html_template; + my $html_path; + for my $path (@$PMG::Config::tt_include_path) { + if (-f "$path/$template_base.tt") { + $html_template = "$template_base.tt"; + $html_path = "$path/$template_base.tt"; + last; + } + } my $html = ''; - $tt->process($template, $data, \$html) || - die $tt->error() . "\n"; - + if (defined($html_template) && -s $html_path) { + $tt->process($html_template, $data, \$html) || + die $tt->error() . "\n"; + } my $title; if ($html =~ m|^\s*(.*)|m) { $title = $1; - } else { - die "unable to extract template title\n"; } + my $plain_template; + my $plain_path; + for my $path (@$PMG::Config::tt_include_path) { + if (-f "$path/$template_base.plain.tt") { + $plain_template = "$template_base.plain.tt"; + $plain_path = "$path/$template_base.plain.tt"; + last; + } + } + + my $plaintext = ''; + if (defined($plain_template) && -s $plain_path) { + $tt->process($plain_template, $data, \$plaintext) || + die $tt->error() . "\n"; + } + + if ($plaintext =~ s/^subject: (.+)$//m) { + $title //= $1; + } + + die "unable to extract template title\n" if !defined($title); + my $top = MIME::Entity->build( - Type => "multipart/related", + Type => ($html && $plaintext) ? 'multipart/alternative' : 'multipart/related', To => $data->{pmail_raw}, From => $mailfrom, Subject => bencode_header(decode_entities($title))); - $top->attach( - Data => $html, - Type => "text/html", - Encoding => $debug ? 'binary' : 'quoted-printable'); - + if ($html) { + $top->attach( + Data => $html, + Type => "text/html", + Encoding => $debug ? 'binary' : 'quoted-printable'); + } + if ($plaintext) { + $top->attach( + Data => $plaintext, + Type => 'text/plain; charset=utf-8', + Encoding => '8-bit'); + } if ($debug) { $top->print(); return; -- 2.39.5 _______________________________________________ pmg-devel mailing list pmg-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pmg-devel