From 71320dae661a8ca351128d917c894b0f8318eaf3 Mon Sep 17 00:00:00 2001
From: Guy Pyrzak
Date: Sun, 3 Oct 2010 13:44:42 -0700
Subject: Bug 65477: Send HTML bugmail r=mkanat, a=mkanat
---
Bugzilla/BugMail.pm | 60 ++++++++---
Bugzilla/Template.pm | 6 +-
template/en/default/email/bugmail-common.txt.html | 38 +++++++
template/en/default/email/bugmail-header.txt.tmpl | 47 ++++++++
template/en/default/email/bugmail.html.tmpl | 126 ++++++++++++++++++++++
template/en/default/email/bugmail.txt.tmpl | 81 ++++++++++++++
template/en/default/email/newchangedmail.txt.tmpl | 119 --------------------
7 files changed, 342 insertions(+), 135 deletions(-)
create mode 100644 template/en/default/email/bugmail-common.txt.html
create mode 100644 template/en/default/email/bugmail-header.txt.tmpl
create mode 100644 template/en/default/email/bugmail.html.tmpl
create mode 100644 template/en/default/email/bugmail.txt.tmpl
delete mode 100644 template/en/default/email/newchangedmail.txt.tmpl
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm
index 2ac575293..dfd7584ea 100644
--- a/Bugzilla/BugMail.pm
+++ b/Bugzilla/BugMail.pm
@@ -29,6 +29,7 @@
# Byron Jones
# Reed Loden
# Frédéric Buclin
+# Guy Pyrzak
use strict;
@@ -83,10 +84,9 @@ sub Send {
# can 'have' a role, if the person in that role has changed, or people are
# watching.
my @assignees = ($bug->assigned_to);
- my @qa_contacts = ($bug->qa_contact);
+ my @qa_contacts = $bug->qa_contact || ();
my @ccs = @{ $bug->cc_users };
-
# Include the people passed in as being in particular roles.
# This can include people who used to hold those roles.
# At this point, we don't care if there are duplicates in these arrays.
@@ -104,6 +104,7 @@ sub Send {
push(@ccs, Bugzilla::User->check($cc));
}
}
+ my %user_cache = map { $_->id => $_ } (@assignees, @qa_contacts, @ccs);
my @diffs;
if (!$start) {
@@ -123,7 +124,7 @@ sub Send {
blocker => $params->{blocker} });
}
else {
- push(@diffs, _get_diffs($bug, $end));
+ push(@diffs, _get_diffs($bug, $end, \%user_cache));
}
my $comments = $bug->comments({ after => $start, to => $end });
@@ -220,7 +221,8 @@ sub Send {
foreach my $user_id (keys %recipients) {
my %rels_which_want;
my $sent_mail = 0;
- my $user = new Bugzilla::User($user_id);
+ $user_cache{$user_id} ||= new Bugzilla::User($user_id);
+ my $user = $user_cache{$user_id};
# Deleted users must be excluded.
next unless $user;
@@ -353,19 +355,47 @@ sub sendMail {
new_comments => \@send_comments,
threadingmarker => build_thread_marker($bug->id, $user->id, !$bug->lastdiffed),
};
-
- my $msg;
- my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
- $template->process("email/newchangedmail.txt.tmpl", $vars, \$msg)
- || ThrowTemplateError($template->error());
-
+ my $msg = _generate_bugmail($user, $vars);
MessageToMTA($msg);
return 1;
}
+sub _generate_bugmail {
+ my ($user, $vars) = @_;
+ my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
+ my ($msg_text, $msg_html, $msg_header);
+
+ $template->process("email/bugmail-header.txt.tmpl", $vars, \$msg_header)
+ || ThrowTemplateError($template->error());
+ $template->process("email/bugmail.txt.tmpl", $vars, \$msg_text)
+ || ThrowTemplateError($template->error());
+ $template->process("email/bugmail.html.tmpl", $vars, \$msg_html)
+ || ThrowTemplateError($template->error());
+
+ my @parts = (
+ Email::MIME->create(
+ attributes => {
+ content_type => "text/plain",
+ },
+ body => $msg_text,
+ ),
+ Email::MIME->create(
+ attributes => {
+ content_type => "text/html",
+ },
+ body => $msg_html,
+ ),
+ );
+
+ my $email = new Email::MIME($msg_header);
+ $email->parts_set(\@parts);
+ $email->content_type_set('multipart/alternative');
+ return $email;
+}
+
sub _get_diffs {
- my ($bug, $end) = @_;
+ my ($bug, $end, $user_cache) = @_;
my $dbh = Bugzilla->dbh;
my @args = ($bug->id);
@@ -377,20 +407,20 @@ sub _get_diffs {
}
my $diffs = $dbh->selectall_arrayref(
- "SELECT profiles.login_name, profiles.realname, fielddefs.name AS field_name,
+ "SELECT fielddefs.name AS field_name,
bugs_activity.bug_when, bugs_activity.removed AS old,
bugs_activity.added AS new, bugs_activity.attach_id,
- bugs_activity.comment_id
+ bugs_activity.comment_id, bugs_activity.who
FROM bugs_activity
INNER JOIN fielddefs
ON fielddefs.id = bugs_activity.fieldid
- INNER JOIN profiles
- ON profiles.userid = bugs_activity.who
WHERE bugs_activity.bug_id = ?
$when_restriction
ORDER BY bugs_activity.bug_when", {Slice=>{}}, @args);
foreach my $diff (@$diffs) {
+ $user_cache->{$diff->{who}} ||= new Bugzilla::User($diff->{who});
+ $diff->{who} = $user_cache->{$diff->{who}};
if ($diff->{attach_id}) {
$diff->{isprivate} = $dbh->selectrow_array(
'SELECT isprivate FROM attachments WHERE attach_id = ?',
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index 5ff5482b2..ee4d6cba2 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -348,8 +348,12 @@ sub get_bug_link {
}
# Prevent code injection in the title.
$title = html_quote(clean_text($title));
-
my $linkval = "show_bug.cgi?id=" . $bug->id;
+
+ if ($options->{full_url}) {
+ $linkval = correct_urlbase() . $linkval;
+ }
+
if (defined $options->{comment_num}) {
$linkval .= "#c" . $options->{comment_num};
}
diff --git a/template/en/default/email/bugmail-common.txt.html b/template/en/default/email/bugmail-common.txt.html
new file mode 100644
index 000000000..b6cadaf11
--- /dev/null
+++ b/template/en/default/email/bugmail-common.txt.html
@@ -0,0 +1,38 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Guy Pyrzak
+ # Portions created by the Initial Developer are Copyright (C) 2010 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s): Guy Pyrzak
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% field_label = field_descs.${change.field_name} %]
+[% old_value = display_value(change.field_name, change.old) %]
+[% new_value = display_value(change.field_name, change.new) %]
+
+[% IF change.field_name == "estimated_time" || change.field_name == "remaining_time" %]
+ [% old_value = old_value FILTER format('%.2f') %]
+ [% new_value = new_value FILTER format('%.2f') %]
+[% END %]
+
+[% IF change.attach_id %]
+ [% field_label = field_label.replace('^(Attachment )?', "Attachment #${change.attach_id} ") %]
+[% END %]
+
+[% IF change.field_name == 'longdescs.isprivate' %]
+ [% field_label = field_label.replace('^(Comment )?', "Comment #${change.num} ") %]
+[% END %]
+
\ No newline at end of file
diff --git a/template/en/default/email/bugmail-header.txt.tmpl b/template/en/default/email/bugmail-header.txt.tmpl
new file mode 100644
index 000000000..c2b4ea4f5
--- /dev/null
+++ b/template/en/default/email/bugmail-header.txt.tmpl
@@ -0,0 +1,47 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Netscape Communications
+ # Corporation. Portions created by Netscape are
+ # Copyright (C) 1998 Netscape Communications Corporation. All
+ # Rights Reserved.
+ #
+ # Contributor(s): André Batosti
+ # Frédéric Buclin
+ # Guy Pyrzak
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+[% PROCESS "global/reason-descs.none.tmpl" %]
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+
+From: [% Param('mailfrom') %]
+To: [% to_user.email %]
+Subject: [[% terms.Bug %] [%+ bug.id %]] [% 'New: ' IF isnew %][%+ bug.short_desc %]
+Date: [% delta_ts || bug.delta_ts FILTER time("%a, %d %b %Y %T %z", to_user.timezone) %]
+X-Bugzilla-Reason: [% reasonsheader %]
+X-Bugzilla-Type: [% isnew ? 'new' : 'changed' %]
+X-Bugzilla-Watch-Reason: [% reasonswatchheader %]
+[% IF Param('useclassification') %]
+X-Bugzilla-Classification: [% bug.classification %]
+[% END %]
+X-Bugzilla-Product: [% bug.product %]
+X-Bugzilla-Component: [% bug.component %]
+X-Bugzilla-Keywords: [% bug.keywords %]
+X-Bugzilla-Severity: [% bug.bug_severity %]
+X-Bugzilla-Who: [% changer.login %]
+X-Bugzilla-Status: [% bug.bug_status %]
+X-Bugzilla-Priority: [% bug.priority %]
+X-Bugzilla-Assigned-To: [% bug.assigned_to.login %]
+X-Bugzilla-Target-Milestone: [% bug.target_milestone %]
+X-Bugzilla-Changed-Fields: [% changedfields.join(" ") %]
+[%+ threadingmarker %]
diff --git a/template/en/default/email/bugmail.html.tmpl b/template/en/default/email/bugmail.html.tmpl
new file mode 100644
index 000000000..888d47bc4
--- /dev/null
+++ b/template/en/default/email/bugmail.html.tmpl
@@ -0,0 +1,126 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Guy Pyrzak
+ # Portions created by the Initial Developer are Copyright (C) 2010 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s): Guy Pyrzak
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+[% PROCESS "global/reason-descs.none.tmpl" %]
+
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+
+
+
+
+
+ [% PROCESS generate_diffs %]
+
+ [% FOREACH comment = new_comments.reverse %]
+
+ [% IF comment.count %]
+
[% "Comment # ${comment.count}" FILTER bug_link( bug,
+ {comment_num => comment.count, full_url => 1}) FILTER none %]
+ from [% INCLUDE global/user.html.tmpl who = comment.author %]
+ [% END %]
+
[% comment.body_full({ wrap => 1 }) FILTER html %]
+
+ [% END %]
+
+
+
+ Configure [% terms.bug %]mail
+
+
+
+ You are receiving this mail because:
+
+
+ [% FOREACH reason = reasons %]
+ [% IF reason_descs.$reason %]
+ - [% reason_descs.$reason FILTER html %]
+ [% END %]
+ [% END %]
+ [% FOREACH reason = reasons_watch %]
+ [% IF watch_reason_descs.$reason %]
+ - [% watch_reason_descs.$reason FILTER html %]
+ [% END %]
+ [% END %]
+
+
+
+
+[% BLOCK generate_diffs %]
+
+ [% "${terms.Bug} ${bug.id}" FILTER bug_link(bug, full_url => 1) FILTER none %]
+
+ [% last_changer = "" %]
+
+ [% FOREACH change = diffs %]
+ [% IF !isnew && change.who.login != last_changer %]
+ [% last_changer = change.who.login %]
+ [% IF change.blocker %]
+
+
+ [% "${terms.Bug} ${bug.id}" FILTER bug_link(bug, full_url => 1) FILTER none %] depends
+ on [% "${terms.bug} ${change.blocker.id}"
+ FILTER bug_link(change.blocker, full_url => 1) FILTER none %],
+ which changed state.
+ |
+
+ [% ELSE %]
+
+
+ [% INCLUDE global/user.html.tmpl who = change.who %]
+ changed:
+ |
+
+ [% END %]
+
+ What |
+ Removed |
+ Added |
+
+ [% END %]
+
+ [% PROCESS "email/bugmail-common.txt.html" %]
+
+ [% IF isnew %]
+
+ [% field_label FILTER html %] |
+ [% new_value FILTER html %] |
+
+ [% ELSE %]
+
+ [% field_label FILTER html %] |
+
+ [% IF old_value %]
+ [% old_value FILTER html %]
+ [% ELSE %]
+
+ [% END%]
+ |
+
+ [% IF new_value %]
+ [% new_value FILTER html %]
+ [% ELSE %]
+
+ [% END%]
+ |
+
+ [% END %]
+ [% END %]
+
+[% END %]
\ No newline at end of file
diff --git a/template/en/default/email/bugmail.txt.tmpl b/template/en/default/email/bugmail.txt.tmpl
new file mode 100644
index 000000000..31efaba33
--- /dev/null
+++ b/template/en/default/email/bugmail.txt.tmpl
@@ -0,0 +1,81 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Netscape Communications
+ # Corporation. Portions created by Netscape are
+ # Copyright (C) 1998 Netscape Communications Corporation. All
+ # Rights Reserved.
+ #
+ # Contributor(s): André Batosti
+ # Frédéric Buclin
+ # Guy Pyrzak
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+[% PROCESS "global/reason-descs.none.tmpl" %]
+
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+
+[%+ PROCESS generate_diffs -%]
+
+[% FOREACH comment = new_comments %]
+
+[%- IF comment.count %]
+--- Comment #[% comment.count %] from [% comment.author.identity %] ---
+[% END %]
+[%+ comment.body_full({ is_bugmail => 1, wrap => 1 }) %]
+[% END %]
+
+-- [%# Protect the trailing space of the signature marker %]
+Configure [% terms.bug %]mail: [% urlbase %]userprefs.cgi?tab=email
+------- You are receiving this mail because: -------
+[% SET reason_lines = [] %]
+[% FOREACH reason = reasons %]
+ [% reason_lines.push(reason_descs.$reason) IF reason_descs.$reason %]
+[% END %]
+[% FOREACH reason = reasons_watch %]
+ [% reason_lines.push(watch_reason_descs.$reason)
+ IF watch_reason_descs.$reason %]
+[% END %]
+[%+ reason_lines.join("\n") %]
+
+[% BLOCK generate_diffs %]
+ [% urlbase %]show_bug.cgi?id=[% bug.id %]
+
+[%+ last_changer = "" %]
+ [% FOREACH change = diffs %]
+ [% IF !isnew && change.who.login != last_changer %]
+ [% last_changer = change.who.login %]
+ [% IF change.blocker %]
+ [% terms.Bug %] [%+ bug.id %] depends on [% terms.bug %] [%+ change.blocker.id %], which changed state.
+
+[%+ terms.Bug %] [%+ change.blocker.id %] Summary: [% change.blocker.short_desc %]
+[%+ urlbase %]show_bug.cgi?id=[% change.blocker.id %]
+ [% ELSE %]
+ [%~ IF change.who.name %]
+ [% change.who.name _ " <" _ change.who.login _ ">" %]
+ [% ELSE %]
+ [% change.who.login %]
+ [% END %] changed:
+ [% END %]
+
+ What |Removed |Added
+----------------------------------------------------------------------------
+[%+ END %][%# End of IF. This indentation is intentional! ~%]
+ [% PROCESS "email/bugmail-common.txt.html"%]
+ [%~ IF isnew %]
+ [% format_columns(2, field_label _ ":", new_value) -%]
+ [% ELSE %]
+ [% format_columns(3, field_label, old_value, new_value) -%]
+ [% END %]
+ [% END -%]
+[% END %]
diff --git a/template/en/default/email/newchangedmail.txt.tmpl b/template/en/default/email/newchangedmail.txt.tmpl
deleted file mode 100644
index de4a248e3..000000000
--- a/template/en/default/email/newchangedmail.txt.tmpl
+++ /dev/null
@@ -1,119 +0,0 @@
-[%# The contents of this file are subject to the Mozilla Public
- # License Version 1.1 (the "License"); you may not use this file
- # except in compliance with the License. You may obtain a copy of
- # the License at http://www.mozilla.org/MPL/
- #
- # Software distributed under the License is distributed on an "AS
- # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- # implied. See the License for the specific language governing
- # rights and limitations under the License.
- #
- # The Original Code is the Bugzilla Bug Tracking System.
- #
- # The Initial Developer of the Original Code is Netscape Communications
- # Corporation. Portions created by Netscape are
- # Copyright (C) 1998 Netscape Communications Corporation. All
- # Rights Reserved.
- #
- # Contributor(s): André Batosti
- # Frédéric Buclin
- #%]
-
-[% PROCESS "global/field-descs.none.tmpl" %]
-[% PROCESS "global/reason-descs.none.tmpl" %]
-
-[% isnew = bug.lastdiffed ? 0 : 1 %]
-
-From: [% Param('mailfrom') %]
-To: [% to_user.email %]
-Subject: [[% terms.Bug %] [%+ bug.id %]] [% 'New: ' IF isnew %][%+ bug.short_desc %]
-Date: [% delta_ts || bug.delta_ts FILTER time("%a, %d %b %Y %T %z", to_user.timezone) %]
-X-Bugzilla-Reason: [% reasonsheader %]
-X-Bugzilla-Type: [% isnew ? 'new' : 'changed' %]
-X-Bugzilla-Watch-Reason: [% reasonswatchheader %]
-[% IF Param('useclassification') %]
-X-Bugzilla-Classification: [% bug.classification %]
-[% END %]
-X-Bugzilla-Product: [% bug.product %]
-X-Bugzilla-Component: [% bug.component %]
-X-Bugzilla-Keywords: [% bug.keywords %]
-X-Bugzilla-Severity: [% bug.bug_severity %]
-X-Bugzilla-Who: [% changer.login %]
-X-Bugzilla-Status: [% bug.bug_status %]
-X-Bugzilla-Priority: [% bug.priority %]
-X-Bugzilla-Assigned-To: [% bug.assigned_to.login %]
-X-Bugzilla-Target-Milestone: [% bug.target_milestone %]
-X-Bugzilla-Changed-Fields: [% changedfields.join(" ") %]
-[%+ threadingmarker %]
-
-[%+ PROCESS generate_diffs -%]
-
-[% FOREACH comment = new_comments %]
-
-[%- IF comment.count %]
---- Comment #[% comment.count %] from [% comment.author.identity %] ---
-[% END %]
-[%+ comment.body_full({ is_bugmail => 1, wrap => 1 }) %]
-[% END %]
-
--- [%# Protect the trailing space of the signature marker %]
-Configure [% terms.bug %]mail: [% urlbase %]userprefs.cgi?tab=email
-------- You are receiving this mail because: -------
-[% SET reason_lines = [] %]
-[% FOREACH reason = reasons %]
- [% reason_lines.push(reason_descs.$reason) IF reason_descs.$reason %]
-[% END %]
-[% FOREACH reason = reasons_watch %]
- [% reason_lines.push(watch_reason_descs.$reason)
- IF watch_reason_descs.$reason %]
-[% END %]
-[%+ reason_lines.join("\n") %]
-
-[% BLOCK generate_diffs %]
- [% urlbase %]show_bug.cgi?id=[% bug.id %]
-
-[%+ last_changer = "" %]
- [% FOREACH change = diffs %]
- [% IF !isnew && change.login_name != last_changer %]
- [% last_changer = change.login_name %]
- [% IF change.blocker %]
- [% terms.Bug %] [%+ bug.id %] depends on [% terms.bug %] [%+ change.blocker.id %], which changed state.
-
-[%+ terms.Bug %] [%+ change.blocker.id %] Summary: [% change.blocker.short_desc %]
-[%+ urlbase %]show_bug.cgi?id=[% change.blocker.id %]
- [% ELSE %]
- [%~ IF change.realname %]
- [% change.realname _ " <" _ change.login_name _ ">" %]
- [% ELSE %]
- [% change.login_name %]
- [% END %] changed:
- [% END %]
-
- What |Removed |Added
-----------------------------------------------------------------------------
-[%+ END %][%# End of IF. This indentation is intentional! ~%]
-
- [% field_label = field_descs.${change.field_name} %]
- [% old_value = display_value(change.field_name, change.old) %]
- [% new_value = display_value(change.field_name, change.new) %]
-
- [%~ IF change.field_name == "estimated_time" || change.field_name == "remaining_time" %]
- [% old_value = old_value FILTER format('%.2f') %]
- [% new_value = new_value FILTER format('%.2f') %]
- [% END %]
-
- [%~ IF change.attach_id %]
- [% field_label = field_label.replace('^(Attachment )?', "Attachment #${change.attach_id} ") %]
- [% END %]
-
- [%~ IF change.field_name == 'longdescs.isprivate' %]
- [% field_label = field_label.replace('^(Comment )?', "Comment #${change.num} ") %]
- [% END %]
-
- [%~ IF isnew %]
- [% format_columns(2, field_label _ ":", new_value) -%]
- [% ELSE %]
- [% format_columns(3, field_label, old_value, new_value) -%]
- [% END %]
- [% END -%]
-[% END %]
--
cgit v1.2.3-24-g4f1b