File Coverage

blib/lib/Acme/Plack/App/GyazoStocker.pm
Criterion Covered Total %
statement 30 82 36.5
branch 0 22 0.0
condition 0 7 0.0
subroutine 10 17 58.8
pod 4 4 100.0
total 44 132 33.3


line stmt bran cond sub pod time code
1             package Acme::Plack::App::GyazoStocker;
2 2     2   246674 use strict;
  2         6  
  2         83  
3 2     2   13 use warnings;
  2         3  
  2         75  
4 2     2   68 use Carp qw/croak carp/;
  2         7  
  2         205  
5 2     2   15904 use HTTP::Status qw//;
  2         12245  
  2         119  
6 2     2   2537 use LWP::UserAgent;
  2         175969  
  2         78  
7 2     2   9648 use Plack::App::File;
  2         122786  
  2         126  
8 2     2   28 use parent qw/Plack::Component/;
  2         4  
  2         18  
9 2     2   4992 use Plack::Request;
  2         259514  
  2         80  
10 2     2   24 use Plack::Util qw//;
  2         5  
  2         47  
11 2         26 use Plack::Util::Accessor qw/
12             image_dir
13             req
14             ua
15             gyazo
16 2     2   22 /;
  2         4  
17              
18             our $VERSION = '0.04';
19              
20             my @ROUTE = (
21             [ 'root', qr!^/[a-f\d]{32}(?:\.png)?$! ],
22             [ 'image', qr!^/image/[a-f\d]{32}\.png$! ],
23             );
24              
25             sub prepare_app {
26 0     0 1   my $self = shift;
27              
28 0 0         croak 'require image dir' unless $self->image_dir;
29 0 0         croak 'not exists image_dir: '. $self->image_dir unless -d $self->image_dir;
30              
31 0 0         $self->ua or $self->ua(
32             LWP::UserAgent->new(
33             agent => __PACKAGE__. "/$VERSION",
34             timeout => 15,
35             )
36             );
37              
38 0 0         $self->gyazo or $self->gyazo('http://gyazo.com/');
39             }
40              
41             sub call {
42 0     0 1   my ($self, $env) = @_;
43              
44 0           $self->req( Plack::Request->new($env) );
45              
46 0           my $res;
47 0           my $not_found = 1;
48 0           for my $route (@ROUTE) {
49 0           my ($method, $path_regex) = @{$route};
  0            
50 0 0         if ($env->{REQUEST_URI} =~ m!$path_regex!) {
51 0           $res = $self->$method($env);
52 0           $not_found = 0;
53 0           last;
54             }
55             }
56              
57 0 0         if ($not_found) {
58 0           return $self->_return_status(404);
59             }
60              
61 0 0         if (ref $res ne 'ARRAY') {
62 0   0       return $self->_return_status($res || 500);
63             }
64              
65 0           return $res;
66             }
67              
68             sub root {
69 0     0 1   my ($self, $env) = @_;
70              
71 0           my ($image_file) = ($self->req->path_info =~ m!/([a-f\d]+(?:\.png)?)!);
72              
73 0 0         unless ($image_file =~ m!\.png$!) {
74 0           $image_file .= '.png';
75             }
76              
77 0 0         if (-e $self->image_dir. "/$image_file") {
78 0           return $self->_redirect("/image/$image_file"); # already exists
79             }
80              
81 0 0         if ( my $image = $self->_fetch_image($image_file) ) {
82 0           open my $fh, '>', $self->image_dir. "/$image_file";
83 0           print $fh $image;
84 0           close $fh;
85 0           return $self->_redirect("/image/$image_file");
86             }
87             }
88              
89             sub _fetch_image {
90 0     0     my ($self, $image_file) = @_;
91              
92 0           my $url = $self->gyazo. $image_file;
93              
94 0           my $res = $self->ua->get($url);
95              
96 0 0         if ($res->is_success) {
97 0           return $res->content;
98             }
99             else {
100 0           carp $res->status_line. ": $url";
101             }
102              
103 0           return;
104             }
105              
106             sub image {
107 0     0 1   my ($self, $env) = @_;
108              
109 0   0       $self->{file} ||= Plack::App::File->new({
110             root => $self->image_dir,
111             });
112              
113 0           my $path = $env->{PATH_INFO};
114 0           $path =~ s!^/image!!;
115 0           local $env->{PATH_INFO} = $path;
116              
117 0           return $self->{file}->call($env);
118             }
119              
120             sub _redirect {
121 0     0     my ($self, $path) = @_;
122              
123 0           my $to_url = $self->req->scheme. '://'. $self->req->uri->host. $path;
124              
125 0           return [ 302, [ 'Location' => $to_url ], [''] ];
126             }
127              
128             sub _return_status {
129 0     0     my $self = shift;
130 0   0       my $status_code = shift || 500;
131              
132 0           my $msg = HTTP::Status::status_message($status_code);
133              
134             return [
135 0           $status_code,
136             [
137             'Content-Type' => 'text/plain',
138             'Content-Length' => length $msg
139             ],
140             [$msg]
141             ];
142             }
143              
144             1;
145              
146             __END__