File Coverage

blib/lib/Assets/Fileinfo.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Assets::Fileinfo;
2             {
3             $Assets::Fileinfo::VERSION = '0.1';
4             }
5 1     1   45493 use Moose;
  0            
  0            
6             use namespace::autoclean;
7             use File::Find;
8             use File::Spec;
9             use Digest::MD5;
10              
11             require Exporter;
12             our @ISA = qw(Exporter);
13             our @EXPORT_OK = qw( regexp_list );
14              
15             our $EXTENSIONS = [qw/js css jpg jpeg png gif ico/];
16              
17             has directory => (
18             is => 'rw',
19             isa => 'Str',
20             );
21              
22             has extensions => (
23             is => 'rw',
24             isa => 'ArrayRef',
25             default => sub { $EXTENSIONS },
26             );
27              
28             has cache_file => (
29             is => 'rw',
30             isa => 'Str',
31             default => ''
32             );
33              
34             has fileinfo => (
35             is => 'rw',
36             lazy => 1,
37             builder => '_build_fileinfo'
38             );
39              
40             sub md5sum {
41             my $file = shift;
42             open(my $fh, "<", $file) or die "Can't open file $file: $!";
43             binmode($fh);
44             my $ctx = Digest::MD5->new;
45             $ctx->addfile($fh);
46             return $ctx->hexdigest;
47             }
48              
49             sub regexp_list {
50             my @list = @_;
51             return join('|', @list);
52             }
53              
54             sub _build_fileinfo {
55             my $self = shift;
56             my %fileinfo;
57             my $dir = $self->directory;
58             my $cached = $self->loadCache;
59             my $cache_invalid = 0;
60             my $extension_re = regexp_list(@{$self->extensions});
61             my $wanted = sub {
62             my $file = $File::Find::name;
63             if ( -f $file && $file =~ /\.$extension_re$/ ) {
64             my $rel_path = File::Spec->abs2rel($file, $dir);
65             my $mtime = [stat($file)]->[9];
66             if ( exists $cached->{$rel_path} && $mtime == $cached->{$rel_path}{mtime} ) {
67             $fileinfo{$rel_path} = $cached->{$rel_path};
68             } else {
69             $cache_invalid = 1;
70             $fileinfo{$rel_path} = {
71             'mtime' => $mtime,
72             'md5' => md5sum($file)
73             };
74             }
75             }
76             };
77             find($wanted, $dir);
78             if ( $cache_invalid ) {
79             $self->saveCache(\%fileinfo);
80             }
81             return \%fileinfo;
82             }
83              
84             sub real_cache_file {
85             my $self = shift;
86             return $self->cache_file && File::Spec->rel2abs($self->cache_file, $self->directory);
87             }
88              
89             sub loadCache {
90             my $self = shift;
91             my %cache;
92             my $file = $self->real_cache_file;
93             if ( $file && -r $file ) {
94             open(my $fh, "<", $file) or die "Can't open file $file: $!";
95             while ( <$fh> ) {
96             chomp;
97             my ($filename, $mtime, $md5) = split /\t/;
98             if ( $mtime && $md5 && $mtime =~ /^\d+$/ && $md5 =~ /^[0-9a-f]{32}$/ ) {
99             $cache{$filename} = { mtime => $mtime, md5 => $md5 };
100             }
101             }
102             }
103             return \%cache;
104             }
105              
106             sub saveCache {
107             my ($self, $data) = @_;
108             my $file = $self->real_cache_file;
109             if ( $file ) {
110             open(my $fh, ">", $file) or die "Can't create file $file: $!";
111             foreach ( keys %$data ) {
112             print $fh join("\t", $_, $data->{$_}{mtime}, $data->{$_}{md5}), "\n";
113             }
114             }
115             }
116              
117             __PACKAGE__->meta->make_immutable;
118              
119             1;
120              
121             __END__
122              
123             =head1 NAME
124              
125             Assets::Fileinfo - Read assets files in directory and calculate md5
126              
127             =head1 VERSION
128              
129             version 0.1
130              
131             =head1 SYNOPSIS
132              
133             use Assets::Fileinfo;
134            
135              
136             =head1 DESCRIPTION
137              
138             输入:目录
139             文件后缀
140             缓存
141              
142             缓存默认放到目录下 .assets-fileinfo 文件中格式:
143             文件名 修改时间 md5
144              
145             Blah blah blah.
146              
147             =head2 EXPORT
148              
149             None by default.
150              
151             =head1 SEE ALSO
152              
153             Mention other useful documentation such as the documentation of
154             related modules or operating system documentation (such as man pages
155             in UNIX), or any relevant external documentation such as RFCs or
156             standards.
157              
158             If you have a mailing list set up for your module, mention it here.
159              
160             If you have a web site set up for your module, mention it here.
161              
162             =head1 AUTHOR
163              
164             Ye Wenbin, E<lt>wenbinye@gmail.comE<gt>
165              
166             =head1 COPYRIGHT AND LICENSE
167              
168             Copyright (C) 2013 by Ye Wenbin
169              
170             This program is free software; you can redistribute it and/or modify
171             it under the same terms as Perl itself, either Perl version 5.8.2 or,
172             at your option, any later version of Perl 5 you may have available.
173              
174             =head1 BUGS
175              
176             None reported... yet.
177              
178             =cut