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 )