App-BinPackUtils
view release on metacpan or search on metacpan
lib/App/BinPackUtils.pm view on Meta::CPAN
};
sub bin_files {
require String::ShellQuote;
my %args = @_;
my $bin_size = $args{bin_size};
my $bin_max_items = $args{bin_max_items};
my $bin_prefix = $args{bin_prefix} // "bin";
my @items;
for my $file (@{ $args{files} }) {
return [404, "File '$file' does not exist"] unless -e $file;
if (defined $bin_size) {
my $cmd = "du ".($args{dereference_files} ? "-D " : "")."--apparent-size -sb ".
String::ShellQuote::shell_quote($file);
my $out = `$cmd`;
my $size;
if ($out =~ /\A(\d+)/) {
$size = $1;
} else {
return [500, "Cannot find the size of '$file': $!"];
}
push @items, [$file, $size];
} else {
push @items, [$file, 1];
}
}
my $res = pack_bins(bin_size => $bin_size // $bin_max_items, items => \@items);
return $res unless $res->[0] == 200;
# reformat as a single 2D table
my @rows;
my $bin_num = 0;
my %bin_names;
for my $bin (@{ $res->[2] }) {
$bin_num++;
for my $item (@{ $bin->{items} }) {
my $bin_name = "$bin_prefix$bin_num";
$bin_names{$bin_name}++;
push @rows, {
bin => $bin_name,
file=>$item->{label},
size=>$item->{size},
};
}
}
if ($args{move}) {
# create all the directories for bins
for my $bin_name (sort keys %bin_names) {
return [412, "Directory $bin_name must not already exist"]
if -d $bin_name;
log_info "Creating directory $bin_name ...";
mkdir $bin_name or return [500, "Can't create directory $bin_name: $!"];
}
# move files to bins
for my $row (@rows) {
log_info "Moving '$row->{file}' to $row->{bin} ...";
rename($row->{file}, "$row->{bin}/$row->{file}") or do {
log_warn "Can't move '$row->{file}' to $row->{bin}/: $!, skipped";
};
}
}
[200, "OK", $args{num_bins} ? scalar(keys %bin_names) : \@rows];
}
$SPEC{bin_files_into_dvds} = {
v => 1.1,
summary => 'Put files into DVD bins',
args => {
%arg0_files,
%argopt_dereference_files,
%argopt_move,
%argopt_dvd_size,
%argopt_num_dvds,
},
};
sub bin_files_into_dvds {
my %args = @_;
bin_files(
files => $args{files},
dereference_files => $args{dereference_files},
move => $args{move},
bin_prefix => "dvd",
bin_size => $args{dvd_size} // 4493*1024*1024,
num_bins => $args{num_dvds},
);
}
$SPEC{count_number_of_dvds_required} = {
v => 1.1,
summary => 'Count the number of DVDs required to contain the files',
description => <<'_',
This:
% count-number-of-dvds-requires *
is a shortcut for:
% bin-files-into-dvds -n *
_
args => {
%arg0_files,
%argopt_dereference_files,
%argopt_move,
%argopt_dvd_size,
},
};
sub count_number_of_dvds_required {
my %args = @_;
bin_files_into_dvds(
%args,
num_dvds => 1,
);
( run in 1.068 second using v1.01-cache-2.11-cpan-39bf76dae61 )