Support for data munging in User Reports
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
* Wildcard support on Device Port MAC Search
|
* Wildcard support on Device Port MAC Search
|
||||||
* Wildcard support on Node name/MAC Search
|
* Wildcard support on Node name/MAC Search
|
||||||
* User Reports appear in "My Reports" menu if no category is given
|
* User Reports appear in "My Reports" menu if no category is given
|
||||||
|
* (beta) Support for data munging in User Reports
|
||||||
* Permit clipboard copy of device IP from Job Queue rows
|
* Permit clipboard copy of device IP from Job Queue rows
|
||||||
* Failed Job Device IPs link to Discover form with pre-filled Discover IP
|
* Failed Job Device IPs link to Discover form with pre-filled Discover IP
|
||||||
* Unknown device page has pre-filled Discover IP
|
* Unknown device page has pre-filled Discover IP
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ requires 'Net::LDAP' => 0;
|
|||||||
requires 'Net::MAC' => 2.103622;
|
requires 'Net::MAC' => 2.103622;
|
||||||
requires 'Net::NBName' => 0.26;
|
requires 'Net::NBName' => 0.26;
|
||||||
requires 'NetAddr::IP' => 4.068;
|
requires 'NetAddr::IP' => 4.068;
|
||||||
|
requires 'Opcode' => 1.07;
|
||||||
requires 'Path::Class' => 0.32;
|
requires 'Path::Class' => 0.32;
|
||||||
requires 'Plack' => 1.0023;
|
requires 'Plack' => 1.0023;
|
||||||
requires 'Plack::Middleware::Expires' => 0.03;
|
requires 'Plack::Middleware::Expires' => 0.03;
|
||||||
|
|||||||
@@ -243,8 +243,14 @@ code or HTML templates. For example:
|
|||||||
ORDER BY name
|
ORDER BY name
|
||||||
|
|
||||||
Each key of the C<reports> configuration is an alias for the report, and
|
Each key of the C<reports> configuration is an alias for the report, and
|
||||||
becomes part of the web path. Within the tree you must provide each of the
|
becomes part of the web path.
|
||||||
keys shown:
|
|
||||||
|
You can munge the data retrieved from the database by placing a Perl script
|
||||||
|
with the same name as the C<reports> key into the C<site_plugins> directory of
|
||||||
|
Netdisco's home area. The script can access C<$config> for its configuration
|
||||||
|
and C<@data> for the retrieved data. It should return a list of munged data.
|
||||||
|
|
||||||
|
Within the tree you can provide each of the keys below:
|
||||||
|
|
||||||
=head4 C<label>
|
=head4 C<label>
|
||||||
|
|
||||||
@@ -258,8 +264,9 @@ heading.
|
|||||||
=head4 C<query>
|
=head4 C<query>
|
||||||
|
|
||||||
SQL which returns the data. Make sure that the columns are named the same as
|
SQL which returns the data. Make sure that the columns are named the same as
|
||||||
the keys of the C<columns> configuration. Note the way the SQL is specified in
|
the keys of the C<columns> or C<query_columns> configuration. Note the way the
|
||||||
the example above, using the pipe symbol and then indenting the query text.
|
SQL is specified in the example above, using the pipe symbol and then
|
||||||
|
indenting the query text.
|
||||||
|
|
||||||
=head4 C<category> (optional)
|
=head4 C<category> (optional)
|
||||||
|
|
||||||
@@ -267,6 +274,13 @@ Section of the Reports menu where this report will appear. See
|
|||||||
L<WritingPlugins|App::Netdisco::Manual::WritingPlugins> for the full list.
|
L<WritingPlugins|App::Netdisco::Manual::WritingPlugins> for the full list.
|
||||||
If not supplied, reports appear in a I<My Reports> category.
|
If not supplied, reports appear in a I<My Reports> category.
|
||||||
|
|
||||||
|
=head4 C<query_columns> (optional)
|
||||||
|
|
||||||
|
If supplying code to munge the data, the columns returned from your database
|
||||||
|
C<query> may not be the same as those in the web report. Set this to a list of
|
||||||
|
the columns in C<query>. The C<columns> setting will then be used for the web
|
||||||
|
report.
|
||||||
|
|
||||||
=head3 C<jobqueue_refresh>
|
=head3 C<jobqueue_refresh>
|
||||||
|
|
||||||
Value: Integer Number. Default: 5.
|
Value: Integer Number. Default: 5.
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ use Dancer::Plugin::DBIC;
|
|||||||
use Dancer::Plugin::Auth::Extensible;
|
use Dancer::Plugin::Auth::Extensible;
|
||||||
|
|
||||||
use App::Netdisco::Web::Plugin;
|
use App::Netdisco::Web::Plugin;
|
||||||
|
use Path::Class 'file';
|
||||||
|
use Safe;
|
||||||
|
|
||||||
# in case user did not set
|
use vars qw/$config @data/;
|
||||||
config->{reports} ||= {};
|
|
||||||
|
|
||||||
foreach my $r (keys %{setting('reports')}) {
|
foreach my $r (keys %{setting('reports')}) {
|
||||||
my $report = setting('reports')->{$r};
|
my $report = setting('reports')->{$r};
|
||||||
@@ -23,28 +24,44 @@ foreach my $r (keys %{setting('reports')}) {
|
|||||||
get "/ajax/content/report/$r" => require_login sub {
|
get "/ajax/content/report/$r" => require_login sub {
|
||||||
my $rs = schema('netdisco')->resultset('Virtual::GenericReport')->result_source;
|
my $rs = schema('netdisco')->resultset('Virtual::GenericReport')->result_source;
|
||||||
|
|
||||||
# this should be done by creating a new Virtual Result class on the fly
|
# TODO: this should be done by creating a new Virtual Result class on
|
||||||
# (package...) and then calling DBIC register_class on it.
|
# the fly (package...) and then calling DBIC register_class on it.
|
||||||
|
|
||||||
$rs->view_definition($report->{query});
|
$rs->view_definition($report->{query});
|
||||||
$rs->remove_columns($rs->columns);
|
$rs->remove_columns($rs->columns);
|
||||||
$rs->add_columns(map {keys %{$_}} @{$report->{columns}});
|
$rs->add_columns( exists $report->{query_columns}
|
||||||
|
? @{ $report->{query_columns} }
|
||||||
|
: (map {keys %{$_}} @{$report->{columns}})
|
||||||
|
);
|
||||||
|
|
||||||
my $set = schema('netdisco')->resultset('Virtual::GenericReport');
|
my $set = schema('netdisco')->resultset('Virtual::GenericReport')
|
||||||
return unless $set->count;
|
->search(undef, {result_class => 'DBIx::Class::ResultClass::HashRefInflator'});
|
||||||
|
@data = $set->all;
|
||||||
|
|
||||||
|
# Data Munging support...
|
||||||
|
|
||||||
|
my $compartment = Safe->new;
|
||||||
|
$config = setting('reports')->{$r};
|
||||||
|
$compartment->share(qw/$config @data/);
|
||||||
|
$compartment->permit_only(qw/:default sort/);
|
||||||
|
|
||||||
|
my $munger = file(($ENV{NETDISCO_HOME} || $ENV{HOME}), 'site_plugins', $r)->stringify;
|
||||||
|
my @results = ((-f $munger) ? $compartment->rdo( $munger ) : @data);
|
||||||
|
return if $@ or (0 == scalar @results);
|
||||||
|
|
||||||
if (request->is_ajax) {
|
if (request->is_ajax) {
|
||||||
template 'ajax/report/generic_report.tt',
|
template 'ajax/report/generic_report.tt',
|
||||||
{ results => $set,
|
{ results => \@results,
|
||||||
headings => [map {values %{$_}} @{$report->{columns}}],
|
headings => [map {values %{$_}} @{$report->{columns}}],
|
||||||
columns => [$rs->columns] },
|
columns => [map {keys %{$_}} @{$report->{columns}}] },
|
||||||
{ layout => undef };
|
{ layout => undef };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||||
template 'ajax/report/generic_report_csv.tt',
|
template 'ajax/report/generic_report_csv.tt',
|
||||||
{ results => $set,
|
{ results => \@results,
|
||||||
headings => [map {values %{$_}} @{$report->{columns}}],
|
headings => [map {values %{$_}} @{$report->{columns}}],
|
||||||
columns => [$rs->columns] },
|
columns => [map {keys %{$_}} @{$report->{columns}}] },
|
||||||
{ layout => undef };
|
{ layout => undef };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ web_plugins:
|
|||||||
extra_web_plugins: []
|
extra_web_plugins: []
|
||||||
jobqueue_refresh: 10
|
jobqueue_refresh: 10
|
||||||
safe_password_store: true
|
safe_password_store: true
|
||||||
|
reports: {}
|
||||||
|
|
||||||
# -------------
|
# -------------
|
||||||
# NETDISCO CORE
|
# NETDISCO CORE
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</tbody>
|
</tbody>
|
||||||
[% WHILE (row = results.next) %]
|
[% FOREACH row IN results %]
|
||||||
<tr>
|
<tr>
|
||||||
[% FOREACH col IN columns %]
|
[% FOREACH col IN columns %]
|
||||||
<td>[% row.get_column(col) | html_entity %]</td>
|
<td>[% row.item(col) | html_entity %]</td>
|
||||||
[% END %]
|
[% END %]
|
||||||
</tr>
|
</tr>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
[% USE CSV %]
|
[% USE CSV %]
|
||||||
[% CSV.dump(headings) %]
|
[% CSV.dump(headings) %]
|
||||||
|
|
||||||
[% FOREACH row IN results.all %]
|
[% FOREACH row IN results %]
|
||||||
[% mylist = [] %]
|
[% mylist = [] %]
|
||||||
[% FOREACH col IN columns %]
|
[% FOREACH col IN columns %]
|
||||||
[% mylist.push(row.get_column(col)) %]
|
[% mylist.push(row.item(col)) %]
|
||||||
[% END %]
|
[% END %]
|
||||||
[% CSV.dump(mylist) %]
|
[% CSV.dump(mylist) %]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user