File Coverage

blib/lib/Catalyst/Controller/SimpleCAS/Store.pm
Criterion Covered Total %
statement 40 90 44.4
branch 1 22 4.5
condition 0 3 0.0
subroutine 12 21 57.1
pod 9 9 100.0
total 62 145 42.7


line stmt bran cond sub pod time code
1             package Catalyst::Controller::SimpleCAS::Store;
2              
3 2     2   2412 use strict;
  2         2  
  2         54  
4 2     2   450 use Moose::Role;
  2         3155  
  2         10  
5              
6 2     2   7042 use Digest::SHA1;
  2         1160  
  2         87  
7 2     2   11 use IO::File;
  2         2  
  2         255  
8 2     2   378 use MIME::Base64;
  2         456  
  2         82  
9 2     2   8 use Try::Tiny;
  2         2  
  2         68  
10 2     2   751 use File::MimeInfo::Magic;
  2         10776  
  2         92  
11 2     2   471 use Image::Size;
  2         3177  
  2         82  
12 2     2   473 use Email::MIME;
  2         42074  
  2         49  
13 2     2   446 use IO::All;
  2         7390  
  2         15  
14 2     2   127 use Path::Class qw( file dir );
  2         2  
  2         1162  
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, '<:raw') 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 2 my $self = shift;
116 1         2 my $file = shift;
117            
118 1         6 my $FH = IO::File->new();
119 1 50       23 $FH->open($file, '<:raw') or die "$! : $file\n";
120              
121 1         108 my $sha1 = Digest::SHA1->new->addfile($FH)->hexdigest;
122 1         11 $FH->close;
123 1         13 return $sha1;
124             }
125              
126             sub calculate_checksum {
127 0     0 1   my $self = shift;
128 0           my $data = shift;
129            
130 0           my $sha1 = Digest::SHA1->new->add($data)->hexdigest;
131 0           return $sha1;
132             }
133              
134             1;
135              
136             =head1 NAME
137              
138             Catalyst::Controller::SimpleCAS::Store - Base Role for all SimpleCAS Store
139              
140             =head1 SYNOPSIS
141              
142             =head1 DESCRIPTION
143              
144             Used as role for all storages of SimpleCAS.
145              
146             =head1 METHODS
147              
148             =head2 add_content
149              
150             =head2 add_content_base64
151              
152             =head2 add_content_file
153              
154             =head2 add_content_file_mv
155              
156             =head2 calculate_checksum
157              
158             =head2 checksum_to_path
159              
160             =head2 content_exists
161              
162             =head2 content_mimetype
163              
164             =head2 content_size
165              
166             =head2 fetch_content
167              
168             =head2 fetch_content_fh
169              
170             =head2 file_checksum
171              
172             =head2 image_size
173              
174             =head2 init_store_dir
175              
176             =head2 split_checksum
177              
178             =head1 SEE ALSO
179              
180             =over
181              
182             =item *
183              
184             L<Catalyst::Controller::SimpleCAS>
185              
186             =back
187              
188             =head1 AUTHOR
189              
190             Henry Van Styn <vanstyn@cpan.org>
191              
192             Torsten Raudssus <torsten@raudss.us>
193              
194             =head1 COPYRIGHT AND LICENSE
195              
196             This software is copyright (c) 2014 by IntelliTree Solutions llc.
197              
198             This is free software; you can redistribute it and/or modify it under
199             the same terms as the Perl 5 programming language system itself.
200              
201             =cut