Commit c1d01f36 authored by Frédéric Buclin's avatar Frédéric Buclin

Bug 466968: Remove hardcoded strings from BugMail.pm, and refactor it so that…

Bug 466968: Remove hardcoded strings from BugMail.pm, and refactor it so that bugmails are 100% localizable r/a=mkanat
parent c3347fb7
......@@ -61,6 +61,11 @@ use Scalar::Util qw(blessed);
use base qw(Template);
use constant FORMAT_TRIPLE => '%19s|%-28s|%-28s';
use constant FORMAT_3_SIZE => [19,28,28];
use constant FORMAT_DOUBLE => '%19s %-55s';
use constant FORMAT_2_SIZE => [19,55];
# Convert the constants in the Bugzilla::Constants module into a hash we can
# pass to the template object for reflection into its "constants" namespace
# (which is like its "variables" namespace, but for constants). To do so, we
......@@ -352,6 +357,36 @@ sub get_bug_link {
return qq{$pre<a href="$linkval" title="$title">$link_text</a>$post};
}
# We use this instead of format because format doesn't deal well with
# multi-byte languages.
sub multiline_sprintf {
my ($format, $args, $sizes) = @_;
my @parts;
my @my_sizes = @$sizes; # Copy this so we don't modify the input array.
foreach my $string (@$args) {
my $size = shift @my_sizes;
my @pieces = split("\n", wrap_hard($string, $size));
push(@parts, \@pieces);
}
my $formatted;
while (1) {
# Get the first item of each part.
my @line = map { shift @$_ } @parts;
# If they're all undef, we're done.
last if !grep { defined $_ } @line;
# Make any single undef item into ''
@line = map { defined $_ ? $_ : '' } @line;
# And append a formatted line
$formatted .= sprintf($format, @line);
# Remove trailing spaces, or they become lots of =20's in
# quoted-printable emails.
$formatted =~ s/\s+$//;
$formatted .= "\n";
}
return $formatted;
}
#####################
# Header Generation #
#####################
......@@ -833,6 +868,14 @@ sub create {
# Function to create date strings
'time2str' => \&Date::Format::time2str,
# Fixed size column formatting for bugmail.
'format_columns' => sub {
my $cols = shift;
my $format = ($cols == 3) ? FORMAT_TRIPLE : FORMAT_DOUBLE;
my $col_size = ($cols == 3) ? FORMAT_3_SIZE : FORMAT_2_SIZE;
return multiline_sprintf($format, \@_, $col_size);
},
# Generic linear search function
'lsearch' => sub {
my ($array, $item) = @_;
......
......@@ -1492,35 +1492,33 @@ sub match_field {
}
# Changes in some fields automatically trigger events. The 'field names' are
# from the fielddefs table. We really should be using proper field names
# throughout.
# Changes in some fields automatically trigger events. The field names are
# from the fielddefs table.
our %names_to_events = (
'Resolution' => EVT_OPENED_CLOSED,
'Keywords' => EVT_KEYWORD,
'CC' => EVT_CC,
'Severity' => EVT_PROJ_MANAGEMENT,
'Priority' => EVT_PROJ_MANAGEMENT,
'Status' => EVT_PROJ_MANAGEMENT,
'Target Milestone' => EVT_PROJ_MANAGEMENT,
'Attachment description' => EVT_ATTACHMENT_DATA,
'Attachment mime type' => EVT_ATTACHMENT_DATA,
'Attachment is patch' => EVT_ATTACHMENT_DATA,
'Depends on' => EVT_DEPEND_BLOCK,
'Blocks' => EVT_DEPEND_BLOCK);
'resolution' => EVT_OPENED_CLOSED,
'keywords' => EVT_KEYWORD,
'cc' => EVT_CC,
'bug_severity' => EVT_PROJ_MANAGEMENT,
'priority' => EVT_PROJ_MANAGEMENT,
'bug_status' => EVT_PROJ_MANAGEMENT,
'target_milestone' => EVT_PROJ_MANAGEMENT,
'attachments.description' => EVT_ATTACHMENT_DATA,
'attachments.mimetype' => EVT_ATTACHMENT_DATA,
'attachments.ispatch' => EVT_ATTACHMENT_DATA,
'dependson' => EVT_DEPEND_BLOCK,
'blocked' => EVT_DEPEND_BLOCK);
# Returns true if the user wants mail for a given bug change.
# Note: the "+" signs before the constants suppress bareword quoting.
sub wants_bug_mail {
my $self = shift;
my ($bug_id, $relationship, $fieldDiffs, $comments, $dep_mail,
$changer, $bug_is_new) = @_;
my ($bug, $relationship, $fieldDiffs, $comments, $dep_mail, $changer) = @_;
# Make a list of the events which have happened during this bug change,
# from the point of view of this user.
my %events;
foreach my $ref (@$fieldDiffs) {
my ($who, $whoname, $fieldName, $when, $old, $new) = @$ref;
foreach my $change (@$fieldDiffs) {
my $fieldName = $change->{field_name};
# A change to any of the above fields sets the corresponding event
if (defined($names_to_events{$fieldName})) {
$events{$names_to_events{$fieldName}} = 1;
......@@ -1532,16 +1530,16 @@ sub wants_bug_mail {
# If the user is in a particular role and the value of that role
# changed, we need the ADDED_REMOVED event.
if (($fieldName eq "AssignedTo" && $relationship == REL_ASSIGNEE) ||
($fieldName eq "QAContact" && $relationship == REL_QA))
if (($fieldName eq "assigned_to" && $relationship == REL_ASSIGNEE) ||
($fieldName eq "qa_contact" && $relationship == REL_QA))
{
$events{+EVT_ADDED_REMOVED} = 1;
}
if ($fieldName eq "CC") {
if ($fieldName eq "cc") {
my $login = $self->login;
my $inold = ($old =~ /^(.*,\s*)?\Q$login\E(,.*)?$/);
my $innew = ($new =~ /^(.*,\s*)?\Q$login\E(,.*)?$/);
my $inold = ($change->{old} =~ /^(.*,\s*)?\Q$login\E(,.*)?$/);
my $innew = ($change->{new} =~ /^(.*,\s*)?\Q$login\E(,.*)?$/);
if ($inold != $innew)
{
$events{+EVT_ADDED_REMOVED} = 1;
......@@ -1549,7 +1547,7 @@ sub wants_bug_mail {
}
}
if ($bug_is_new) {
if (!$bug->lastdiffed) {
# Notify about new bugs.
$events{+EVT_BUG_CREATED} = 1;
......@@ -1589,19 +1587,8 @@ sub wants_bug_mail {
$wants_mail &= $self->wants_mail([EVT_CHANGED_BY_ME], $relationship);
}
if ($wants_mail) {
my $dbh = Bugzilla->dbh;
# We don't create a Bug object from the bug_id here because we only
# need one piece of information, and doing so (as of 2004-11-23) slows
# down bugmail sending by a factor of 2. If Bug creation was more
# lazy, this might not be so bad.
my $bug_status = $dbh->selectrow_array('SELECT bug_status
FROM bugs WHERE bug_id = ?',
undef, $bug_id);
if ($bug_status eq "UNCONFIRMED") {
$wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship);
}
if ($wants_mail && $bug->bug_status eq 'UNCONFIRMED') {
$wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship);
}
return $wants_mail;
......
......@@ -39,8 +39,7 @@ use base qw(Exporter);
do_ssl_redirect_if_required use_attachbase
diff_arrays on_main_db
trim wrap_hard wrap_comment find_wrap_point
format_time format_time_decimal validate_date
validate_time datetime_from
format_time validate_date validate_time datetime_from
file_mod_time is_7bit_clean
bz_crypt generate_random_password
validate_email_syntax clean_text
......@@ -466,18 +465,6 @@ sub datetime_from {
return $dt;
}
sub format_time_decimal {
my ($time) = (@_);
my $newtime = sprintf("%.2f", $time);
if ($newtime =~ /0\Z/) {
$newtime = sprintf("%.1f", $time);
}
return $newtime;
}
sub file_mod_time {
my ($filename) = (@_);
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
......@@ -935,11 +922,6 @@ is used, as defined in his preferences.
This routine is mainly called from templates to filter dates, see
"FILTER time" in L<Bugzilla::Template>.
=item C<format_time_decimal($time)>
Returns a number with 2 digit precision, unless the last digit is a 0. Then it
returns only 1 digit precision.
=item C<datetime_from($time, $timezone)>
Returns a DateTime object given a date string. If the string is not in some
......
......@@ -16,11 +16,14 @@
# Rights Reserved.
#
# Contributor(s): André Batosti <batosti@async.com.br>
# Frédéric Buclin <LpSolit@gmail.com>
#%]
[% PROCESS "global/variables.none.tmpl" %]
[% 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 %]
......@@ -43,11 +46,8 @@ X-Bugzilla-Target-Milestone: [% bug.target_milestone %]
X-Bugzilla-Changed-Fields: [% changedfields.join(" ") %]
[%+ threadingmarker %]
[%+ urlbase %]show_bug.cgi?id=[% bug.id %]
[%- IF diffs %]
[%+ PROCESS generate_diffs -%]
[%+ diffs %]
[% END -%]
[% FOREACH comment = new_comments %]
[%- IF comment.count %]
......@@ -68,3 +68,52 @@ Configure [% terms.bug %]mail: [% urlbase %]userprefs.cgi?tab=email
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 %]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment