@@ -155,4 +155,12 @@ between the date stamp and time stamp. That is:
|
||||
|
||||
sub finished_stamp { return (shift)->get_column('finished_stamp') }
|
||||
|
||||
=head2 duration
|
||||
|
||||
Difference between started and finished.
|
||||
|
||||
=cut
|
||||
|
||||
sub duration { return (shift)->get_column('duration') }
|
||||
|
||||
1;
|
||||
|
||||
@@ -46,6 +46,8 @@ will add the following additional synthesized columns to the result set:
|
||||
|
||||
=item finished_stamp
|
||||
|
||||
=item duration
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
@@ -58,9 +60,10 @@ sub with_times {
|
||||
->search({},
|
||||
{
|
||||
'+columns' => {
|
||||
entered_stamp => \"to_char(entered, 'YYYY-MM-DD HH24:MI')",
|
||||
started_stamp => \"to_char(started, 'YYYY-MM-DD HH24:MI')",
|
||||
finished_stamp => \"to_char(finished, 'YYYY-MM-DD HH24:MI')",
|
||||
entered_stamp => \"to_char(entered, 'YYYY-MM-DD HH24:MI:SS')",
|
||||
started_stamp => \"to_char(started, 'YYYY-MM-DD HH24:MI:SS')",
|
||||
finished_stamp => \"to_char(finished, 'YYYY-MM-DD HH24:MI:SS')",
|
||||
duration => \"justify_interval(extract(epoch FROM (finished - started)) * interval '1 second')",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -257,10 +257,39 @@ sub jq_complete {
|
||||
|
||||
sub jq_log {
|
||||
return schema(vars->{'tenant'})->resultset('Admin')->search({
|
||||
'me.action' => { '-not_like' => 'hook::%' },
|
||||
-or => [
|
||||
{ 'me.log' => undef },
|
||||
{ 'me.log' => { '-not_like' => 'duplicate of %' } },
|
||||
(param('backend') ? (
|
||||
'me.status' => { '=' => [
|
||||
# FIXME 'done-'. param('backend'),
|
||||
'queued-'. param('backend'),
|
||||
] },
|
||||
) : ()),
|
||||
(param('action') ? ('me.action' => param('action')) : ()),
|
||||
(param('device') ? (
|
||||
-or => [
|
||||
{ 'me.device' => param('device') },
|
||||
{ 'target.ip' => param('device') },
|
||||
],
|
||||
) : ()),
|
||||
(param('username') ? ('me.username' => param('username')) : ()),
|
||||
(param('status') ? ('me.status' => lc(param('status'))) : ()),
|
||||
(param('duration') ? (
|
||||
-bool => [
|
||||
-or => [
|
||||
{
|
||||
'me.finished' => undef,
|
||||
'me.started' => { '<' => \[q{(CURRENT_TIMESTAMP - ? ::interval)}, param('duration') .' minutes'] },
|
||||
},
|
||||
-and => [
|
||||
{ 'me.started' => { '!=' => undef } },
|
||||
{ 'me.finished' => { '!=' => undef } },
|
||||
\[ q{ (me.finished - me.started) > ? ::interval }, param('duration') .' minutes'],
|
||||
],
|
||||
],
|
||||
],
|
||||
) : ()),
|
||||
'me.log' => [
|
||||
{ '=' => undef },
|
||||
{ '-not_like' => 'duplicate of %' },
|
||||
],
|
||||
}, {
|
||||
prefetch => 'target',
|
||||
|
||||
@@ -24,6 +24,7 @@ ajax '/ajax/control/admin/jobqueue/delall' => require_role admin => sub {
|
||||
|
||||
ajax '/ajax/content/admin/jobqueue' => require_role admin => sub {
|
||||
content_type('text/html');
|
||||
|
||||
template 'ajax/admintask/jobqueue.tt', {
|
||||
results => [ jq_log ],
|
||||
}, { layout => undef };
|
||||
|
||||
@@ -7,6 +7,90 @@ use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
use App::Netdisco::Util::Web (); # for sort_port
|
||||
use HTML::Entities 'encode_entities';
|
||||
use List::MoreUtils ();
|
||||
|
||||
ajax '/ajax/data/queue/typeahead/backend' => require_role admin => sub {
|
||||
return '[]' unless setting('navbar_autocomplete');
|
||||
|
||||
my $q = quotemeta( param('query') || param('term') || param('backend') );
|
||||
my @backends =
|
||||
grep { $q ? m/$q/ : true }
|
||||
List::MoreUtils::uniq
|
||||
sort
|
||||
grep { defined }
|
||||
schema(vars->{'tenant'})->resultset('DeviceSkip')->get_distinct_col('backend');
|
||||
|
||||
content_type 'application/json';
|
||||
to_json \@backends;
|
||||
};
|
||||
|
||||
ajax '/ajax/data/queue/typeahead/username' => require_role admin => sub {
|
||||
return '[]' unless setting('navbar_autocomplete');
|
||||
|
||||
my $q = quotemeta( param('query') || param('term') || param('username') );
|
||||
my @users =
|
||||
grep { $q ? m/$q/ : true }
|
||||
List::MoreUtils::uniq
|
||||
sort
|
||||
grep { defined }
|
||||
schema(vars->{'tenant'})->resultset('Admin')->get_distinct_col('username');
|
||||
|
||||
content_type 'application/json';
|
||||
to_json \@users;
|
||||
};
|
||||
|
||||
ajax '/ajax/data/queue/typeahead/action' => require_role admin => sub {
|
||||
return '[]' unless setting('navbar_autocomplete');
|
||||
|
||||
my @actions = ();
|
||||
my @core_plugins = @{ setting('worker_plugins') || [] };
|
||||
my @user_plugins = @{ setting('extra_worker_plugins') || [] };
|
||||
|
||||
# load worker plugins for our action
|
||||
foreach my $plugin (@user_plugins, @core_plugins) {
|
||||
$plugin =~ s/^X::/+App::NetdiscoX::Worker::Plugin::/;
|
||||
$plugin = 'App::Netdisco::Worker::Plugin::'. $plugin
|
||||
if $plugin !~ m/^\+/;
|
||||
$plugin =~ s/^\+//;
|
||||
|
||||
next if $plugin =~ m/::Plugin::Internal::/;
|
||||
|
||||
if ($plugin =~ m/::Plugin::(Hook::[^:]+)/) {
|
||||
push @actions, lc $1;
|
||||
next;
|
||||
}
|
||||
|
||||
next unless $plugin =~ m/::Plugin::([^:]+)::/;
|
||||
push @actions, lc $1;
|
||||
}
|
||||
|
||||
my $q = quotemeta( param('query') || param('term') || param('action') );
|
||||
@actions =
|
||||
grep { $q ? m/^$q/ : true }
|
||||
List::MoreUtils::uniq
|
||||
sort
|
||||
grep { defined }
|
||||
@actions,
|
||||
schema(vars->{'tenant'})->resultset('Admin')->get_distinct_col('action');
|
||||
|
||||
content_type 'application/json';
|
||||
to_json \@actions;
|
||||
};
|
||||
|
||||
ajax '/ajax/data/queue/typeahead/status' => require_role admin => sub {
|
||||
return '[]' unless setting('navbar_autocomplete');
|
||||
|
||||
my $q = quotemeta( param('query') || param('term') || param('status') );
|
||||
my @actions =
|
||||
grep { $q ? m/^$q/ : true }
|
||||
List::MoreUtils::uniq
|
||||
sort
|
||||
grep { defined }
|
||||
qw(Queued Done Info Deferred Error);
|
||||
|
||||
content_type 'application/json';
|
||||
to_json \@actions;
|
||||
};
|
||||
|
||||
ajax '/ajax/data/devicename/typeahead' => require_login sub {
|
||||
return '[]' unless setting('navbar_autocomplete');
|
||||
|
||||
Reference in New Issue
Block a user