File Coverage

blib/lib/Plack/App/DummyBox.pm
Criterion Covered Total %
statement 76 88 86.3
branch 22 38 57.8
condition 12 26 46.1
subroutine 13 14 92.8
pod 3 3 100.0
total 126 169 74.5


line stmt bran cond sub pod time code
1             package Plack::App::DummyBox;
2 5     5   404604 use strict;
  5         15  
  5         219  
3 5     5   28 use warnings;
  5         11  
  5         183  
4 5     5   26 use Carp qw/croak/;
  5         14  
  5         374  
5 5     5   1883 use parent qw/Plack::Component/;
  5         778  
  5         35  
6 5     5   99717 use Imager;
  5         246435  
  5         48  
7 5     5   6970 use Image::Empty;
  5         11381  
  5         161  
8 5     5   5419 use HTTP::Status qw//;
  5         25390  
  5         197  
9 5     5   7213 use HTTP::Date qw//;
  5         29285  
  5         164  
10 5     5   9551 use Plack::Request;
  5         304945  
  5         212  
11 5     5   108 use Plack::Util qw//;
  5         13  
  5         154  
12 5         52 use Plack::Util::Accessor qw/
13             dot_gif
14             dot_png
15             font
16             text
17             filter
18             cache
19             cache_key
20             max_width
21             max_height
22             stderr
23 5     5   5563 /;
  5         1466  
24              
25             our $VERSION = '0.041';
26              
27             sub prepare_app {
28 4     4 1 35285 my $self = shift;
29              
30 4 100       29 $self->max_width(5000) unless $self->max_width;
31 4 100       199 $self->max_height(5000) unless $self->max_height;
32              
33 4         98 $self->dot_gif(Image::Empty->gif);
34 4         182 $self->dot_png(Image::Empty->png);
35              
36 4 50       122 if ($self->font) {
37 0 0 0     0 my $font = Imager::Font->new(
      0        
38             file => $self->font->{file},
39             type => $self->font->{type},
40             size => $self->font->{size} || 15,
41             color => $self->font->{color} || 'darkgray',
42             ) or croak(Imager->errstr);
43 0         0 $self->font($font);
44             }
45              
46 4         40 return $self;
47             }
48              
49             sub call {
50 7     7 1 72367 my ($self, $env) = @_;
51              
52 7         65 my $req = Plack::Request->new($env);
53              
54 7   100     102 my $w = int($req->param('width') || $req->param('w') || 1);
55 7 50       1866 return $self->return_status(400) if $w > $self->max_width;
56 7   100     74 my $h = int($req->param('height') || $req->param('h') || 1);
57 7 50       187 return $self->return_status(400) if $h > $self->max_height;
58 7   100     68 my $ext = $req->param('ext') || 'gif';
59 7 50       126 return $self->return_status(400) if $ext !~ m!^(?:gif|png)$!;
60              
61 7 100       47 my $ext_obj = ($ext eq 'gif') ? $self->dot_gif : $self->dot_png;
62              
63 7 100 66     68 if ($w == 1 && $h == 1) {
64             #----- dot image
65 2         14 my $disposition = $ext_obj->disposition. '; filename="'
66             . $ext_obj->filename. '"';
67             return [
68 2         43 200,
69             [
70             'Content-Type' => $ext_obj->type,
71             'Content-Length' => $ext_obj->length,
72             'Content-Disposition' => $disposition,
73             'Last-Modified' => HTTP::Date::time2str(time),
74             ],
75             [$ext_obj->content]
76             ];
77             }
78             else {
79             #----- box
80 5   50     18 my $fill = $req->param('fill') || 'white';
81 5   50     80 my $border = $req->param('border') || 'gray';
82 5   50     71 my $line = int($req->param('line') || 1); $line++;
  5         75  
83 5 50 33     52 return $self->return_status(400) if $line > $w && $line > $h;
84              
85 5 100       28 if ($self->cache) {
86 2         47 $self->cache_key(
87             join ':',
88             $w, $h, $ext, $fill, $border, $line
89             );
90 2 100       21 if ( my $cache = $self->cache->get($self->cache_key) ) {
91 1         13 return [ 200, @{$cache} ];
  1         12  
92             }
93             }
94              
95 4         93 my $img = Imager->new(xsize => $w, ysize => $h);
96 4         550 $img->box(
97             filled => 1,
98             color => $border
99             );
100 4         28709 $img->box(
101             xmin => $line-1, ymin => $line-1,
102             xmax => $w-$line, ymax => $h-$line,
103             filled => 1,
104             color => $fill,
105             );
106              
107 4 50       804 if ($self->font) {
108 0 0       0 $img->string(
109             font => $self->font,
110             x => 5,
111             y => $self->font->{size}+5,
112             string => "$w x $h",
113             aa => 1,
114             ) or return $self->return_status(500, Imager->errstr);
115              
116 0 0       0 if ($self->text) {
117 0 0       0 $img->string(
118             font => $self->font,
119             x => 5,
120             y => $self->font->{size}*2+5+5,
121             string => $self->text,
122             aa => 1,
123             ) or return $self->return_status(500, Imager->errstr);
124             }
125             }
126              
127 4 100       60 if (ref($self->filter) eq 'CODE') {
128 1         12 $self->filter->($self, $img);
129             }
130              
131 4         120 my $content = '';
132 4         25 $img->write(data => \$content , type => $ext);
133 4         13346 my $disposition = $ext_obj->disposition. '; filename="'
134             . "${w}x$h\.$ext". '"';
135              
136 4         64 my $response = [
137             [
138             'Content-Type' => $ext_obj->type,
139             'Content-Length' => length $content,
140             'Content-Disposition' => $disposition,
141             'Last-Modified' => HTTP::Date::time2str(time),
142             ],
143             [$content]
144             ];
145              
146 4 100       151 if ($self->cache) {
147 1         13 $self->cache->set($self->cache_key => $response);
148             }
149 4         42 return [ 200, @{$response} ];
  4         38  
150             }
151             }
152              
153             sub return_status {
154 0     0 1   my $self = shift;
155 0   0       my $status_code = shift || 500;
156 0   0       my $err = shift || '';
157              
158 0 0         if ($self->stderr) {
159 0           print STDERR "$err\n";
160             }
161              
162 0           my $msg = HTTP::Status::status_message($status_code);
163              
164             return [
165 0           $status_code,
166             [
167             'Content-Type' => 'text/plain',
168             'Content-Length' => length $msg
169             ],
170             [$msg]
171             ];
172             }
173              
174             1;
175              
176             __END__