File Coverage

blib/lib/Cog/WebApp.pm
Criterion Covered Total %
statement 39 92 42.3
branch 0 24 0.0
condition n/a
subroutine 13 18 72.2
pod 0 4 0.0
total 52 138 37.6


line stmt bran cond sub pod time code
1             package Cog::WebApp;
2 2     2   1672 use Mo;
  2         4  
  2         11  
3             extends 'Cog::Base';
4              
5             has env => ();
6              
7 2     2   225 use constant index_file => '';
  2         5  
  2         126  
8 2     2   12 use constant plugins => [];
  2         4  
  2         99  
9 2     2   11 use constant site_navigation => [];
  2         4  
  2         108  
10 2     2   11 use constant url_map => [];
  2         8  
  2         120  
11 2     2   11 use constant post_map => [];
  2         7  
  2         102  
12 2     2   11 use constant coffee_files => [];
  2         2  
  2         139  
13 2         148 use constant js_files => [qw(
14             jquery.js
15             jquery-ui.js
16             jquery-json.js
17             jquery.cookie.js
18             jquery.jemplate.js
19             jemplate.js
20             cog.js
21             config.js
22             url-map.js
23             fixups.js
24 2     2   15 )];
  2         3  
25 2         102 use constant css_files => [qw(
26             reset.css
27             layout.css
28             layout-table.css
29 2     2   12 )];
  2         2  
30 2     2   10 use constant image_files => [];
  2         3  
  2         112  
31 2     2   10 use constant template_files => [];
  2         3  
  2         100  
32 2     2   10 use constant runner_class => 'Cog::Runner';
  2         2  
  2         91  
33 2     2   10 use constant rewrite => undef;
  2         10  
  2         1682  
34              
35             sub web_app {
36 0     0 0   my $self = shift;
37 0           my $webapp = $self->app->webapp_root;
38 0           my $index_file = "$webapp/index.html";
39 0 0         open INDEX, $index_file or die "Can't open '$index_file'";
40 0           my $html = do {local $/; <INDEX>};
  0            
  0            
41 0 0         close INDEX or die;
42              
43 0           my $time = scalar(gmtime);
44 0 0         $time .= ' GMT' unless $time =~ /GMT/;
45             return sub {
46 0     0     my $env = shift;
47 0 0         return $env->{REQUEST_METHOD} eq 'POST'
48             ? $self->handle_post($env)
49             : [
50             200, [
51             'Content-Type' => 'text/html',
52             'Last-Modified' => $time,
53             ], [$html]
54             ];
55 0           };
56             }
57              
58             sub handle_post {
59             # Call handler based on url
60             # Return results or OK
61 0     0 0   my $self = shift;
62 0           $self->env(shift);
63 0           $self->read_json;
64 0           my $path = $self->env->{PATH_INFO};
65 0           my $post_map = $self->config->post_map;
66 0           my ($regexp, $action, @args, @captures);
67 0           for my $entry (@$post_map) {
68 0           ($regexp, $action, @args) = @$entry;
69 0 0         if ($path =~ /^$regexp$/) {
70 0           @captures = ('', $1, $2, $3, $4, $5);
71 0           last;
72             }
73 0           undef $action;
74             }
75 0 0         return [501, [], ["Invalid POST request: '$path'"]] unless $action;
76 0           @args = map {s/\$(\d+)/$captures[$1]/ge; ($_)} @args;
  0            
  0            
  0            
77 0           my $method = "handle_$action";
78 0           my $result = eval { $self->$method(@args) };
  0            
79 0 0         if ($@) {
80 0           warn $@;
81 0           return [500, [], [ $@ ]];
82             }
83 0 0         $result = 'OK' unless defined $result;
84 0 0         if (ref($result) eq 'ARRAY') {
    0          
85 0           return $result;
86             }
87             elsif (ref($result) eq 'HASH') {
88             return [
89 0           200,
90             [ 'Content-Type' => 'application/json' ],
91             [ $self->json->encode($result) ]
92             ];
93             }
94             else {
95 0           return [ 200, [ 'Content-Type' => 'text/plain' ], [ $result ] ];
96             }
97             }
98              
99             sub response_json {
100 0     0 0   my ($self, $data) = @_;
101 0 0         die "response_json() requires a hash or array" unless ref $data;
102 0           my $json = $self->json->encode($data);
103             return [
104 0           200,
105             [ 'Content-Type' => 'application/json' ],
106             [ $json ],
107             ];
108             }
109              
110             sub read_json {
111 0     0 0   my $self = shift;
112 0           my $env = $self->env;
113             return unless
114             # $env->{CONTENT_TYPE} =~ m!application/json! and
115 0 0         $env->{CONTENT_LENGTH};
116 0           my $json = do { my $io = $env->{'psgi.input'}; local $/; <$io> };
  0            
  0            
  0            
117 0           $env->{post_data} = $self->json->decode($json);
118             }
119              
120             1;