summaryrefslogtreecommitdiff
path: root/lib/App/Hashl.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/App/Hashl.pm')
-rw-r--r--lib/App/Hashl.pm155
1 files changed, 155 insertions, 0 deletions
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.