--- /dev/null
+# 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.
+
+package Bugzilla::Job::RunTask;
+
+use 5.10.1;
+use strict;
+use warnings;
+
+use parent 'TheSchwartz::Worker';
+
+use constant grab_for => 300;
+use constant max_retries => 0;
+
+use Bugzilla::Logging;
+use Module::Runtime qw(require_module);
+use Scalar::Util qw(blessed);
+use Email::MIME;
+use Bugzilla::Mailer qw(MessageToMTA);
+
+sub work {
+ my ($class, $job) = @_;
+ my $task = $job->arg;
+ my $task_class = blessed($task) // '';
+ die "Invalid task class: $task_class"
+ unless $task_class =~ /^Bugzilla::Task::/;
+ require_module($task_class);
+
+ my $template = Bugzilla->template;
+ my $vars = $task->run();
+ my $name = $task->name;
+ my $html = "";
+ my $ok = $template->process("email/task/$name.html.tmpl", $vars, \$html);
+
+ unless ($ok) {
+ FATAL($template->error);
+ $html = "Something went run running task '$name'";
+ }
+
+ my @parts = (
+ Email::MIME->create(
+ attributes => {
+ content_type => 'text/html',
+ charset => 'UTF-8',
+ encoding => 'quoted-printable',
+ },
+ body_str => $html,
+ ),
+ );
+
+ my $email = Email::MIME->create(
+ header_str => [
+ From => Bugzilla->params->{'mailfrom'},
+ To => $task->user->email,
+ Subject => $task->subject,
+ 'X-Bugzilla-Type' => 'task',
+ ],
+ parts => [@parts],
+ );
+
+ # We're already in the jobqueue, so send right away.
+ MessageToMTA($email, 1);
+
+ $job->completed;
+}
+
+
+1;
use IO::Async::Loop;
use Future;
use base qw(TheSchwartz);
+use Bugzilla::Types qw(Task);
+use Type::Params qw( compile Invocant );
# This maps job names for Bugzilla::JobQueue to the appropriate modules.
# If you add new types of jobs, you should add a mapping here.
use constant JOB_MAP => {
send_mail => 'Bugzilla::Job::Mailer',
bug_mail => 'Bugzilla::Job::BugMail',
+ run_task => 'Bugzilla::Job::RunTask',
};
# Without a driver cache TheSchwartz opens a new database connection
return map { $self->driver_for($_) } @hashes;
}
+sub run_task {
+ state $check = compile(Invocant, Task);
+ my ($self, $task) = $check->(@_);
+
+ $task->prepare;
+
+ return $self->insert(run_task => $task);
+}
+
# inserts a job into the queue to be processed and returns immediately
sub insert {
my $self = shift;
--- /dev/null
+# 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.
+
+package Bugzilla::Task;
+use 5.10.1;
+use Moo::Role;
+
+use Bugzilla::Constants;
+use Bugzilla::Logging;
+use Bugzilla::Types qw(User);
+use Types::Standard qw(Str);
+use Type::Utils;
+use Scalar::Util qw(blessed);
+use Mojo::Util qw(decamelize);
+use Try::Tiny;
+use Capture::Tiny qw(capture_stdout);
+
+requires 'prepare', 'run', 'subject', '_build_estimated_duration';
+
+my $Duration = class_type { class => 'DateTime::Duration' };
+
+has 'user' => (is => 'ro', isa => User, required => 1);
+has 'name' => (is => 'lazy', isa => Str, init_arg => undef);
+has 'estimated_duration' => (is => 'lazy', isa => $Duration, init_arg => undef);
+
+around 'run' => sub {
+ my ($original_method, $self, @args) = @_;
+ my $scope = Bugzilla->set_user($self->user, scope_guard => 1);
+ Bugzilla->error_mode(ERROR_MODE_MOJO);
+ my $result;
+ try {
+ my $stdout = capture_stdout {
+ $result = $self->$original_method(@args);
+ };
+ if ($stdout) {
+ FATAL("$self sent output to STDOUT: $stdout");
+ }
+ }
+ catch {
+ $result = {error => $_};
+ };
+ return $result;
+};
+
+sub _build_name {
+ my ($self) = @_;
+ my $class = blessed($self);
+ my $pkg = __PACKAGE__;
+ $class =~ s/^\Q$pkg\E:://;
+ return decamelize($class);
+}
+
+1;
use Type::Library
-base,
- -declare => qw( Bug User Group Attachment Comment JSONBool );
+ -declare => qw( Bug User Group Attachment Comment JSONBool Task );
use Type::Utils -all;
use Types::Standard -types;
class_type Attachment, { class => 'Bugzilla::Attachment' };
class_type Comment, { class => 'Bugzilla::Comment' };
class_type JSONBool, { class => 'JSON::PP::Boolean' };
+role_type Task, { role => 'Bugzilla::Task' };
1;