<commit_before>package CCNQ::Portal::Inner::provisioning;
# Copyright (C) 2009  <NAME>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
use strict; use warnings;

use Dancer ':syntax';
use CCNQ::Portal;
use CCNQ::Portal::I18N;
use CCNQ::Portal::Util;
use CCNQ::Portal::Inner::Util;
use CCNQ::API;

use CCNQ::AE;

=head1 Formatters

=head2 to_html

=head2 as_json

=head2 as_tabs

=cut

use constant hidden_columns => qr/^_|^account|^action|^api|^cluster|^request|^type|^endpoint_ip|^profile/;

sub to_html {
  my $cv = shift;
  var template_name => 'provisioning';
  $cv and var result => sub { CCNQ::AE::receive_docs($cv) };
  return CCNQ::Portal::content;
}

sub as_json {
  my $cv = shift;
  $cv or return send_error();
  content_type 'text/json';
  header 'Content-Disposition' => qq(attachment; filename="export.json");
  return to_json($cv->recv);
}

sub as_tabs {
  my $cv = shift;
  $cv or return send_error();
  content_type 'text/tab-separated-values';
  header 'Content-Disposition' => qq(attachment; filename="export.csv");
  my $result = CCNQ::AE::receive_docs($cv);
  $result->[0] or return "";
  my @columns = sort grep { !hidden_columns } keys %{ $result->[0] };
  unshift $result->[0]->{profile}, @columns;
  return
    # header row
    join("\t", map { _($_)_ } @columns)."\n".
    # data rows
    join('', map {
      join("\t", map { defined($_) ? $_ : '' } @{$_}{@columns})."\n"  # everybody love hashref slices!
    } @$result);
}

=head1 /provisioning/view/:view/@id

Retrieve a view for the current (session) account.

=cut

sub _view_id {
  my $account = CCNQ::Portal::Inner::Util::validate_account;

  CCNQ::Portal->current_session->user &&
  $account
    or return;

  my $id = params->{id};

  my $cv = AE::cv;
  if($id eq '_all') {
    CCNQ::API::provisioning('report',params->{view},$account,$cv);
  } else {
    CCNQ::API::provisioning('report',params->{view},$account,$id,$cv);
  }
  return $cv;
}

get '/provisioning/view/:view/:id.html' => sub { to_html(_view_id) };
get '/provisioning/view/:view/:id.json' => sub { as_json(_view_id) };
get '/provisioning/view/:view/:id.tabs' => sub { as_tabs(_view_id) };

get '/provisioning/page/:view.html' => sub {
  CCNQ::Portal::Inner::Util::validate_account;

  my $page = int(params->{page} || 0);
  if($page) {
    return paginate_html($page,_view_page($page));
  } else {
    var template_name => 'provisioning-paginate';
    return CCNQ::Portal::content;
  }
};

use constant default_limit => 25;

sub paginate_html {
  my ($page,$cv) = @_;
  $cv or return send_error();

  my $limit = int(params->{limit} || default_limit);

  my $answer = CCNQ::AE::receive($cv);
  my $result = [ map { $_->{doc} } @{$answer->{rows}} ];

  $result->[0] or $page = 1;

  my $navigation = '';

  $page > 1
    and $navigation .= sprintf(
      q(<a href="?page=%d&limit=%d" class="prev_page">&larr;</a>),
      $page-1, $limit,
    );

  $navigation .= qq(<span class="current_page">$page</span>);

  $#$result < $limit
  and $navigation .= sprintf(
    q(<a href="?page=%d&limit=%d" class="next_page">&rarr;</a>),
    $page+1, $limit,
  );

  $navigation .= q(<select class="per_page">);
  $navigation .= join('', map {
    sprintf( q(<option value="%d" %s>%d</option>),
    $_, ($_ == $limit ? 'selected' : ''), $_ )
  } qw( 10 25 50 100 ));
  $navigation .= q(</select>);

  $result->[0] or return $navigation;

  my @columns = sort grep { !hidden_columns } keys %{ $result->[0] };
  unshift $result->[0]->{profile}, @columns;

  return $navigation .
    q(<table>).
    # header row<commit_msg>syntax<commit_after>package CCNQ::Portal::Inner::provisioning;
# Copyright (C) 2009  <NAME>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
use strict; use warnings;

use Dancer ':syntax';
use CCNQ::Portal;
use CCNQ::Portal::I18N;
use CCNQ::Portal::Util;
use CCNQ::Portal::Inner::Util;
use CCNQ::API;

use CCNQ::AE;

=head1 Formatters

=head2 to_html

=head2 as_json

=head2 as_tabs

=cut

use constant hidden_columns => qr/^_|^account|^action|^api|^cluster|^request|^type|^endpoint_ip|^profile/;

sub to_html {
  my $cv = shift;
  var template_name => 'provisioning';
  $cv and var result => sub { CCNQ::AE::receive_docs($cv) };
  return CCNQ::Portal::content;
}

sub as_json {
  my $cv = shift;
  $cv or return send_error();
  content_type 'text/json';
  header 'Content-Disposition' => qq(attachment; filename="export.json");
  return to_json($cv->recv);
}

sub as_tabs {
  my $cv = shift;
  $cv or return send_error();
  content_type 'text/tab-separated-values';
  header 'Content-Disposition' => qq(attachment; filename="export.csv");
  my $result = CCNQ::AE::receive_docs($cv);
  $result->[0] or return "";
  my @columns = sort grep { !hidden_columns } keys %{ $result->[0] };
  unshift @columsn, $result->[0]->{profile};
  return
    # header row
    join("\t", map { _($_)_ } @columns)."\n".
    # data rows
    join('', map {
      join("\t", map { defined($_) ? $_ : '' } @{$_}{@columns})."\n"  # everybody love hashref slices!
    } @$result);
}

=head1 /provisioning/view/:view/@id

Retrieve a view for the current (session) account.

=cut

sub _view_id {
  my $account = CCNQ::Portal::Inner::Util::validate_account;

  CCNQ::Portal->current_session->user &&
  $account
    or return;

  my $id = params->{id};

  my $cv = AE::cv;
  if($id eq '_all') {
    CCNQ::API::provisioning('report',params->{view},$account,$cv);
  } else {
    CCNQ::API::provisioning('report',params->{view},$account,$id,$cv);
  }
  return $cv;
}

get '/provisioning/view/:view/:id.html' => sub { to_html(_view_id) };
get '/provisioning/view/:view/:id.json' => sub { as_json(_view_id) };
get '/provisioning/view/:view/:id.tabs' => sub { as_tabs(_view_id) };

get '/provisioning/page/:view.html' => sub {
  CCNQ::Portal::Inner::Util::validate_account;

  my $page = int(params->{page} || 0);
  if($page) {
    return paginate_html($page,_view_page($page));
  } else {
    var template_name => 'provisioning-paginate';
    return CCNQ::Portal::content;
  }
};

use constant default_limit => 25;

sub paginate_html {
  my ($page,$cv) = @_;
  $cv or return send_error();

  my $limit = int(params->{limit} || default_limit);

  my $answer = CCNQ::AE::receive($cv);
  my $result = [ map { $_->{doc} } @{$answer->{rows}} ];

  $result->[0] or $page = 1;

  my $navigation = '';

  $page > 1
    and $navigation .= sprintf(
      q(<a href="?page=%d&limit=%d" class="prev_page">&larr;</a>),
      $page-1, $limit,
    );

  $navigation .= qq(<span class="current_page">$page</span>);

  $#$result < $limit
  and $navigation .= sprintf(
    q(<a href="?page=%d&limit=%d" class="next_page">&rarr;</a>),
    $page+1, $limit,
  );

  $navigation .= q(<select class="per_page">);
  $navigation .= join('', map {
    sprintf( q(<option value="%d" %s>%d</option>),
    $_, ($_ == $limit ? 'selected' : ''), $_ )
  } qw( 10 25 50 100 ));
  $navigation .= q(</select>);

  $result->[0] or return $navigation;

  my @columns = sort grep { !hidden_columns } keys %{ $result->[0] };
  unshift @columns, $result->[0]->{profile};

  return $navigation .
    q(<table>).
    # header row
{'fraction_non_alphanumeric': 0.18369552167126907, 'fraction_numerical': 0.008404370272541721, 'mean_word_length': 4.0638297872340425, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '8420', 'n_tokens_mistral': 3034, 'n_tokens_neox': 2938, 'n_words': 753}