summaryrefslogtreecommitdiffstats
path: root/extensions/RequestNagger/bin/send-request-nags.pl
diff options
context:
space:
mode:
authorByron Jones <glob@mozilla.com>2015-05-19 14:46:40 +0200
committerByron Jones <glob@mozilla.com>2015-05-19 14:46:40 +0200
commit70b298ecbd3aba8f24bf6d0147bece13b81d6040 (patch)
treeb150bd979da130f3bfc7f361730ff9f63f1baa0b /extensions/RequestNagger/bin/send-request-nags.pl
parenta92ec2797af87cb17fff925ccd8c739f6d21ea79 (diff)
downloadbugzilla-70b298ecbd3aba8f24bf6d0147bece13b81d6040.tar.gz
bugzilla-70b298ecbd3aba8f24bf6d0147bece13b81d6040.tar.xz
Bug 1163868: Include requests from others in RequestNagger
Diffstat (limited to 'extensions/RequestNagger/bin/send-request-nags.pl')
-rwxr-xr-xextensions/RequestNagger/bin/send-request-nags.pl316
1 files changed, 180 insertions, 136 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 });
}
}
-