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 = '1016';
5 12     12   42 use strict;
  12         14  
  12         339  
6 12     12   65 use warnings;
  12         11  
  12         255  
7 12     12   36 use Carp;
  12         13  
  12         564  
8 12     12   2934 use DDG::ZeroClickInfo::Spice;
  12         22  
  12         276  
9 12     12   4176 use DDG::ZeroClickInfo::Spice::Data;
  12         20  
  12         296  
10 12     12   4061 use DDG::Rewrite;
  12         24  
  12         337  
11 12     12   63 use Package::Stash;
  12         16  
  12         282  
12 12     12   5109 use URI::Encode qw(uri_encode uri_decode);
  12         108435  
  12         658  
13 12     12   4811 use IO::All;
  12         98929  
  12         84  
14              
15 11     11 0 39 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 16 my ( $class, $target ) = @_;
39            
40 11 50       34 return if exists $applied{$target};
41 11         16 $applied{$target} = undef;
42              
43 11         12 my ($callback, $path, $answer_type) = @{params_from_target($target)};
  11         20  
44              
45 11         77 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         97 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         121 });
71              
72             $stash->add_symbol('&spice_new',sub {
73 11     11   6 shift;
74 11         8 my @call;
75 11         59 my %params = %zcispice_params;
76 11         13 my $data;
77 11         10 delete $params{'from'};
78 11         11 delete $params{'to'};
79 11         12 for (@_) {
80 16 100       41 if (ref $_ eq 'HASH') {
    100          
    50          
    50          
81 1         2 for my $k (keys %{$_}) {
  1         3  
82 1         3 $params{$k} = $_->{$k};
83             };
84             } elsif (ref $_ eq 'DDG::ZeroClickInfo::Spice::Data') {
85 3 100       4 if ($data) {
86 2         7 $data->add_data($_);
87             } else {
88 1         2 $data = $_;
89             }
90             } elsif (ref $_ eq 'DDG::ZeroClickInfo::Spice') {
91 0         0 return $_;
92             } elsif (!defined $_) {
93             # do nothing
94             } else {
95 12         19 push @call, $_;
96             }
97             }
98 11 100       19 $params{'call_data'} = $data->data if $data;
99 11 50       18 if (@call) {
100 11 100       17 if ($params{'call_type'} eq 'include') {
    50          
101 10         20 $params{'call'} = $target->path.join('/',map { uri_encode($_,1) } @call);
  11         705  
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         7979 DDG::ZeroClickInfo::Spice->new(%params)
109 11         70 });
110              
111             $stash->add_symbol('&spice',sub {
112 9 50   9   31 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         18 while (@_) {
118 9         9 my $key = shift;
119 9         6 my $value = shift;
120 9         15 $zcispice_params{check_zeroclickinfospice_key($key)} = $value;
121             }
122             }
123 11         61 });
124              
125 11     1   51 $stash->add_symbol('&callback',sub { $callback });
  1         4  
126              
127 11     11   63 $stash->add_symbol('&path',sub { $path });
  11         287  
128              
129 11         11 my $spice_js;
130              
131             $stash->add_symbol('&data',sub {
132 3 50   3   742 unshift @_, %{$_[0]} if ref $_[0] eq 'HASH';
  0         0  
133 3         7 my ( %data ) = @_;
134 3         38 return DDG::ZeroClickInfo::Spice::Data->new( data => \%data );
135 11         58 });
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         61 });
150              
151 11         12 my $rewrite;
152             $stash->add_symbol('&has_rewrite',sub {
153 2     2   7 defined $zcispice_params{'to'};
154 11         50 });
155              
156             $stash->add_symbol('&rewrite',sub {
157 1 50   1   2 unless (defined $rewrite) {
158 1 50       2 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         18 return $rewrite;
166 11         54 });
167              
168             # make these accessbile, e.g. for duckpan
169             $stash->add_symbol('&alt_rewrites', sub {
170 2     2   3 my %rewrites;
171             # check if we have alternate end points to add
172 2 100       6 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         8 check_zeroclickinfospice_key($_) for keys %$params;
176 2         4 my $target = "$base_target$to";
177 2         2 my ($callback, $path) = @{params_from_target($target)};
  2         4  
178 2         5 $rewrites{$to} = create_rewrite($callback, $path, $params);
179             }
180             }
181              
182 2         6 return \%rewrites;
183 11         66 });
184              
185             $stash->add_symbol('&get_nginx_conf',sub {
186 2     2   18 my $nginx_conf_func = $stash->get_symbol('&nginx_conf');
187 2 100       10 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         3 $conf = $target->rewrite->nginx_conf;
193             }
194              
195             # check if we have alternate end points to add
196 1         2 for my $r (values %{$target->alt_rewrites}){
  1         6  
197 0         0 $conf .= $r->nginx_conf;
198             }
199              
200 1         4 return $conf;
201 11         56 });
202              
203             ### SHOULD GET DEPRECATED vvvv ###
204 11     0   52 $stash->add_symbol('&spice_from',sub { $zcispice_params{'from'} });
  0         0  
205 11     0   47 $stash->add_symbol('&spice_to',sub { $zcispice_params{'to'} });
  0         0  
206 11     0   71 $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 11 my $key = shift;
213 11 50       18 if (grep { $key eq $_ } zeroclickinfospice_attributes) {
  187         155  
214 11         39 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 17 my $target = shift;
222              
223 15         46 my @parts = split('::',$target);
224 15         23 my $callback = join('_',map { s/([a-z])([A-Z])/$1_$2/g; lc; } @parts);
  45         113  
  45         87  
225 15         21 shift @parts;
226 15         21 my $path = '/js/'.join('/',map { s/([a-z])([A-Z])/$1_$2/g; lc; } @parts).'/';
  30         43  
  30         52  
227 15         14 shift @parts;
228 15         25 my $answer_type = lc(join(' ',@parts));
229              
230 15         47 return [$callback, $path, $answer_type];
231             }
232              
233             sub create_rewrite {
234 3     3 0 5 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       65 );
    50          
    50          
    50          
250             }
251              
252             1;
253              
254             __END__