File Coverage

blib/lib/Debian/Snapshot/File.pm
Criterion Covered Total %
statement 16 66 24.2
branch 0 38 0.0
condition 0 9 0.0
subroutine 6 11 54.5
pod 3 3 100.0
total 25 127 19.6


line stmt bran cond sub pod time code
1             package Debian::Snapshot::File;
2             BEGIN {
3 3     3   84 $Debian::Snapshot::File::VERSION = '0.003';
4             }
5             # ABSTRACT: information about a file
6              
7 3     3   15 use Any::Moose;
  3         5  
  3         40  
8              
9 3     3   3899 use Digest::SHA1;
  3         3070  
  3         167  
10 3     3   17 use File::Spec;
  3         7  
  3         78  
11 3     3   2840 use List::MoreUtils qw( uniq );
  3         3382  
  3         2750  
12              
13             has 'hash' => (
14             is => 'ro',
15             isa => 'Str',
16             required => 1,
17             );
18              
19             has '_fileinfo' => (
20             is => 'ro',
21             isa => 'ArrayRef[HashRef]',
22             lazy => 1,
23             builder => '_fileinfo_builder',
24             );
25              
26             has '_service' => (
27             is => 'ro',
28             isa => 'Debian::Snapshot',
29             required => 1,
30             );
31              
32             sub archive {
33 0     0 1   my ($self, $archive_name) = @_;
34              
35 0 0         $archive_name = qr/^\Q$archive_name\E$/ unless ref($archive_name) eq 'Regexp';
36              
37 0           my @archives = map $_->{archive_name}, @{ $self->_fileinfo };
  0            
38 0           return 0 != grep $_ =~ $archive_name, @archives;
39             }
40              
41             sub _checksum {
42 0     0     my ($self, $filename) = @_;
43              
44 0           open my $fp, "<", $filename;
45 0           binmode $fp;
46              
47 0           my $sha1 = Digest::SHA1->new->addfile($fp)->hexdigest;
48              
49 0           close $fp;
50              
51 0           return lc($self->hash) eq lc($sha1);
52             }
53              
54             sub download {
55 0     0 1   my ($self, %p) = @_;
56 0           my $hash = $self->hash;
57              
58 0 0 0       unless (defined $p{directory} || defined $p{filename}) {
59 0           die "One of 'directory', 'file' parameters must be given.";
60             }
61 0 0 0       if (ref($p{filename}) eq 'Regexp' && ! defined $p{directory}) {
62 0           die "Parameter 'directory' is required if 'filename' is a regular expression.";
63             }
64              
65 0           my $filename = $p{filename};
66 0 0 0       if (ref($p{filename}) eq 'Regexp' || ! defined $filename) {
67 0           $filename = $self->filename($p{archive_name}, $p{filename});
68             }
69              
70 0 0         if (defined $p{directory}) {
71 0           $filename = File::Spec->catfile($p{directory}, $filename);
72             }
73              
74 0 0         if (-f $filename) {
75 0 0         return $filename if $self->_checksum($filename);
76 0 0         die "$filename does already exist." unless $p{overwrite};
77             }
78              
79 0           $self->_service->_get("/file/$hash", ':content_file' => $filename);
80 0 0         die "Wrong checksum for '$filename' (expected " . $self->hash . ")." unless $self->_checksum($filename);
81              
82 0           return $filename;
83             }
84              
85             sub filename {
86 0     0 1   my ($self, $archive_name, $constraint) = @_;
87 0           my $hash = $self->hash;
88              
89 0           my @fileinfo = @{ $self->_fileinfo };
  0            
90              
91 0 0         if (defined $archive_name) {
92 0 0         $archive_name = qr/^\Q$archive_name\E$/ unless ref($archive_name) eq 'Regexp';
93 0           @fileinfo = grep $_->{archive_name} =~ $archive_name, @fileinfo;
94             }
95              
96 0           my @names = uniq map $_->{name}, @fileinfo;
97 0 0         die "No filename found for file $hash." unless @names;
98              
99 0 0         if (defined $constraint) {
100 0 0         $constraint = qr/^\Q$constraint\E_/ unless ref($constraint) eq 'Regexp';
101 0           @names = grep $_ =~ $constraint, @names;
102 0 0         die "No matching filename found for file $hash." unless @names;
103             }
104              
105 0 0         return @names if wantarray;
106 0 0         die "More than one filename and calling function does not want a list." unless @names == 1;
107              
108 0           my $filename = $names[0];
109              
110 0 0         die "Filename contains a slash." if $filename =~ m{/};
111 0 0         die "Filename does not start with an alphanumeric character." unless $filename =~ m{^[a-zA-Z0-9]};
112              
113 0           return $filename;
114             }
115            
116             sub _fileinfo_builder {
117 0     0     my $self = shift;
118 0           my $hash = $self->hash;
119 0           $self->_service->_get_json("/mr/file/$hash/info")->{result};
120             }
121              
122 3     3   23 no Any::Moose;
  3         6  
  3         27  
123             1;
124              
125              
126              
127             =pod
128              
129             =head1 NAME
130              
131             Debian::Snapshot::File - information about a file
132              
133             =head1 VERSION
134              
135             version 0.003
136              
137             =head1 ATTRIBUTES
138              
139             =head2 hash
140              
141             The hash of this file.
142              
143             =head1 METHODS
144              
145             =head2 archive($archive_name)
146              
147             Check if this file belongs to the archive C<$archive_name> which can either be
148             a string or a regular expression.
149              
150             =head2 download(%params)
151              
152             Download the file from the snapshot service.
153              
154             =over
155              
156             =item archive_name
157              
158             (Optional.) Name of the archive used when looking for the filename.
159              
160             =item directory
161              
162             The name of the directory where the file should be stored.
163              
164             =item filename
165              
166             The filename to use. If this option is not specified the method C
167             will be used to retrieve the filename.
168              
169             =item overwrite
170              
171             If true downloading will overwrite existing files if their hash differs from
172             the expected value. Defaults to false.
173              
174             =back
175              
176             At least one of C and C must be given.
177              
178             =head2 filename($archive_name?, $constraint?)
179              
180             Return the filename(s) of this file in the archive C<$archive_name> (which
181             might be a string or a regular expression). Will die if there is no known
182             filename or several filenames were want and the method is called in scalar
183             context.
184              
185             If the optional parameter C<$constraint> is specified the filename must either
186             start with this string followed by an underscore or match this regular
187             expression.
188              
189             =head1 SEE ALSO
190              
191             L
192              
193             =head1 AUTHOR
194              
195             Ansgar Burchardt
196              
197             =head1 COPYRIGHT AND LICENSE
198              
199             This software is copyright (c) 2010 by Ansgar Burchardt .
200              
201             This is free software; you can redistribute it and/or modify it under
202             the same terms as the Perl 5 programming language system itself.
203              
204             =cut
205              
206              
207             __END__