summaryrefslogtreecommitdiffstats
path: root/extensions/RequestNagger
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/RequestNagger')
-rwxr-xr-xextensions/RequestNagger/bin/send-request-nags.pl316
-rw-r--r--extensions/RequestNagger/lib/Bug.pm16
-rw-r--r--extensions/RequestNagger/lib/Constants.pm104
-rw-r--r--extensions/RequestNagger/template/en/default/email/request_nagging-requestee.html.tmpl90
-rw-r--r--extensions/RequestNagger/template/en/default/email/request_nagging-user-header.txt.tmpl (renamed from extensions/RequestNagger/template/en/default/email/request_nagging-requestee-header.txt.tmpl)20
-rw-r--r--extensions/RequestNagger/template/en/default/email/request_nagging-user.html.tmpl115
-rw-r--r--extensions/RequestNagger/template/en/default/email/request_nagging-user.txt.tmpl (renamed from extensions/RequestNagger/template/en/default/email/request_nagging-requestee.txt.tmpl)45
-rw-r--r--extensions/RequestNagger/template/en/default/email/request_nagging-watching-header.txt.tmpl8
-rw-r--r--extensions/RequestNagger/template/en/default/email/request_nagging-watching.html.tmpl121
-rw-r--r--extensions/RequestNagger/template/en/default/email/request_nagging-watching.txt.tmpl61
10 files changed, 570 insertions, 326 deletions
diff --git a/extensions/RequestNagger/bin/send-request-nags.pl b/extensions/RequestNagger/bin/send-request-nags.pl
index 93265b9ee..1673d2208 100755
--- a/extensions/RequestNagger/bin/send-request-nags.pl
+++ b/extensions/RequestNagger/bin/send-request-nags.pl
@@ -19,6 +19,7 @@ BEGIN { Bugzilla->extensions() }
use Bugzilla::Attachment;
use Bugzilla::Bug;
use Bugzilla::Constants;
+use Bugzilla::Hook;
use Bugzilla::Error;
use Bugzilla::Extension::RequestNagger::Constants;
use Bugzilla::Extension::RequestNagger::Bug;
@@ -26,7 +27,7 @@ use Bugzilla::Mailer;
use Bugzilla::User;
use Bugzilla::Util qw(format_time);
use Email::MIME;
-use Sys::Hostname;
+use Sys::Hostname qw(hostname);
Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
@@ -42,168 +43,211 @@ Bugzilla->switch_to_shadow_db();
# send nags to requestees
send_nags(
- sql => REQUESTEE_NAG_SQL,
- template => 'requestee',
- recipient_field => 'requestee_id',
- date => $date,
+ requestee_sql => REQUESTEE_NAG_SQL,
+ setter_sql => SETTER_NAG_SQL,
+ template => 'user',
+ date => $date,
);
# send nags to watchers
send_nags(
- sql => WATCHING_NAG_SQL,
- template => 'watching',
- recipient_field => 'watcher_id',
- date => $date,
+ requestee_sql => WATCHING_REQUESTEE_NAG_SQL,
+ setter_sql => WATCHING_SETTER_NAG_SQL,
+ template => 'watching',
+ date => $date,
);
sub send_nags {
my (%args) = @_;
- my $rows = $dbh->selectall_arrayref($args{sql}, { Slice => {} });
-
- # iterate over rows, sending email when the current recipient changes
- my $requests = [];
- my $current_recipient;
- foreach my $request (@$rows) {
- # send previous user's requests
- if (!$current_recipient || $request->{$args{recipient_field}} != $current_recipient->id) {
- send_email(%args, recipient => $current_recipient, requests => $requests);
- $current_recipient = Bugzilla::User->new({ id => $request->{$args{recipient_field}}, cache => 1 });
- $requests = [];
+
+ my @reports = qw( requestee setter );
+ my $securemail = Bugzilla::User->can('public_key');
+ my $requests = {};
+
+ # get requests
+
+ foreach my $report (@reports) {
+
+ # collate requests
+ my $rows = $dbh->selectall_arrayref($args{$report . '_sql'}, { Slice => {} });
+ foreach my $request (@$rows) {
+ next unless _include_request($request, $report);
+
+ my $target = Bugzilla::User->new({ id => $request->{target_id}, cache => 1 });
+ push @{
+ $requests
+ ->{$request->{recipient_id}}
+ ->{$target->login}
+ ->{$report}
+ ->{$request->{flag_type}}
+ }, $request;
+ push @{
+ $requests
+ ->{$request->{recipient_id}}
+ ->{$target->login}
+ ->{bug_ids}
+ ->{$report}
+ }, $request->{bug_id};
}
- # check group membership
- $request->{requestee} = Bugzilla::User->new({ id => $request->{requestee_id}, cache => 1 });
- my $group;
- foreach my $type (FLAG_TYPES) {
- next unless $type->{type} eq $request->{flag_type};
- $group = $type->{group};
- last;
+ # process requests here to avoid doing it in the templates
+ foreach my $recipient_id (keys %$requests) {
+ foreach my $target_login (keys %{ $requests->{$recipient_id} }) {
+ my $rh = $requests->{$recipient_id}->{$target_login};
+
+ # build a list of valid types in the correct order
+ $rh->{types}->{$report} = [];
+ foreach my $type (map { $_->{type} } FLAG_TYPES) {
+ next unless exists $rh->{$report}->{$type};
+ push @{ $rh->{types}->{$report} }, $type;
+ }
+
+ # build a summary
+ $rh->{summary}->{$report} = join(', ',
+ map { scalar(@{ $rh->{$report}->{$_} }) . ' ' . $_ }
+ @{ $rh->{types}->{$report} }
+ );
+ }
}
- next unless $request->{requestee}->in_group($group);
-
- # check bug visibility
- next unless $current_recipient->can_see_bug($request->{bug_id});
-
- # create objects
- $request->{bug} = Bugzilla::Bug->new({ id => $request->{bug_id}, cache => 1 });
- $request->{requester} = Bugzilla::User->new({ id => $request->{requester_id}, cache => 1 });
- $request->{flag} = Bugzilla::Flag->new({ id => $request->{flag_id}, cache => 1 });
- if ($request->{attach_id}) {
- $request->{attachment} = Bugzilla::Attachment->new({ id => $request->{attach_id}, cache => 1 });
- # check attachment visibility
- next if $request->{attachment}->isprivate && !$current_recipient->is_insider;
+ }
+
+ # send emails
+
+ foreach my $recipient_id (sort keys %$requests) {
+ my $recipient = Bugzilla::User->new({ id => $recipient_id, cache => 1 });
+ my $has_key = $securemail && $recipient->public_key;
+ my $has_private_bug = 0;
+
+ foreach my $target_login (keys %{ $requests->{$recipient_id} }) {
+ my $rh = $requests->{$recipient_id}->{$target_login};
+ $rh->{target} = Bugzilla::User->new({ name => $target_login, cache => 1 });
+ foreach my $report (@reports) {
+ foreach my $type (keys %{ $rh->{$report} }) {
+ foreach my $request (@{ $rh->{$report}->{$type} }) {
+
+ _create_objects($request);
+
+ # we need to encrypt or censor emails which contain
+ # non-public bugs
+ if ($request->{bug}->is_private) {
+ $has_private_bug = 1;
+ $request->{bug}->{sanitise_bug} = !$securemail || !$has_key;
+ }
+ else {
+ $request->{bug}->{sanitise_bug} = 0;
+ }
+ }
+ }
+ }
}
- if (exists $request->{watcher_id}) {
- $request->{watcher} = Bugzilla::User->new({ id => $request->{watcher_id}, cache => 1 });
+ my $encrypt = $securemail && $has_private_bug && $has_key;
+
+ # generate email
+ my $template = Bugzilla->template_inner($recipient->setting('lang'));
+ my $template_file = $args{template};
+ my $vars = {
+ recipient => $recipient,
+ requests => $requests->{$recipient_id},
+ date => $args{date},
+ };
+
+ my ($header, $text);
+ $template->process("email/request_nagging-$template_file-header.txt.tmpl", $vars, \$header)
+ || ThrowTemplateError($template->error());
+ $header .= "\n";
+ $template->process("email/request_nagging-$template_file.txt.tmpl", $vars, \$text)
+ || ThrowTemplateError($template->error());
+
+ my @parts = (
+ Email::MIME->create(
+ attributes => { content_type => "text/plain" },
+ body => $text,
+ )
+ );
+ if ($recipient->setting('email_format') eq 'html') {
+ my $html;
+ $template->process("email/request_nagging-$template_file.html.tmpl", $vars, \$html)
+ || ThrowTemplateError($template->error());
+ push @parts, Email::MIME->create(
+ attributes => { content_type => "text/html" },
+ body => $html,
+ );
}
- # add this request to the current user's list
- push(@$requests, $request);
- }
- send_email(%args, recipient => $current_recipient, requests => $requests);
-}
+ my $email = Email::MIME->new($header);
+ $email->header_set('X-Generated-By' => hostname());
+ if (scalar(@parts) == 1) {
+ $email->content_type_set($parts[0]->content_type);
+ }
+ else {
+ $email->content_type_set('multipart/alternative');
+ }
+ $email->parts_set(\@parts);
+ if ($encrypt) {
+ $email->header_set('X-Bugzilla-Encrypt' => '1');
+ }
-sub send_email {
- my (%vars) = @_;
- my $vars = \%vars;
- return unless $vars->{recipient} && @{ $vars->{requests} };
-
- my $request_list = delete $vars->{requests};
-
- # if securemail is installed, we need to encrypt or censor emails which
- # contain non-public bugs
- my $default_user = Bugzilla::User->new();
- my $securemail = $vars->{recipient}->can('public_key');
- my $has_key = $securemail && $vars->{recipient}->public_key;
- # have to do this each time as objects are shared between requests
- my $has_private_bug = 0;
- foreach my $request (@{ $request_list }) {
- # rebless bug objects into our subclass
- bless($request->{bug}, 'Bugzilla::Extension::RequestNagger::Bug');
- # and tell that object to hide the summary if required
- if ($securemail && !$default_user->can_see_bug($request->{bug})) {
- $has_private_bug = 1;
- $request->{bug}->{secure_bug} = !$has_key;
+ # send
+ if ($DO_NOT_NAG) {
+ # uncomment the following line to enable other extensions to
+ # process this email, including encryption
+ # Bugzilla::Hook::process('mailer_before_send', { email => $email });
+ print $email->as_string, "\n";
}
else {
- $request->{bug}->{secure_bug} = 0;
+ MessageToMTA($email);
}
+
+ # nuke objects to avoid excessive memory usage
+ $requests->{$recipient_id} = undef;
+ Bugzilla->clear_request_cache();
}
- my $encrypt = $securemail && $has_private_bug && $has_key;
-
- # restructure the list to group by requestee then flag type
- my $requests = {};
- my %seen_types;
- foreach my $request (@{ $request_list }) {
- # by requestee
- my $requestee_login = $request->{requestee}->login;
- $requests->{$requestee_login} ||= {
- requestee => $request->{requestee},
- types => {},
- typelist => [],
- };
+}
- # by flag type
- my $types = $requests->{$requestee_login}->{types};
- my $flag_type = $request->{flag_type};
- $types->{$flag_type} ||= [];
+sub _include_request {
+ my ($request, $report) = @_;
- push @{ $types->{$flag_type} }, $request;
- $seen_types{$requestee_login}{$flag_type} = 1;
- }
- foreach my $requestee_login (keys %seen_types) {
- my @flag_types;
- foreach my $flag_type (map { $_->{type} } FLAG_TYPES) {
- push @flag_types, $flag_type if $seen_types{$requestee_login}{$flag_type};
+ my $recipient = Bugzilla::User->new({ id => $request->{recipient_id}, cache => 1 });
+
+ if ($report eq 'requestee') {
+ # check recipient group membership
+ my $group;
+ foreach my $type (FLAG_TYPES) {
+ next unless $type->{type} eq $request->{flag_type};
+ $group = $type->{group};
+ last;
}
- $requests->{$requestee_login}->{typelist} = \@flag_types;
+ return 0 unless $recipient->in_group($group);
}
- $vars->{requests} = $requests;
-
- # generate email
- my $template = Bugzilla->template_inner($vars->{recipient}->setting('lang'));
- my $template_file = $vars->{template};
-
- my ($header, $text);
- $template->process("email/request_nagging-$template_file-header.txt.tmpl", $vars, \$header)
- || ThrowTemplateError($template->error());
- $header .= "\n";
- $template->process("email/request_nagging-$template_file.txt.tmpl", $vars, \$text)
- || ThrowTemplateError($template->error());
-
- my @parts = (
- Email::MIME->create(
- attributes => { content_type => "text/plain" },
- body => $text,
- )
- );
- if ($vars->{recipient}->setting('email_format') eq 'html') {
- my $html;
- $template->process("email/request_nagging-$template_file.html.tmpl", $vars, \$html)
- || ThrowTemplateError($template->error());
- push @parts, Email::MIME->create(
- attributes => { content_type => "text/html" },
- body => $html,
- );
+
+ # check bug visibility
+ return 0 unless $recipient->can_see_bug($request->{bug_id});
+
+ # check attachment visibility
+ if ($request->{attach_id}) {
+ my $attachment = Bugzilla::Attachment->new({ id => $request->{attach_id}, cache => 1 });
+ return 0 if $attachment->isprivate && !$recipient->is_insider;
}
- my $email = Email::MIME->new($header);
- $email->header_set('X-Generated-By' => hostname());
- if (scalar(@parts) == 1) {
- $email->content_type_set($parts[0]->content_type);
- } else {
- $email->content_type_set('multipart/alternative');
+ return 1;
+}
+
+sub _create_objects {
+ my ($request) = @_;
+
+ $request->{recipient} = Bugzilla::User->new({ id => $request->{recipient_id}, cache => 1 });
+ $request->{setter} = Bugzilla::User->new({ id => $request->{setter_id}, cache => 1 });
+
+ if (defined $request->{requestee_id}) {
+ $request->{requestee} = Bugzilla::User->new({ id => $request->{requestee_id}, cache => 1 });
}
- $email->parts_set(\@parts);
- if ($encrypt) {
- $email->header_set('X-Bugzilla-Encrypt' => '1');
+ if (exists $request->{watcher_id}) {
+ $request->{watcher} = Bugzilla::User->new({ id => $request->{watcher_id}, cache => 1 });
}
- # send
- if ($DO_NOT_NAG) {
- print $email->as_string, "\n";
- } else {
- MessageToMTA($email);
+ $request->{bug} = Bugzilla::Extension::RequestNagger::Bug->new({ id => $request->{bug_id}, cache => 1 });
+ $request->{flag} = Bugzilla::Flag->new({ id => $request->{flag_id}, cache => 1 });
+ if (defined $request->{attach_id}) {
+ $request->{attachment} = Bugzilla::Attachment->new({ id => $request->{attach_id}, cache => 1 });
}
}
-
diff --git a/extensions/RequestNagger/lib/Bug.pm b/extensions/RequestNagger/lib/Bug.pm
index de6d5eae5..bd5bb7fd7 100644
--- a/extensions/RequestNagger/lib/Bug.pm
+++ b/extensions/RequestNagger/lib/Bug.pm
@@ -9,10 +9,22 @@ package Bugzilla::Extension::RequestNagger::Bug;
use strict;
use parent qw(Bugzilla::Bug);
+use feature 'state';
+
+use Bugzilla::User;
sub short_desc {
my ($self) = @_;
- return $self->{secure_bug} ? '(Secure bug)' : $self->SUPER::short_desc;
+ return $self->{sanitise_bug} ? '(Secure bug)' : $self->SUPER::short_desc;
+}
+
+sub is_private {
+ my ($self) = @_;
+ if (!exists $self->{is_private}) {
+ state $default_user //= Bugzilla::User->new();
+ $self->{is_private} = !$default_user->can_see_bug($self);
+ }
+ return $self->{is_private};
}
sub tooltip {
@@ -21,7 +33,7 @@ sub tooltip {
if ($self->bug_status eq 'RESOLVED') {
$tooltip .= '/' . $self->resolution;
}
- if (!$self->{secure_bug}) {
+ if (!$self->{sanitise_bug}) {
$tooltip .= ' ' . $self->product . ' :: ' . $self->component;
}
return $tooltip;
diff --git a/extensions/RequestNagger/lib/Constants.pm b/extensions/RequestNagger/lib/Constants.pm
index f61e616a7..899336a72 100644
--- a/extensions/RequestNagger/lib/Constants.pm
+++ b/extensions/RequestNagger/lib/Constants.pm
@@ -13,7 +13,9 @@ use base qw(Exporter);
our @EXPORT = qw(
FLAG_TYPES
REQUESTEE_NAG_SQL
- WATCHING_NAG_SQL
+ SETTER_NAG_SQL
+ WATCHING_REQUESTEE_NAG_SQL
+ WATCHING_SETTER_NAG_SQL
);
# the order of this array determines the order used in email
@@ -47,12 +49,14 @@ sub REQUESTEE_NAG_SQL {
flags.bug_id,
flags.attach_id,
flags.modification_date,
- requester.userid AS requester_id,
- requestee.userid AS requestee_id
+ setter.userid AS setter_id,
+ requestee.userid AS requestee_id,
+ flags.requestee_id AS recipient_id,
+ flags.requestee_id AS target_id
FROM
flags
INNER JOIN flagtypes ON flagtypes.id = flags.type_id
- INNER JOIN profiles AS requester ON requester.userid = flags.setter_id
+ INNER JOIN profiles AS setter ON setter.userid = flags.setter_id
INNER JOIN profiles AS requestee ON requestee.userid = flags.requestee_id
INNER JOIN bugs ON bugs.bug_id = flags.bug_id
INNER JOIN products ON products.id = bugs.product_id
@@ -75,7 +79,48 @@ sub REQUESTEE_NAG_SQL {
";
}
-sub WATCHING_NAG_SQL {
+sub SETTER_NAG_SQL {
+ my $dbh = Bugzilla->dbh;
+ my @flag_types_sql = map { $dbh->quote($_->{type}) } FLAG_TYPES;
+
+ return "
+ SELECT
+ flagtypes.name AS flag_type,
+ flags.id AS flag_id,
+ flags.bug_id,
+ flags.attach_id,
+ flags.modification_date,
+ setter.userid AS setter_id,
+ requestee.userid AS requestee_id,
+ flags.setter_id AS recipient_id,
+ flags.setter_id AS target_id
+ FROM
+ flags
+ INNER JOIN flagtypes ON flagtypes.id = flags.type_id
+ INNER JOIN profiles AS setter ON setter.userid = flags.setter_id
+ LEFT JOIN profiles AS requestee ON requestee.userid = flags.requestee_id
+ INNER JOIN bugs ON bugs.bug_id = flags.bug_id
+ INNER JOIN products ON products.id = bugs.product_id
+ LEFT JOIN attachments ON attachments.attach_id = flags.attach_id
+ LEFT JOIN profile_setting ON profile_setting.setting_name = 'request_nagging'
+ AND profile_setting.user_id = flags.setter_id
+ LEFT JOIN nag_defer ON nag_defer.flag_id = flags.id
+ WHERE
+ " . $dbh->sql_in('flagtypes.name', \@flag_types_sql) . "
+ AND flags.status = '?'
+ AND products.nag_interval != 0
+ AND TIMESTAMPDIFF(HOUR, flags.modification_date, CURRENT_DATE()) >= products.nag_interval
+ AND (profile_setting.setting_value IS NULL OR profile_setting.setting_value = 'on')
+ AND setter.disable_mail = 0
+ AND nag_defer.id IS NULL
+ ORDER BY
+ flags.setter_id,
+ flagtypes.name,
+ flags.modification_date
+ ";
+}
+
+sub WATCHING_REQUESTEE_NAG_SQL {
my $dbh = Bugzilla->dbh;
my @flag_types_sql = map { $dbh->quote($_->{type}) } FLAG_TYPES;
@@ -87,12 +132,14 @@ sub WATCHING_NAG_SQL {
flags.bug_id,
flags.attach_id,
flags.modification_date,
- requester.userid AS requester_id,
- requestee.userid AS requestee_id
+ setter.userid AS setter_id,
+ requestee.userid AS requestee_id,
+ nag_watch.watcher_id AS recipient_id,
+ requestee.userid AS target_id
FROM
flags
INNER JOIN flagtypes ON flagtypes.id = flags.type_id
- INNER JOIN profiles AS requester ON requester.userid = flags.setter_id
+ INNER JOIN profiles AS setter ON setter.userid = flags.setter_id
INNER JOIN profiles AS requestee ON requestee.userid = flags.requestee_id
INNER JOIN bugs ON bugs.bug_id = flags.bug_id
INNER JOIN products ON products.id = bugs.product_id
@@ -113,4 +160,45 @@ sub WATCHING_NAG_SQL {
";
}
+sub WATCHING_SETTER_NAG_SQL {
+ my $dbh = Bugzilla->dbh;
+ my @flag_types_sql = map { $dbh->quote($_->{type}) } FLAG_TYPES;
+
+ return "
+ SELECT
+ nag_watch.watcher_id,
+ flagtypes.name AS flag_type,
+ flags.id AS flag_id,
+ flags.bug_id,
+ flags.attach_id,
+ flags.modification_date,
+ setter.userid AS setter_id,
+ requestee.userid AS requestee_id,
+ nag_watch.watcher_id AS recipient_id,
+ setter.userid AS target_id
+ FROM
+ flags
+ INNER JOIN flagtypes ON flagtypes.id = flags.type_id
+ INNER JOIN profiles AS setter ON setter.userid = flags.setter_id
+ LEFT JOIN profiles AS requestee ON requestee.userid = flags.requestee_id
+ INNER JOIN bugs ON bugs.bug_id = flags.bug_id
+ INNER JOIN products ON products.id = bugs.product_id
+ LEFT JOIN attachments ON attachments.attach_id = flags.attach_id
+ LEFT JOIN nag_defer ON nag_defer.flag_id = flags.id
+ INNER JOIN nag_watch ON nag_watch.nagged_id = flags.setter_id
+ INNER JOIN profiles AS watcher ON watcher.userid = nag_watch.watcher_id
+ WHERE
+ " . $dbh->sql_in('flagtypes.name', \@flag_types_sql) . "
+ AND flags.status = '?'
+ AND products.nag_interval != 0
+ AND TIMESTAMPDIFF(HOUR, flags.modification_date, CURRENT_DATE()) >= products.nag_interval
+ AND watcher.disable_mail = 0
+ ORDER BY
+ nag_watch.watcher_id,
+ flags.requestee_id,
+ flags.modification_date
+ ";
+}
+
+
1;
diff --git a/extensions/RequestNagger/template/en/default/email/request_nagging-requestee.html.tmpl b/extensions/RequestNagger/template/en/default/email/request_nagging-requestee.html.tmpl
deleted file mode 100644
index bdaaabb97..000000000
--- a/extensions/RequestNagger/template/en/default/email/request_nagging-requestee.html.tmpl
+++ /dev/null
@@ -1,90 +0,0 @@
-[%# This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #
- # This Source Code Form is "Incompatible With Secondary Licenses", as
- # defined by the Mozilla Public License, v. 2.0.
- #%]
-
-[% PROCESS "global/field-descs.none.tmpl" %]
-
-<!doctype html>
-<html>
-
-<head>
- <title>[[% terms.Bugzilla %]] Your Overdue Requests</title>
-</head>
-
-<body bgcolor="#ffffff">
-
-<p>
- The following is a list of requests people have made of you, which are
- currently overdue. To avoid disappointing others, please deal with them as
- quickly as possible.
-</p>
-
-[% requests = requests.item(recipient.login) %]
-[% FOREACH type = requests.typelist %]
-
- <h3>
- [% type FILTER upper FILTER html %] requests
- <span style="font-size: x-small; font-weight: normal">
- (<a href="[% urlbase FILTER none %]buglist.cgi?bug_id=
- [% FOREACH request = requests.types.$type %]
- [% request.bug.id FILTER none %]
- [% "%2C" UNLESS loop.last %]
- [% END %]">buglist</a>)
- </span>
- </h3>
-
- <ul>
- [% FOREACH request = requests.types.$type %]
- <li>
- <a href="[% urlbase FILTER none %]show_bug.cgi?id=[% request.bug.id FILTER none %]"
- title="[% request.bug.tooltip FILTER html %]">
- [% request.bug.id FILTER none %] - [% request.bug.short_desc FILTER html %]
- </a><br>
- <b>[%+ request.flag.age FILTER html %]</b> from [% request.requester.identity FILTER html %]<br>
- <div style="font-size: x-small">
- [% IF request.attachment %]
- <a href="[% urlbase FILTER none %]attachment.cgi?id=[% request.attachment.id FILTER none %]&amp;action=edit">Details</a>
- [% IF request.attachment.ispatch %]
- | <a href="[% urlbase FILTER none %]attachment.cgi?id=[% request.attachment.id FILTER none %]&amp;action=diff">Diff</a>
- | <a href="[% urlbase FILTER none %]review?bug=[% request.bug.id FILTER none %]&amp;attachment=[% request.attachment.id FILTER none %]">Review</a>
- [% END %]
- |
- [% END %]
- <a href="[% urlbase FILTER none %]request_defer?flag=[% request.flag.id FILTER none %]">Defer</a>
- </div>
- <br>
- </li>
- [% END %]
- </ul>
-
-[% END %]
-
-<div>
- <hr style="border: 1px dashed #969696">
- [% IF requests.types.item('review').size || requests.types.item('feedback').size %]
- <a href="https://wiki.mozilla.org/BMO/Handling_Requests">
- Guidance on handling requests
- </a><br>
- [% END %]
- <a href="[% urlbase FILTER none %]request.cgi?action=queue&amp;requestee=[% recipient.login FILTER uri %]&amp;group=type">
- See all your overdue requests
- </a><br>
- <a href="[% urlbase FILTER none %]userprefs.cgi#request_nagging">
- Opt out of these emails
- </a><br>
-</div>
-
-<div style="font-size: 90%; color: #666666">
- <hr style="border: 1px dashed #969696">
- <b>You are receiving this mail because:</b>
- <ul>
- <li>You have overdue requests.</li>
- </ul>
-</div>
-@@body-headers@@
-</body>
-</html>
diff --git a/extensions/RequestNagger/template/en/default/email/request_nagging-requestee-header.txt.tmpl b/extensions/RequestNagger/template/en/default/email/request_nagging-user-header.txt.tmpl
index 8ad9d6cb1..6bb9e997b 100644
--- a/extensions/RequestNagger/template/en/default/email/request_nagging-requestee-header.txt.tmpl
+++ b/extensions/RequestNagger/template/en/default/email/request_nagging-user-header.txt.tmpl
@@ -6,14 +6,20 @@
# defined by the Mozilla Public License, v. 2.0.
#%]
-[% PROCESS "global/field-descs.none.tmpl" %]
-[% PROCESS "global/reason-descs.none.tmpl" %]
+[%
+ PROCESS "global/field-descs.none.tmpl";
+ PROCESS "global/reason-descs.none.tmpl";
+ summary = requests.item(recipient.login).summary;
+%]
+
From: [% Param('mailfrom') %]
To: [% recipient.email %]
-Subject: [[% terms.Bugzilla %]] Your Overdue Requests
- ([% FOREACH type = requests.item(recipient.email).typelist %]
- [%- requests.item(recipient.email).types.item(type).size %] [%+ type %]
- [% ", " UNLESS loop.last %]
- [% END %])
+Subject: [[% terms.Bugzilla %]] Overdue Requests
+ [% IF summary.requestee %]
+ (Of you: [% summary.requestee %])
+ [% END %]
+ [% IF summary.setter %]
+ (By you: [% summary.setter %])
+ [% END %]
Date: [% date %]
X-Bugzilla-Type: nag
diff --git a/extensions/RequestNagger/template/en/default/email/request_nagging-user.html.tmpl b/extensions/RequestNagger/template/en/default/email/request_nagging-user.html.tmpl
new file mode 100644
index 000000000..9aeb73f61
--- /dev/null
+++ b/extensions/RequestNagger/template/en/default/email/request_nagging-user.html.tmpl
@@ -0,0 +1,115 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%
+ PROCESS "global/field-descs.none.tmpl";
+ requestee = requests.item(recipient.login).requestee;
+ setter = requests.item(recipient.login).setter;
+ summary = requests.item(recipient.login).summary;
+ types = requests.item(recipient.login).types;
+%]
+
+<!doctype html>
+<html>
+
+<head>
+ <title>[[% terms.Bugzilla %]] Your Overdue Requests</title>
+</head>
+
+<body bgcolor="#ffffff">
+
+[% IF requestee.size %]
+ <h3>Overdue requests requiring action from you:</h3>
+ <div>[% summary.requestee FILTER html %]</div>
+ [% PROCESS requests report="requestee" requests=requestee %]
+[% END %]
+
+[% IF requestee.size && setter.size %]
+ <hr>
+[% END %]
+
+[% IF setter.size %]
+ <h3>Overdue requests you have requested:</h3>
+ <div>[% summary.setter FILTER html %]</div>
+ [% PROCESS requests report="setter" requests=setter %]
+[% END %]
+
+[% BLOCK requests %]
+ [% FOREACH type IN types.item(report) %]
+ <h3>
+ [% type FILTER upper FILTER html %] requests
+ <span style="font-size: x-small; font-weight: normal">
+ (<a href="[% urlbase FILTER none %]buglist.cgi?bug_id=
+ [% FOREACH request IN requests.item(type) %]
+ [% request.bug.id FILTER none %]
+ [% "%2C" UNLESS loop.last %]
+ [% END %]">buglist</a>)
+ </span>
+ </h3>
+
+ <ul>
+ [% FOREACH request IN requests.item(type) %]
+ <li>
+ <a href="[% urlbase FILTER none %]show_bug.cgi?id=[% request.bug.id FILTER none %]"
+ title="[% request.bug.tooltip FILTER html %]">
+ [% request.bug.id FILTER none %] - [% request.bug.short_desc FILTER html %]
+ </a><br>
+ <b>[%+ request.flag.age FILTER html %]</b>
+ [% IF report == "requestee" %]
+ from [% request.setter.realname || request.setter.login FILTER html %]
+ [% ELSIF request.requestee %]
+ to [% request.requestee.realname || request.setter.login FILTER html %]
+ [% ELSE %]
+ to <i>anyone</i>
+ [% END %]
+ <br>
+ [% IF report == "requestee" %]
+ <div style="font-size: x-small">
+ [% IF request.attachment %]
+ <a href="[% urlbase FILTER none %]attachment.cgi?id=[% request.attachment.id FILTER none %]&amp;action=edit">Details</a>
+ [% IF request.attachment.ispatch %]
+ | <a href="[% urlbase FILTER none %]attachment.cgi?id=[% request.attachment.id FILTER none %]&amp;action=diff">Diff</a>
+ | <a href="[% urlbase FILTER none %]review?bug=[% request.bug.id FILTER none %]&amp;attachment=[% request.attachment.id FILTER none %]">Review</a>
+ [% END %]
+ |
+ [% END %]
+ <a href="[% urlbase FILTER none %]request_defer?flag=[% request.flag.id FILTER none %]">Defer</a>
+ </div>
+ [% END %]
+ <br>
+ </li>
+ [% END %]
+ </ul>
+ [% END %]
+[% END %]
+
+<div>
+ <hr style="border: 1px dashed #969696">
+ [% IF requestee.item('review').size || requestee.item('feedback').size %]
+ <a href="https://wiki.mozilla.org/BMO/Handling_Requests">
+ Guidance on handling requests
+ </a><br>
+ [% END %]
+ <a href="[% urlbase FILTER none %]request.cgi?action=queue&amp;requestee=[% recipient.login FILTER uri %]&amp;group=type">
+ See all your overdue requests
+ </a><br>
+ <a href="[% urlbase FILTER none %]userprefs.cgi#request_nagging">
+ Opt out of these emails
+ </a><br>
+</div>
+
+<div style="font-size: 90%; color: #666666">
+ <hr style="border: 1px dashed #969696">
+ <b>You are receiving this mail because:</b>
+ <ul>
+ <li>You have overdue requests.</li>
+ </ul>
+</div>
+@@body-headers@@
+</body>
+</html>
diff --git a/extensions/RequestNagger/template/en/default/email/request_nagging-requestee.txt.tmpl b/extensions/RequestNagger/template/en/default/email/request_nagging-user.txt.tmpl
index 4e3f67090..5138f5f00 100644
--- a/extensions/RequestNagger/template/en/default/email/request_nagging-requestee.txt.tmpl
+++ b/extensions/RequestNagger/template/en/default/email/request_nagging-user.txt.tmpl
@@ -6,31 +6,58 @@
# defined by the Mozilla Public License, v. 2.0.
#%]
-[% PROCESS "global/field-descs.none.tmpl" %]
+[%
+ PROCESS "global/field-descs.none.tmpl";
+ requestee = requests.item(recipient.login).requestee;
+ setter = requests.item(recipient.login).setter;
+ summary = requests.item(recipient.login).summary;
+ types = requests.item(recipient.login).types;
+%]
-The following is a list of requests people have made of you, which are
-currently overdue. To avoid disappointing others, please deal with them as
-quickly as possible.
+[% IF requestee.size %]
+Overdue requests requiring action from you:
+[%+ summary.requestee %]
-[% requests = requests.item(recipient.login) %]
-[% FOREACH type = requests.typelist %]
+[%+ PROCESS requests report="requestee" request_list=requestee %]
+[% END %]
+
+[% IF requestee.size && setter.size %]
+-
+[% END %]
+
+[% IF setter.size %]
+Overdue requests you have requested:
+[%+ summary.setter %]
+
+[%+ PROCESS requests report="setter" request_list=setter %]
+[% END %]
+
+[% BLOCK requests %]
+[% FOREACH type IN types.item(report) %]
:: [% type FILTER upper FILTER html %] requests
-[% FOREACH request = requests.types.$type %]
+[% FOREACH request IN request_list.item(type) %]
[[% terms.Bug %] [%+ request.bug.id %]] [% request.bug.short_desc %]
- [%+ request.flag.age %] from [% request.requester.identity %]
+ [% IF report == "requestee" %]
+ [%+ request.flag.age %] from [% request.setter.realname || request.setter.login %]
+ [% ELSE %]
+ [%+ request.flag.age %] to [% request.requestee.realname || request.requestee.login %]
+ [% END %]
[%+ urlbase %]show_bug.cgi?id=[% request.bug.id +%]
[% IF request.attachment && request.attachment.ispatch %]
Review: [% urlbase %]review?bug=[% request.bug.id %]&attachment=[% request.attachment.id %]
[% END %]
+ [% IF report == "requestee" %]
Defer: [% urlbase %]request_defer?flag=[% request.flag.id %]
+ [% END %]
[% END %]
[% END %]
+[% END %]
::
-[% IF requests.types.item('review').size || requests.types.item('feedback').size %]
+[% IF requestee.item('review').size || requestee.item('feedback').size %]
Guidance on handling requests:
https://wiki.mozilla.org/BMO/Handling_Requests
[% END %]
diff --git a/extensions/RequestNagger/template/en/default/email/request_nagging-watching-header.txt.tmpl b/extensions/RequestNagger/template/en/default/email/request_nagging-watching-header.txt.tmpl
index 261e92f13..d825cb459 100644
--- a/extensions/RequestNagger/template/en/default/email/request_nagging-watching-header.txt.tmpl
+++ b/extensions/RequestNagger/template/en/default/email/request_nagging-watching-header.txt.tmpl
@@ -6,10 +6,12 @@
# defined by the Mozilla Public License, v. 2.0.
#%]
-[% PROCESS "global/field-descs.none.tmpl" %]
-[% PROCESS "global/reason-descs.none.tmpl" %]
+[%
+ PROCESS "global/field-descs.none.tmpl";
+ PROCESS "global/reason-descs.none.tmpl";
+%]
From: [% Param('mailfrom') %]
To: [% recipient.email %]
-Subject: [[% terms.Bugzilla %]] Overdue Requests Report
+Subject: [[% terms.Bugzilla %]] Overdue Requests
Date: [% date %]
X-Bugzilla-Type: nag-watch
diff --git a/extensions/RequestNagger/template/en/default/email/request_nagging-watching.html.tmpl b/extensions/RequestNagger/template/en/default/email/request_nagging-watching.html.tmpl
index 91fb36e1d..14e4d7f4e 100644
--- a/extensions/RequestNagger/template/en/default/email/request_nagging-watching.html.tmpl
+++ b/extensions/RequestNagger/template/en/default/email/request_nagging-watching.html.tmpl
@@ -18,70 +18,55 @@
<body bgcolor="#ffffff">
<p>
- The following is a list of people who you are watching that have overdue
- requests.
+ The following is a list of people who you are watching that are involved in
+ overdue requests.
</p>
-<hr>
-
[% FOREACH login = requests.keys.sort %]
- [% requestee = requests.$login.requestee %]
- [% requestee.identity FILTER html %]
+ [%
+ target = requests.item(login).target;
+ requestee = requests.item(login).requestee;
+ setter = requests.item(login).setter;
+ summary = requests.item(login).summary;
+ bug_ids = requests.item(login).bug_ids;
+ %]
+ <h3>
+ [% target.realname || target.login FILTER html %]
+ </h3>
<ul>
- <li>
- [%+ FOREACH type = requests.$login.typelist %]
- [% requests.$login.types.item(type).size %] [%+ type FILTER html %]
- [% ", " UNLESS loop.last %]
- [% END %]
+ [% IF requestee.size %]
+ <li>
+ Requested of: [% summary.requestee FILTER html %]
+ (<a href="[% urlbase FILTER none %]buglist.cgi?bug_id=[% bug_ids.requestee.join(",") FILTER uri %]">buglist</a>)
+ </li>
+ [% END %]
+ [% IF setter.size %]
+ <li>
+ Waiting on: [% summary.setter FILTER html %]
+ (<a href="[% urlbase FILTER none %]buglist.cgi?bug_id=[% bug_ids.setter.join(",") FILTER uri %]">buglist</a>)
+ </li>
+ [% END %]
</li>
</ul>
[% END %]
[% FOREACH login = requests.keys.sort %]
- [% requestee = requests.$login.requestee %]
-
- [% bug_ids = [] %]
- [% FOREACH type = requests.$login.typelist %]
- [% FOREACH request = requests.$login.types.$type %]
- [% bug_ids.push(request.bug.id) %]
- [% END %]
- [% END %]
+ [%
+ target = requests.item(login).target;
+ requestee = requests.item(login).requestee;
+ setter = requests.item(login).setter;
+ summary = requests.item(login).summary;
+ types = requests.item(login).types;
+ %]
<hr>
+
<h3>
- [% requestee.identity FILTER html %]
- <span style="font-size: x-small; font-weight: normal">
- (<a href="[% urlbase FILTER none %]buglist.cgi?bug_id=[% bug_ids.join(",") FILTER uri %]">buglist</a>)
- </span><br>
- <span style="font-size: x-small; font-weight: normal">
- [% FOREACH type = requests.$login.typelist %]
- [% requests.$login.types.item(type).size %] [%+ type FILTER html %]
- [% ", " UNLESS loop.last %]
- [% END %]
- </span>
+ [% target.realname || target.login FILTER html %]<br>
</h3>
- [% FOREACH type = requests.$login.typelist %]
-
- <h3>[% type FILTER upper FILTER html %] requests</h3>
-
- <ul>
- [% FOREACH request = requests.$login.types.$type %]
- <li>
- <a href="[% urlbase FILTER none %]show_bug.cgi?id=[% request.bug.id FILTER none %]"
- title="[% request.bug.tooltip FILTER html %]">
- [% request.bug.id FILTER none %] - [% request.bug.short_desc FILTER html %]
- </a><br>
- <b>[%+ request.flag.age FILTER html %]</b> from [% request.requester.identity FILTER html %]<br>
- [% IF request.flag.deferred %]
- Deferred until [%+ request.flag.deferred.ymd FILTER html %]<br>
- [% END %]
- <br>
- </li>
- [% END %]
- </ul>
-
- [% END %]
+ [% PROCESS requests report="requestee" request_list=requestee %]
+ [% PROCESS requests report="setter" request_list=setter %]
[% END %]
@@ -102,3 +87,39 @@
@@body-headers@@
</body>
</html>
+
+[% BLOCK requests %]
+ [% RETURN UNLESS request_list.size %]
+ [% FOREACH type IN types.item(report) %]
+
+ <h3>
+ [% type FILTER upper FILTER html %]
+ [%= report == "requestee" ? "requested of" : "waiting on" FILTER none %]
+ </h3>
+
+ <ul>
+ [% FOREACH request IN request_list.item(type) %]
+ <li>
+ <a href="[% urlbase FILTER none %]show_bug.cgi?id=[% request.bug.id FILTER none %]"
+ title="[% request.bug.tooltip FILTER html %]">
+ [% request.bug.id FILTER none %] - [% request.bug.short_desc FILTER html %]
+ </a><br>
+
+ <b>[% request.flag.age FILTER html %]</b>
+ [% IF report == "requestee" %]
+ from [% request.setter.realname || request.setter.login FILTER html %]
+ [% ELSE %]
+ to [% request.requestee.realname || request.requestee.login FILTER html %]
+ [% END %]
+
+ [% IF request.flag.deferred %]
+ <br>
+ Deferred until [%+ request.flag.deferred.ymd FILTER html %]<br>
+ [% END %]
+ </li>
+ [% END %]
+ </ul>
+
+ [% END %]
+
+[% END %]
diff --git a/extensions/RequestNagger/template/en/default/email/request_nagging-watching.txt.tmpl b/extensions/RequestNagger/template/en/default/email/request_nagging-watching.txt.tmpl
index 8bc5a3b7c..0e80cc73c 100644
--- a/extensions/RequestNagger/template/en/default/email/request_nagging-watching.txt.tmpl
+++ b/extensions/RequestNagger/template/en/default/email/request_nagging-watching.txt.tmpl
@@ -8,32 +8,28 @@
[% PROCESS "global/field-descs.none.tmpl" %]
-The following is a list of people who you are watching that have overdue
-requests.
+[% FOREACH login IN requests.keys.sort %]
+[%
+ target = requests.item(login).target;
+ requestee = requests.item(login).requestee;
+ setter = requests.item(login).setter;
+ summary = requests.item(login).summary;
+ types = requests.item(login).types;
+%]
-[% FOREACH login = requests.keys.sort %]
-[% requestee = requests.$login.requestee %]
::
-:: [% requestee.identity %]
-:: [% FOREACH type = requests.$login.typelist %]
- [%- requests.$login.types.item(type).size %] [%+ type %]
- [% ", " UNLESS loop.last %]
- [% END %]
+:: [% target.identity %]
+[% IF requestee.size %]
+:: Requested of: [% summary.requestee %]
+[% END %]
+[% IF setter.size %]
+:: Waiting on: [% summary.setter %]
+[% END %]
::
-[% FOREACH type = requests.$login.typelist %]
-:: [% type FILTER upper FILTER html %] requests
+[%+ PROCESS requests report="requestee" request_list=requestee %]
-[% FOREACH request = requests.$login.types.$type %]
-[[% terms.Bug %] [%+ request.bug.id %]] [% request.bug.short_desc %]
- [%+ request.flag.age %] from [% request.requester.identity %]
- [%+ urlbase %]show_bug.cgi?id=[% request.bug.id +%]
- [% IF request.flag.deferred %]
- Deferred until [%+ request.flag.deferred.ymd %]
- [% END %]
-
-[% END %]
-[% END %]
+[%+ PROCESS requests report="setter" request_list=setter %]
[% END %]
@@ -47,3 +43,26 @@ You are receiving this mail because: you are watching someone with overdue
requests.
@@body-headers@@
+
+[% BLOCK requests %]
+[% RETURN UNLESS request_list.size %]
+
+[% FOREACH type IN types.item(report) %]
+:: [% type FILTER upper %] [%= report == "requestee" ? "requested of" : "waiting on" %]
+
+[% FOREACH request IN request_list.item(type) %]
+[[% terms.Bug %] [%+ request.bug.id %]] [% request.bug.short_desc %]
+ [% IF report == "requestee" %]
+ [%+ request.flag.age %] from [% request.setter.realname || request.setter.login %]
+ [% ELSE %]
+ [%+ request.flag.age %] to [% request.requestee.realname || request.requestee.login %]
+ [% END %]
+ [%+ urlbase %]show_bug.cgi?id=[% request.bug.id +%]
+ [% IF request.flag.deferred %]
+ Deferred until [%+ request.flag.deferred.ymd %]
+ [% END %]
+
+[% END %]
+[% END %]
+
+[% END %]