summaryrefslogtreecommitdiff
path: root/bin/hashl
diff options
context:
space:
mode:
Diffstat (limited to 'bin/hashl')
-rwxr-xr-xbin/hashl224
1 files changed, 97 insertions, 127 deletions
diff --git a/bin/hashl b/bin/hashl
index aa38749..6c4cee4 100755
--- a/bin/hashl
+++ b/bin/hashl
@@ -24,11 +24,14 @@ my $total = 0;
my $cur = 0;
my $timer;
my $incoming_dir;
+my ($find_ref, $find_db_write);
my $VERSION = '0.1';
my $db;
+STDOUT->autoflush(1);
+
GetOptions(
'd|database=s' => \$db_file,
's|read-size=i' => sub { $read_size = $_[1] * 1024 },
@@ -38,7 +41,7 @@ if (substr($db_file, 0, 1) ne '/') {
$db_file = "${base}/${db_file}";
}
-my $action = $ARGV[0];
+my $action = shift;
sub usage {
die(<<"EOF");
@@ -77,6 +80,17 @@ sub drop_deleted {
}
}
+sub copy_file {
+ my ($file, $to) = @_;
+
+ my $base = substr($file, length($base) + 1);
+ if ($base =~ s{ / [^/]+ $}{}x) {
+ mkdirs($incoming_dir, $base);
+ }
+
+ copy($file, "${to}/${base}");
+}
+
sub hash_file {
my ($file) = @_;
my ($fh, $data);
@@ -116,29 +130,6 @@ sub file_in_db {
return hash_in_db(hash_file($file));
}
-sub db_find {
- if ($ARGV[1]) {
- given ($action) {
- when ('know-file') { exit (not defined file_in_db($ARGV[1])) }
- when ('know-hash') { exit (not defined hash_in_db($ARGV[1])) }
- when ('new-file') { exit (defined file_in_db($ARGV[1])) }
- when ('new-hash') { exit (defined hash_in_db($ARGV[1])) }
- }
- }
- else {
- while (my $line = <STDIN>) {
- chomp $line;
- if (
- ($action eq 'know-file' and defined file_in_db($line)) or
- ($action eq 'know-hash' and defined hash_in_db($line)) or
- ($action eq 'new-file' and not defined file_in_db($line)) or
- ($action eq 'new-hash' and not defined hash_in_db($line))) {
- say $line;
- }
- }
- }
-}
-
sub db_info {
printf(
"Read size: %d bytes (%.f KiB)\n",
@@ -159,22 +150,33 @@ sub file_info {
}
sub process_file {
+ my ($code, $write) = ($find_ref, $find_db_write);
my $file = $File::Find::name;
my $path = $file;
- my ($size, $mtime) = (stat($file))[7,9];
if (not -f $file or -l $file or $file eq $db_file) {
return;
}
- $cur++;
-
if ($rel_paths) {
$file = substr($file, length($base) + 1);
}
+ $cur++;
+
print $timer->report("\r\e[2KUpdating: %p done, %L elapsed, %E remaining", $cur);
+ &{$code}($file, $path);
+
+ if ($write and (($cur % 100) == 0)) {
+ nstore($db, $db_file);
+ }
+}
+
+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 ) {
@@ -186,33 +188,24 @@ sub process_file {
mtime => $mtime,
size => $size,
};
-
- if (($cur % 100) == 0) {
- nstore($db, $db_file);
- }
}
-sub ignore_file {
- my $file = $File::Find::name;
-
- if (not -f $file or -l $file or $file eq $db_file) {
- return;
- }
-
- my $hash = hash_file($file);
-
- $cur++;
-
- print $timer->report("\r\e[2KUpdating: %p done, %L elapsed, %E remaining", $cur);
+sub db_ignore {
+ my ($file, $path) = @_;
+ my $hash = hash_file($path);
if (hash_in_db($hash)) {
return;
}
push(@{$db->{'ignored'}->{'hashes'}}, $hash);
+}
- if (($cur % 100) == 0) {
- nstore($db, $db_file);
+sub db_copy {
+ my ($file, $path) = @_;
+
+ if (not defined file_in_db($path)) {
+ copy_file($path, $incoming_dir);
}
}
@@ -227,119 +220,96 @@ sub mkdirs {
}
}
-sub copy_file {
- my ($file, $to) = @_;
-
- my $base = substr($file, length($base) + 1);
- if ($base =~ s{ / [^/]+ $}{}x) {
- mkdirs($incoming_dir, $base);
- }
+sub prepare_db_run {
+ find(\&get_total, $base);
- copy($file, "${to}/${base}");
+ $timer = Time::Progress->new();
+ $timer->attr(
+ min => 1,
+ max => $total,
+ );
+ return;
}
-sub maybe_copy_file {
- my $file = $File::Find::name;
+sub cmd_copy {
+ prepare_db_run();
+ $incoming_dir = (@_);
- if (not -f $file or -l $file or $file eq $db_file) {
- return;
+ if (not $incoming_dir) {
+ usage();
}
- $cur++;
-
- print $timer->report("\r\e[KCopying: %p done, %L elapsed, %E remaining", $cur);
-
- if (not defined file_in_db($file)) {
- copy_file($file, $incoming_dir);
+ if (substr($incoming_dir, 0, 1) ne '/') {
+ $incoming_dir = $base . '/' . $incoming_dir;
}
+
+ $find_ref = \&db_copy;
+ $find_db_write = 0;
+ find(\&process_file, $base);
+ print "\n";
}
-if ($action eq 'update') {
+sub cmd_ignore {
+ my ($ign_dir) = @_;
- STDOUT->autoflush(1);
+ $ign_dir //= $base;
- drop_deleted();
- find(\&get_total, $base);
+ prepare_db_run();
- $timer = Time::Progress->new();
- $timer->attr(
- min => 1,
- max => $total
- );
+ if (substr($ign_dir, 0, 1) ne '/') {
+ $ign_dir = $base . '/' . $ign_dir;
+ }
+ $find_ref = \&db_ignore;
+ $find_db_write = 1;
find(\&process_file, $base);
- print "\n";
nstore($db, $db_file);
+ print "\n";
}
-elsif ($action eq 'list') {
+
+sub cmd_info {
+ my ($file) = @_;
+
+ if ($file) {
+ file_info($file);
+ }
+ else {
+ db_info();
+ }
+}
+
+sub cmd_list {
for my $name (sort keys %{$db->{'files'}}) {
my $file = $db->{'files'}->{$name};
printf("%s %s\n", $file->{'hash'}, $name);
}
}
-elsif ($action eq 'list-ignored') {
+
+sub cmd_list_ignored {
if (exists $db->{'ignored'}->{'hashes'}) {
for my $hash (@{$db->{'ignored'}->{'hashes'}}) {
say $hash;
}
}
}
-elsif ($action ~~ [qw[know-file know-hash new-file new-hash]]) {
- db_find();
-}
-elsif ($action eq 'info') {
- if ($ARGV[1]) {
- file_info($ARGV[1]);
- }
- else {
- db_info();
- }
-}
-elsif ($action eq 'copy') {
-
- if (not $ARGV[1]) {
- usage();
- }
- $incoming_dir = $ARGV[1];
- if (substr($incoming_dir, 0, 1) ne '/') {
- $incoming_dir = $base . '/' . $incoming_dir;
- }
-
- STDOUT->autoflush(1);
- find(\&get_total, $base);
-
- $timer = Time::Progress->new();
- $timer->attr(
- min => 1,
- max => $total,
- );
-
- find(\&maybe_copy_file, $base);
+sub cmd_update {
+ prepare_db_run();
+ $find_ref = \&db_update;
+ $find_db_write = 1;
+ find(\&process_file, $base);
print "\n";
-}
-elsif ($action eq 'ignore') {
- my $ign_dir = $ARGV[1] // $base;
-
- if (substr($ign_dir, 0, 1) ne '/') {
- $ign_dir = $base . '/' . $ign_dir;
- }
-
- STDOUT->autoflush(1);
- find(\&get_total, $base);
-
- $timer = Time::Progress->new();
- $timer->attr(
- min => 1,
- max => $total,
- );
-
- find(\&ignore_file, $base);
nstore($db, $db_file);
- print "\n";
}
-else {
- usage();
+
+given ($action) {
+ when ('copy') { cmd_copy(@ARGV) }
+ when ('ignore') { cmd_ignore(@ARGV) }
+ when ('info') { cmd_info(@ARGV) }
+ when ('list') { cmd_list(@ARGV) }
+ when ('list-ignored') { cmd_list_ignored(@ARGV) }
+ when ('update') { cmd_update(@ARGV) }
+ default { usage() }
}
__END__