File Coverage

blib/lib/DDG/Meta/ZeroClickInfoSpice.pm
Criterion Covered Total %
statement 124 155 80.0
branch 29 50 58.0
condition 0 3 0.0
subroutine 24 28 85.7
pod 0 5 0.0
total 177 241 73.4


line stmt bran cond sub pod time code
1             package DDG::Meta::ZeroClickInfoSpice;
2             our $AUTHORITY = 'cpan:DDG';
3             # ABSTRACT: Functions for generating a L factory
4             $DDG::Meta::ZeroClickInfoSpice::VERSION = '1017';
5 12     23   71 use strict;
  12         40  
  12         290  
6 12     12   63 use warnings;
  12         24  
  12         243  
7 12     12   47 use Carp;
  12         24  
  12         602  
8 12     12   2966 use DDG::ZeroClickInfo::Spice;
  12         34  
  12         303  
9 12     12   4320 use DDG::ZeroClickInfo::Spice::Data;
  12         34  
  12         322  
10 12     12   4324 use DDG::Rewrite;
  12         44  
  12         353  
11 12     12   88 use Package::Stash;
  12         25  
  12         299  
12 12     12   5058 use URI::Encode qw(uri_encode uri_decode);
  12         109753  
  12         804  
13 12     12   4918 use IO::All;
  12         104433  
  12         98  
14              
15 11     11 0 56 sub zeroclickinfospice_attributes {qw(
16             call
17             call_type
18             caller
19             from
20             proxy_cache_valid
21             proxy_ssl_session_reuse
22             to
23             wrap_jsonp_callback
24             wrap_string_callback
25             headers
26             post_body
27             is_cached
28             is_unsafe
29             ttl
30             error_fallback
31             alt_to
32             upstream_timeouts
33             )}
34              
35             my %applied;
36              
37             sub apply_keywords {
38 11     11 0 26 my ( $class, $target ) = @_;
39            
40 11 50       41 return if exists $applied{$target};
41 11         26 $applied{$target} = undef;
42              
43 11         16 my ($callback, $path, $answer_type) = @{params_from_target($target)};
  11         28  
44              
45 11         84 my %zcispice_params = (
46             caller => $target,
47             call_type => 'include',
48             call => $path,
49             wrap_jsonp_callback => 0,
50             wrap_string_callback => 0,
51             accept_header => 0,
52             upstream_timeouts => +{},
53             );
54              
55 11         111 my $stash = Package::Stash->new($target);
56              
57             $stash->add_symbol('&call',sub {
58 0     0   0 my %params = %zcispice_params;
59 0         0 delete $params{'from'};
60 0         0 delete $params{'to'};
61 0         0 delete $params{'wrap_jsonp_callback'};
62 0         0 delete $params{'wrap_string_callback'};
63 0         0 delete $params{'accept_header'};
64 0         0 delete $params{'proxy_cache_valid'};
65 0         0 delete $params{'proxy_ssl_session_reuse'};
66 0         0 delete $params{'upstream_timeouts'};
67 0         0 return DDG::ZeroClickInfo::Spice->new(
68             %params,
69             );
70 11         139 });
71              
72             $stash->add_symbol('&spice_new',sub {
73 11     11   20 shift;
74 11         18 my @call;
75 11         71 my %params = %zcispice_params;
76 11         21 my $data;
77 11         19 delete $params{'from'};
78 11         18 delete $params{'to'};
79 11         23 for (@_) {
80 16 100       58 if (ref $_ eq 'HASH') {
    100          
    50          
    50          
81 1         3 for my $k (keys %{$_}) {
  1         3  
82 1         4 $params{$k} = $_->{$k};
83             };
84             } elsif (ref $_ eq 'DDG::ZeroClickInfo::Spice::Data') {
85 3 100       6 if ($data) {
86 2         6 $data->add_data($_);
87             } else {
88 1         3 $data = $_;
89             }
90             } elsif (ref $_ eq 'DDG::ZeroClickInfo::Spice') {
91 0         0 return $_;
92             } elsif (!defined $_) {
93             # do nothing
94             } else {
95 12         26 push @call, $_;
96             }
97             }
98 11 100       28 $params{'call_data'} = $data->data if $data;
99 11 50       24 if (@call) {
100 11 100       31 if ($params{'call_type'} eq 'include') {
    50          
101 10         29 $params{'call'} = $target->path.join('/',map { uri_encode($_,1) } @call);
  11         1082  
102             } elsif (scalar @call == 1) {
103 1         4 $params{'call'} = uri_encode($call[0]);
104             } else {
105 0         0 croak "DDG::ZeroClickInfo::Spice can't handle more then one value in return list on non include call_type";
106             }
107             }
108 11         11948 DDG::ZeroClickInfo::Spice->new(%params)
109 11         90 });
110              
111             $stash->add_symbol('&spice',sub {
112 9 50   9   50 if (ref $_[0] eq 'HASH') {
113 0         0 for (keys %{$_[0]}) {
  0         0  
114 0         0 $zcispice_params{check_zeroclickinfospice_key($_)} = $_[0]->{$_};
115             }
116             } else {
117 9         24 while (@_) {
118 9         18 my $key = shift;
119 9         14 my $value = shift;
120 9         19 $zcispice_params{check_zeroclickinfospice_key($key)} = $value;
121             }
122             }
123 11         79 });
124              
125 11     1   73 $stash->add_symbol('&callback',sub { $callback });
  1         7  
126              
127 11     11   82 $stash->add_symbol('&path',sub { $path });
  11         564  
128              
129 11         22 my $spice_js;
130              
131             $stash->add_symbol('&data',sub {
132 3 50   3   952 unshift @_, %{$_[0]} if ref $_[0] eq 'HASH';
  0         0  
133 3         10 my ( %data ) = @_;
134 3         39 return DDG::ZeroClickInfo::Spice::Data->new( data => \%data );
135 11         75 });
136              
137             $stash->add_symbol('&spice_js',sub {
138 0 0   3   0 return $spice_js if defined $spice_js;
139 0         0 my ( $self ) = @_;
140 0         0 $spice_js = "";
141 0 0 0     0 if ($target->can('module_share_dir') && (my $spice_js_file = $target->can('share')->('spice.js'))) {
142 0         0 $spice_js .= io($spice_js_file)->slurp;
143 0         0 $spice_js .= "\n";
144             }
145 0 0       0 if ($target->spice_call_type eq 'self') {
146 0         0 $spice_js .= $target->callback."();";
147             }
148 0         0 return $spice_js;
149 11         89 });
150              
151 11         23 my $rewrite;
152             $stash->add_symbol('&has_rewrite',sub {
153 2     5   8 defined $zcispice_params{'to'};
154 11         64 });
155              
156             $stash->add_symbol('&rewrite',sub {
157 1 50   4   4 unless (defined $rewrite) {
158 1 50       3 if ($target->has_rewrite) {
159 1         5 $rewrite = create_rewrite($callback, $path, \%zcispice_params);
160             }
161             else {
162 0         0 $rewrite = '';
163             }
164             }
165 1         20 return $rewrite;
166 11         71 });
167              
168             # make these accessbile, e.g. for duckpan
169             $stash->add_symbol('&alt_rewrites', sub {
170 2     5   4 my %rewrites;
171             # check if we have alternate end points to add
172 2 100       9 if(my $alt_to = $zcispice_params{alt_to}){
173 1         5 my ($base_target) = $target =~ /^(.+::)\w+$/;
174 1         7 while(my ($to, $params) = each %$alt_to){
175 2         12 check_zeroclickinfospice_key($_) for keys %$params;
176 2         6 my $target = "$base_target$to";
177 2         3 my ($callback, $path) = @{params_from_target($target)};
  2         5  
178 2         6 $rewrites{$to} = create_rewrite($callback, $path, $params);
179             }
180             }
181              
182 2         8 return \%rewrites;
183 11         85 });
184              
185             $stash->add_symbol('&get_nginx_conf',sub {
186 2     5   19 my $nginx_conf_func = $stash->get_symbol('&nginx_conf');
187 2 100       12 return $nginx_conf_func->(@_) if $nginx_conf_func;
188            
189             # (20151208 zt) just in case downstream can't handle undef ;-/
190 1         3 my $conf = '';
191 1 50       4 if($target->has_rewrite){
192 1         4 $conf = $target->rewrite->nginx_conf;
193             }
194              
195             # check if we have alternate end points to add
196 1         3 for my $r (values %{$target->alt_rewrites}){
  1         5  
197 0         0 $conf .= $r->nginx_conf;
198             }
199              
200 1         6 return $conf;
201 11         73 });
202              
203             ### SHOULD GET DEPRECATED vvvv ###
204 11     0   71 $stash->add_symbol('&spice_from',sub { $zcispice_params{'from'} });
  0         0  
205 11     0   65 $stash->add_symbol('&spice_to',sub { $zcispice_params{'to'} });
  0         0  
206 11     0   89 $stash->add_symbol('&spice_call_type',sub { $zcispice_params{'call_type'} });
  0         0  
207             ### ^^^^ ###
208              
209             }
210              
211             sub check_zeroclickinfospice_key {
212 11     11 0 24 my $key = shift;
213 11 50       26 if (grep { $key eq $_ } zeroclickinfospice_attributes) {
  187         305  
214 11         55 return $key;
215             } else {
216 0         0 croak $key." is not supported on DDG::ZeroClickInfo::Spice";
217             }
218             }
219              
220             sub params_from_target {
221 15     15 0 31 my $target = shift;
222              
223 15         57 my @parts = split('::',$target);
224 15         37 my $callback = join('_',map { s/([a-z])([A-Z])/$1_$2/g; lc; } @parts);
  45         151  
  45         129  
225 15         52 shift @parts;
226 15         37 my $path = '/js/'.join('/',map { s/([a-z])([A-Z])/$1_$2/g; lc; } @parts).'/';
  30         70  
  30         80  
227 15         29 shift @parts;
228 15         34 my $answer_type = lc(join(' ',@parts));
229              
230 15         64 return [$callback, $path, $answer_type];
231             }
232              
233             sub create_rewrite {
234 3     3 0 7 my ($callback, $path, $params) = @_;
235              
236             return DDG::Rewrite->new(
237             to => $params->{to},
238             defined $params->{from} ? ( from => $params->{from}) : (),
239             defined $params->{proxy_cache_valid} ? ( proxy_cache_valid => $params->{proxy_cache_valid} ) : (),
240             defined $params->{proxy_ssl_session_reuse} ? ( proxy_ssl_session_reuse => $params->{proxy_ssl_session_reuse} ) : (),
241             defined $params->{post_body} ? ( post_body => $params->{post_body} ) : (),
242             callback => $callback,
243             path => $path,
244             wrap_jsonp_callback => $params->{wrap_jsonp_callback},
245             wrap_string_callback => $params->{wrap_string_callback},
246             headers => $params->{headers},
247             error_fallback => $params->{error_fallback},
248             upstream_timeouts => $params->{upstream_timeouts},
249 3 50       70 );
    50          
    50          
    50          
250             }
251              
252             1;
253              
254             __END__