Add progress bar

This commit is contained in:
Dan Church 2020-11-09 16:35:20 -06:00
parent c77fc7a205
commit 58740f34c5
Signed by: h3xx
GPG Key ID: EA2BF379CD2CDBD0
2 changed files with 70 additions and 22 deletions

View File

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
## [Unreleased] ## [Unreleased]
### Added
- Add progress bar
## [3.0.0] ## [3.0.0]
### Changed ### Changed

View File

@ -4,9 +4,9 @@
package main; package main;
use strict; use strict;
use warnings; use warnings;
require Cwd; use List::Util qw/ sum /;
our $VERSION = '3.0.0'; our $VERSION = '3.1.0';
=pod =pod
@ -97,7 +97,6 @@ Written by Dan Church S<E<lt>amphetamachine@gmail.comE<gt>>
=cut =cut
use File::Find qw/ find /; use File::Find qw/ find /;
require Digest::SHA;
use Getopt::Std qw/ getopts /; use Getopt::Std qw/ getopts /;
sub HELP_MESSAGE { sub HELP_MESSAGE {
@ -166,14 +165,31 @@ MAIN: {
return; return;
} }
push @files, $File::Find::name; push @files, Directory::Simplify::File->new($File::Find::name);
}, @dirs_to_process); }, @dirs_to_process);
printf STDERR "%s files found.\nGenerating hashes...", scalar @files printf STDERR "%s files found.\n",
scalar @files
if $opts{v}; if $opts{v};
print STDERR "Generating hashes..." if $opts{v};
my $filehash = Directory::Simplify::FileHash->new; my $filehash = Directory::Simplify::FileHash->new;
$filehash->add(@files); my $report_every = 1; # seconds
my $processed_bytes = 0;
my $last_report = time;
my $total_size_hr = sprintf "%0.4G %s", Directory::Simplify::Utils::hr_size(&sum(map { $_->{size} } @files));
printf STDERR "\e\x{37}";
my $cb = sub {
my ($file, $now) = (shift, time);
$processed_bytes += $file->{size};
if ($now >= $last_report + $report_every) {
printf STDERR "\e\x{38}%8s / %8s",
(sprintf '%0.4G %s', Directory::Simplify::Utils::hr_size($processed_bytes)),
$total_size_hr;
$last_report = $now;
}
};
$filehash->add({ files => \@files, callback => $cb });
print STDERR "done.\n" print STDERR "done.\n"
if $opts{v}; if $opts{v};
@ -469,10 +485,36 @@ sub instructions {
@inst @inst
} }
package Directory::Simplify::File;
use strict;
use warnings;
require Cwd;
sub new {
my $class = shift;
my $self = bless {
name => Cwd::abs_path(shift),
}, $class;
(@{$self}{qw/ dev ino mode nlink uid gid rdev size
atime mtime ctime blksize blocks /})
= lstat $self->{name};
$self
}
sub hash {
my $self = shift;
unless (defined $self->{_hash}) {
require Digest::SHA;
my $ctx = Digest::SHA->new;
$ctx->addfile($self->{name});
$self->{_hash} = $ctx->hexdigest;
}
$self->{_hash}
}
package Directory::Simplify::FileHash; package Directory::Simplify::FileHash;
use strict; use strict;
use warnings; use warnings;
require Digest::SHA;
=head1 DESCRIPTION =head1 DESCRIPTION
@ -490,28 +532,30 @@ sub new {
} }
sub add { sub add {
require Cwd;
my $self = shift; my $self = shift;
my $ctx = $self->{_ctx}; my (@files, $callback);
unless (defined $ctx) { if (ref $_[0] eq 'HASH') {
$ctx = $self->{_ctx} = Digest::SHA->new; # Called method like { files => [] }
my %opts = %{$_[0]};
@files = @{$opts{files}};
$callback = $opts{callback};
} else {
@files = @_;
} }
foreach my $filename (@_) { foreach my $file (@files) {
$filename = Cwd::abs_path($filename); unless (ref $file eq 'Directory::Simplify::File') {
unless ($self->{_files_in_hash}->{$filename}) { $file = Directory::Simplify::File->new($file);
my $entry = {}; }
(@{$entry}{qw/ name dev ino mode nlink uid gid rdev size unless ($self->{_files_in_hash}->{$file->{name}}) {
atime mtime ctime blksize blocks /}) my $hash = $file->hash;
= ($filename, lstat $filename);
$ctx->addfile($filename);
my $hash = $ctx->hexdigest;
unless (defined $self->{_entries}->{$hash}) { unless (defined $self->{_entries}->{$hash}) {
$self->{_entries}->{$hash} = []; $self->{_entries}->{$hash} = [];
} }
push @{$self->{_entries}->{$hash}}, $entry; push @{$self->{_entries}->{$hash}}, $file;
&{$callback}($file) if ref $callback eq 'CODE';
} }
$self->{_files_in_hash}->{$filename} = 1; $self->{_files_in_hash}->{$file->{name}} = 1;
} }
} }