summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2011-05-17 19:21:54 +0200
committerDaniel Friesel <derf@finalrewind.org>2011-05-17 19:21:54 +0200
commit60fba3105a1bf2f537742cfe591f5af1e5c5faa2 (patch)
treed6bf02e346497ed317f93e71013f038e908acd49
parent3604c18bdca5ccb87800e3caa503ad771cbfc3ab (diff)
Initial switch to App::Hashl
-rw-r--r--Build.PL4
-rwxr-xr-xbin/hashl128
-rw-r--r--lib/App/Hashl.pm155
3 files changed, 194 insertions, 93 deletions
diff --git a/Build.PL b/Build.PL
index 1336543..b709be0 100644
--- a/Build.PL
+++ b/Build.PL
@@ -11,8 +11,7 @@ my $build = Module::Build->new(
'Test::Compile' => 0,
'Test::Pod' => 0,
},
- dist_name => 'hashl',
- dist_version_from => 'bin/hashl',
+ module_name => 'App::Hashl',
license => 'unrestricted',
requires => {
'perl' => '5.10.0',
@@ -26,5 +25,6 @@ my $build = Module::Build->new(
'Time::Progress' => 0,
},
script_files => 'bin/',
+ sign => 1,
);
$build->create_build_script();
diff --git a/bin/hashl b/bin/hashl
index 35891f1..3f03789 100755
--- a/bin/hashl
+++ b/bin/hashl
@@ -7,29 +7,29 @@ use warnings;
use 5.010;
use autodie;
+use App::Hashl;
use Cwd;
use Digest::SHA qw(sha1_hex);
use File::Copy;
use File::Find;
use Getopt::Long;
use IO::Handle;
-use Storable qw(nstore retrieve);
use Time::Progress;
my $base = getcwd();
my $rel_paths = 1;
-my $read_size = (2 ** 20) * 4; # 4 MiB
my $db_file = '.hashl.db';
my $total = 0;
my $cur = 0;
my $show_progress = 1;
my $timer;
my $incoming_dir;
+my $read_size;
my ($find_ref, $find_db_write);
-my $VERSION = '0.1';
+my $hashl;
-my $db;
+my $VERSION = '0.1';
STDERR->autoflush(1);
@@ -59,13 +59,12 @@ if (not defined $action) {
}
if (-r $db_file) {
- $db = retrieve($db_file);
- $read_size = $db->{'config'}->{'read_size'};
+ $hashl = App::Hashl->new_from_file($db_file);
}
else {
- $db->{'config'} = {
+ $hashl = App::Hashl->new(
read_size => $read_size,
- }
+ );
}
sub get_total {
@@ -75,20 +74,10 @@ sub get_total {
}
}
-sub si_size {
- my @post = (' ', 'k', 'M', 'G', 'T');
- my $bytes = shift;
- while ($bytes > 1024) {
- $bytes /= 1024;
- shift @post;
- }
- return sprintf("%6.1f%s", $bytes, $post[0]);
-}
-
sub drop_deleted {
- for my $file (keys %{$db->{'files'}}) {
+ for my $file ($hashl->files()) {
if (! -e $file) {
- delete $db->{'files'}->{$file};
+ $hashl->delete_file($file);
}
}
}
@@ -104,58 +93,18 @@ sub copy_file {
copy($file, "${to}/${base}");
}
-sub hash_file {
- my ($file) = @_;
- my ($fh, $data);
-
- open($fh, '<', $file);
- binmode($fh);
- read($fh, $data, $read_size);
- close($fh);
-
- return sha1_hex($data);
-}
-
-sub hash_in_db {
- my ($hash) = @_;
-
- if ($db->{'ignored'}->{'hashes'}) {
- for my $ihash (@{$db->{'ignored'}->{'hashes'}}) {
- if ($hash eq $ihash) {
- return '// ignored';
- }
- }
- }
-
- for my $name (keys %{$db->{'files'}}) {
- my $file = $db->{'files'}->{$name};
-
- if ($file->{'hash'} eq $hash) {
- return $name;
- }
- }
- return undef;
-}
-
-sub file_in_db {
- my ($file) = @_;
-
- return hash_in_db(hash_file($file));
-}
-
sub db_find_new {
my ($file, $path) = @_;
- if (not defined file_in_db($path)) {
+ if (not $hashl->file_in_db($path)) {
say "\r\e[2K${file}";
}
}
sub db_find_known {
my ($file, $path) = @_;
- my $in_db = file_in_db($path);
- if (defined $in_db) {
+ if ($hashl->file_in_db($path)) {
say "\r\e[2K${file}";
}
}
@@ -163,8 +112,8 @@ sub db_find_known {
sub db_info {
printf(
"Read size: %d bytes (%s)\n",
- $db->{'config'}->{'read_size'},
- si_size($db->{'config'}->{'read_size'}),
+ $hashl->read_size(),
+ $hashl->si_size($hashl->read_size),
);
}
@@ -174,9 +123,9 @@ sub file_info {
printf(
"File: %s\nSize: %d bytes (%s)\nHash: %s\n",
$file,
- $db->{'files'}->{$file}->{'size'},
- si_size($db->{'files'}->{$file}->{'size'}),
- $db->{'files'}->{$file}->{'hash'},
+ $hashl->file($file)->{size},
+ $hashl->si_size($hashl->file($file)->{size}),
+ $hashl->files($file)->{hash},
);
}
@@ -205,7 +154,7 @@ sub process_file {
&{$code}($file, $path);
if ($write and (($cur % 100) == 0)) {
- nstore($db, $db_file);
+ $hashl->save($db_file);
}
}
@@ -213,34 +162,33 @@ sub db_update {
my ($file, $path) = @_;
my ($size, $mtime) = (stat($path))[7,9];
- if (exists($db->{'files'}->{$file}) and
- $db->{'files'}->{$file}->{'mtime'} == $mtime and
- $db->{'files'}->{$file}->{'size'} == $size ) {
+ if ($hashl->file($file) and
+ $hashl->file($file)->{mtime} == $mtime and
+ $hashl->file($file)->{size} == $size ) {
return;
}
- $db->{'files'}->{$file} = {
- hash => hash_file($path),
+ $hashl->add_file($file, {
+ hash => $hashl->hash_file($path),
mtime => $mtime,
size => $size,
- };
+ });
}
sub db_ignore {
my ($file, $path) = @_;
- my $hash = hash_file($path);
- if (hash_in_db($hash)) {
+ if ($hashl->file_in_db($path)) {
return;
}
- push(@{$db->{'ignored'}->{'hashes'}}, $hash);
+ $hashl->ignore($path);
}
sub db_copy {
my ($file, $path) = @_;
- if (not defined file_in_db($path)) {
+ if (not $hashl->file_in_db($path)) {
copy_file($path, $incoming_dir);
}
}
@@ -340,7 +288,7 @@ sub cmd_ignore {
$find_ref = \&db_ignore;
$find_db_write = 1;
find(\&process_file, $base);
- nstore($db, $db_file);
+ $hashl->save($db_file);
print "\n";
}
@@ -359,29 +307,27 @@ sub cmd_list {
printf(
"# hashl v%s Read Size %d bytes (%s)\n",
$VERSION,
- $db->{'config'}->{'read_size'},
- si_size($db->{'config'}->{'read_size'}),
+ $hashl->read_size(),
+ $hashl->si_size($hashl->read_size()),
);
- for my $name (sort keys %{$db->{'files'}}) {
- my $file = $db->{'files'}->{$name};
+ for my $name ($hashl->files()) {
+ my $file = $hashl->file($name);
printf(
"%s %-7s %s\n",
- $file->{'hash'},
- si_size($file->{'size'}),
+ $file->{hash},
+ $hashl->si_size($file->{size}),
$name
);
}
}
sub cmd_list_files {
- say join("\n", sort keys %{$db->{'files'}});
+ say join("\n", $hashl->files());
}
sub cmd_list_ignored {
- if (exists $db->{'ignored'}->{'hashes'}) {
- for my $hash (@{$db->{'ignored'}->{'hashes'}}) {
- say $hash;
- }
+ for my $hash ($hashl->ignored()) {
+ say $hash;
}
}
@@ -392,7 +338,7 @@ sub cmd_update {
$find_db_write = 1;
find(\&process_file, $base);
print "\n";
- nstore($db, $db_file);
+ $hashl->save($db_file);
}
given ($action) {
diff --git a/lib/App/Hashl.pm b/lib/App/Hashl.pm
new file mode 100644
index 0000000..f99406f
--- /dev/null
+++ b/lib/App/Hashl.pm
@@ -0,0 +1,155 @@
+package App::Hashl;
+
+use strict;
+use warnings;
+use autodie;
+use 5.010;
+
+use Digest::SHA qw(sha1_hex);
+use Storable qw(nstore retrieve);
+
+my $VERSION = '0.1';
+
+sub new {
+ my ($obj, %conf) = @_;
+ my $ref = {
+ files => {},
+ ignored => {},
+ };
+
+ $ref->{config} = \%conf;
+ $ref->{config}->{read_size} //= (2 ** 20) * 4, # 4 MiB
+
+ return bless($ref, $obj);
+}
+
+sub new_from_file {
+ my ($obj, $file) = @_;
+ my $ref = retrieve($file);
+ return bless($ref, $obj);
+}
+
+sub si_size {
+ my ($self, $bytes) = @_;
+ my @post = (' ', qw(k M G T));
+
+ while ($bytes > 1024) {
+ $bytes /= 1024;
+ shift @post;
+ }
+
+ return sprintf("%6.1f%s", $bytes, $post[0]);
+}
+
+sub hash_file {
+ my ($self, $file) = @_;
+ my ($fh, $data);
+
+ open($fh, '<', $file);
+ binmode($fh);
+ read($fh, $data, $self->{config}->{read_size});
+ close($fh);
+
+ return sha1_hex($data);
+}
+
+sub hash_in_db {
+ my ($self, $hash) = @_;
+
+ if ($self->{ignored}->{hashes}) {
+ for my $ihash (@{$self->{ignored}->{hashes}}) {
+ if ($hash eq $ihash) {
+ return '// ignored';
+ }
+ }
+ }
+
+ for my $name ($self->files()) {
+ my $file = $self->file($name);
+
+ if ($file->{hash} eq $hash) {
+ return $name;
+ }
+ }
+ return undef;
+}
+
+sub file_in_db {
+ my ($self, $file) = @_;
+
+ return $self->hash_in_db($self->hash_file($file));
+}
+
+sub read_size {
+ my ($self) = @_;
+ return $self->{config}->{read_size};
+}
+
+sub file {
+ my ($self, $name) = @_;
+ return $self->{files}->{$name};
+}
+
+sub delete_file {
+ my ($self, $name) = @_;
+ delete $self->{files}->{$name};
+}
+
+sub files {
+ my ($self) = @_;
+ return sort keys %{ $self->{files} };
+}
+
+sub add_file {
+ my ($self, $name, $data) = @_;
+ $self->{files}->{$name} = $data;
+}
+
+sub ignored {
+ my ($self) = @_;
+ if (exists $self->{ignored}->{hashes}) {
+ return @{ $self->{ignored}->{hashes} };
+ }
+ else {
+ return ();
+ }
+}
+
+sub ignore {
+ my ($self, $file) = @_;
+
+ push(@{ $self->{ignored}->{hashes} }, $file);
+}
+
+sub save {
+ my ($self, $file) = @_;
+ nstore($self, $file);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=over
+
+=back
+
+=head1 DEPENDENCIES
+
+=head1 SEE ALSO
+
+=head1 AUTHOR
+
+Copyright (C) 2011 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+
+=head1 LICENSE
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.