Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions bin/bulk_layout_permissions.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/perl

use FindBin;
use lib "$FindBin::Bin/../lib";

use Dancer2;
use Dancer2::Plugin::DBIC;
use Getopt::Long;
use Text::CSV;
use feature 'say';
use Log::Report syntax => 'LONG';

my ($action, $file);

GetOptions(
'action=s' => \$action,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be worth aligning the fat commas to keep the code neat.

'file=s' => \$file
) or exit;

$action or report ERROR => "Please state if you want to import/export group permissions with --action";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be worth aligning the fat commas for clarity across the script - it's done in other places in the stack too.

$file or report ERROR => "Please provide the file you want to import/export to/from with --file";
if ($action eq 'import') {
Import_permissions();
}
elsif ($action eq 'export') {
Export_permissions();
}
else {
report ERROR => "You must state if you want to import or export with --action";
}


sub Import_permissions {

-f $file or report ERROR => "File '$file' does not exist";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally better to use parameters, e.g. ERROR => "File '{file}' does not exist", file => $file


my $csv = Text::CSV->new({ binary => 1 })
or report ERROR => "Cannot use CSV: ".Text::CSV->error_diag ();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity, would be ideal to indent this line.

open my $fh, "<:encoding(utf8)", $file or report FAULT => "$file";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to write something like FAULT => "Unable to open file {file}", file => $file - the reason will be automatically appended when using FAULT

my $guard = schema->txn_scope_guard;

my $headers = $csv->getline($fh);
$csv->column_names(@$headers) if $headers;

report ERROR => "Invalid CSV header/s. Import must consist of 3 columns: layout_id, group_id and permission"
unless $headers && join(',', sort @$headers) eq 'group_id,layout_id,permission';

while (my $row = $csv->getline_hr($fh)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation of some lines within this while loop should be reviewed.


my $RowCount = $csv->record_number;
my $layout_id = $row->{layout_id};
my $group_id = $row->{group_id};
my $permission = $row->{permission};

unless (defined $layout_id && $layout_id =~ /^\d+$/) {
report ERROR => "ERROR: Invalid Layout ID '$layout_id' on row $RowCount.";
}
unless (defined $group_id && $group_id =~ /^\d+$/) {
Comment thread
Oliver-ctrlo marked this conversation as resolved.
report ERROR => "ERROR: Invalid Group ID '$row->{group_id}' on row $RowCount.";
}
unless (defined $permission && $permission =~ /^(?:read|write_new|write_existing|write_existing_no_approval|write_new_no_approval)$/) {
Comment thread
Oliver-ctrlo marked this conversation as resolved.
report ERROR => "Invalid Permission '$permission' on row $RowCount. Value must be read, write_new, write_existing, or write_existing_no_approval.";
}

rset('Layout')->find($layout_id) or report ERROR => "Layout ID '$layout_id' does not exist\n";
rset('Group')->find($group_id) or report ERROR => "Group ID '$group_id' does not exist\n";

my $existing = rset('LayoutGroup')->find({
layout_id => $layout_id,
group_id => $group_id,
permission => $permission
});

if ($existing) {
info "Skipping permission '$permission' for group '$group_id' on layout '$layout_id' because this permission already exists";
next;
}

rset('LayoutGroup')->create({
layout_id => $layout_id,
group_id => $group_id,
permission => $permission,
});
info "Will add permission '$permission' to group '$group_id' for layout '$layout_id'";
}
$guard->commit;
info "Import complete";
}

sub Export_permissions {
! -f $file or report ERROR => "$file already exists, unable to overwrite file!";
say "Enter the group IDs you're looking to export (e.g. 1,2,3): ";
my $input = <STDIN>;
chomp($input);

if (!$input || $input !~ /^\s*\d+(?:\s*,\s*\d+)*\s*$/) {
report ERROR => "You need to enter a number or a comma-separated list of numbers.\n";
}

my @groups = split(/\s*,\s*/, $input);

my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $fh, ">:encoding(utf8)", $file or report FAULT => "$file";

my @layout_groups = rset('LayoutGroup')->search(
{
'me.group_id' => { '-in' => \@groups },
},
{
prefetch => [ 'layout' ],
}
)->all;
Comment thread
Oliver-ctrlo marked this conversation as resolved.

$csv->say($fh, [ 'instance_id','layout_name','layout_id','group_id','permission' ]);

foreach my $lg (@layout_groups) {
my $layout = $lg->layout;
my $instance_id = $layout->instance_id;
my $layout_name = $layout->name ;
my $group_id = $lg->group_id;
my $layout_id = $lg->layout_id;
my $permission = $lg->permission;

$csv->say($fh, [ $instance_id, $layout_name, $layout_id, $group_id, $permission ]);
}
close($fh);
info "Successfully exported permissions to '$file'";
}
Loading