File Coverage

blib/lib/Catalyst/Controller/SimpleCAS/Store.pm
Criterion Covered Total %
statement 41 91 45.0
branch 1 22 4.5
condition 0 3 0.0
subroutine 12 21 57.1
pod 9 9 100.0
total 63 146 43.1


line stmt bran cond sub pod time code
1             package Catalyst::Controller::SimpleCAS::Store;
2              
3 2     2   2626 use strict;
  2         48  
  2         74  
4 2     2   368 use Moose::Role;
  2         3031  
  2         10  
5              
6 2     2   6530 use Digest::SHA1;
  2         1204  
  2         82  
7 2     2   10 use IO::File;
  2         2  
  2         243  
8 2     2   380 use MIME::Base64;
  2         451  
  2         84  
9 2     2   9 use Try::Tiny;
  2         2  
  2         71  
10 2     2   782 use File::MimeInfo::Magic;
  2         10403  
  2         96  
11 2     2   498 use Image::Size;
  2         3146  
  2         79  
12 2     2   475 use Email::MIME;
  2         38782  
  2         43  
13 2     2   415 use IO::All;
  2         7732  
  2         11  
14 2     2   118 use Path::Class qw( file dir );
  2         3  
  2         1009  
15              
16             requires qw(
17             content_exists
18             fetch_content
19             add_content
20             checksum_to_path
21             );
22              
23             sub add_content_base64 {
24 0     0 1 0 my $self = shift;
25 0 0       0 my $data = decode_base64(shift) or die "Error decoding base64 data. $@";
26 0         0 return $self->add_content($data);
27             }
28              
29             sub add_content_file {
30 0     0 1 0 my $self = shift;
31 0         0 my $file = shift;
32              
33 0         0 my $checksum = $self->file_checksum($file);
34              
35 0 0       0 return $checksum if ($self->content_exists($checksum));
36              
37 0         0 return $self->add_content(scalar(io($file)->slurp));
38             }
39              
40             sub add_content_file_mv {
41 0     0 1 0 my $self = shift;
42 0         0 my $file = shift;
43              
44 0         0 my $result = $self->add_content_file($file);
45              
46 0 0       0 die "SimpleCAS: Failed to move file '$file' into storage" unless $result;
47              
48 0         0 unlink $file;
49            
50 0         0 return $result;
51             }
52              
53             sub image_size {
54 0     0 1 0 my $self = shift;
55 0         0 my $checksum = shift;
56            
57 0 0       0 my $content_type = $self->content_mimetype($checksum) or return undef;
58 0         0 my ($mime_type,$mime_subtype) = split(/\//,$content_type);
59 0 0       0 return undef unless ($mime_type eq 'image');
60            
61 0 0       0 my ($width,$height) = imgsize($self->checksum_to_path($checksum)) or return undef;
62 0         0 return ($width,$height);
63             }
64              
65             sub content_mimetype {
66 0     0 1 0 my $self = shift;
67 0         0 my $checksum = shift;
68            
69             # See if this is an actual MIME file with a defined Content-Type:
70             my $MIME = try{
71 0     0   0 my $fh = $self->fetch_content_fh($checksum);
72             # only read the begining of the file, enough to make it past the Content-Type header:
73 0         0 my $buf; $fh->read($buf,1024); $fh->close;
  0         0  
  0         0  
74            
75             # This will frequently produce uninitialized value warnings from Email::Simple::Header,
76             # and I haven't been able to figure out how to stop it
77 0         0 return Email::MIME->new($buf);
78 0         0 };
79 0 0 0     0 if($MIME && $MIME->content_type) {
80 0         0 my ($type) = split(/\s*\;\s*/,$MIME->content_type);
81 0         0 return $type;
82             }
83              
84             # Otherwise, guess the mimetype from the file on disk
85 0         0 my $file = $self->checksum_to_path($checksum);
86              
87 0 0       0 return undef unless ( -f $file );
88 0         0 return mimetype($file);
89             }
90              
91             sub content_size {
92 0     0 1 0 my $self = shift;
93 0         0 my $checksum = shift;
94            
95 0         0 my $file = $self->checksum_to_path($checksum);
96            
97 0         0 return file($file)->stat->size;
98             }
99              
100             sub fetch_content_fh {
101 0     0 1 0 my $self = shift;
102 0         0 my $checksum = shift;
103              
104 0         0 my $file = $self->checksum_to_path($checksum);
105 0 0       0 return undef unless ( -f $file);
106            
107 0         0 my $fh = IO::File->new();
108 0 0       0 $fh->open('< ' . $file) or die "Failed to open $file for reading.";
109            
110 0         0 return $fh;
111             }
112              
113             # All stores should use SHA-1, in order to be able to swap Store modules later on.
114             sub file_checksum {
115 1     1 1 1 my $self = shift;
116 1         1 my $file = shift;
117            
118 1         4 my $FH = IO::File->new();
119 1 50       21 $FH->open('< ' . $file) or die "$! : $file\n";
120 1         54 $FH->binmode;
121              
122 1         30 my $sha1 = Digest::SHA1->new->addfile($FH)->hexdigest;
123 1         10 $FH->close;
124 1         12 return $sha1;
125             }
126              
127             sub calculate_checksum {
128 0     0 1   my $self = shift;
129 0           my $data = shift;
130            
131 0           my $sha1 = Digest::SHA1->new->add($data)->hexdigest;
132 0           return $sha1;
133             }
134              
135             1;
136              
137             =head1 NAME
138              
139             Catalyst::Controller::SimpleCAS::Store - Base Role for all SimpleCAS Store
140              
141             =head1 SYNOPSIS
142              
143             =head1 DESCRIPTION
144              
145             Used as role for all storages of SimpleCAS.
146              
147             =head1 METHODS
148              
149             =head2 add_content
150              
151             =head2 add_content_base64
152              
153             =head2 add_content_file
154              
155             =head2 add_content_file_mv
156              
157             =head2 calculate_checksum
158              
159             =head2 checksum_to_path
160              
161             =head2 content_exists
162              
163             =head2 content_mimetype
164              
165             =head2 content_size
166              
167             =head2 fetch_content
168              
169             =head2 fetch_content_fh
170              
171             =head2 file_checksum
172              
173             =head2 image_size
174              
175             =head2 init_store_dir
176              
177             =head2 split_checksum
178              
179             =head1 SEE ALSO
180              
181             =over
182              
183             =item *
184              
185             L<Catalyst::Controller::SimpleCAS>
186              
187             =back
188              
189             =head1 AUTHOR
190              
191             Henry Van Styn <vanstyn@cpan.org>
192              
193             Torsten Raudssus <torsten@raudss.us>
194              
195             =head1 COPYRIGHT AND LICENSE
196              
197             This software is copyright (c) 2014 by IntelliTree Solutions llc.
198              
199             This is free software; you can redistribute it and/or modify it under
200             the same terms as the Perl 5 programming language system itself.
201              
202             =cut