File Coverage

blib/lib/WebService/Upcoming.pm
Criterion Covered Total %
statement 22 137 16.0
branch 2 46 4.3
condition 0 8 0.0
subroutine 5 14 35.7
pod n/a
total 29 205 14.1


line stmt bran cond sub pod time code
1             # *****************************************************************************
2             # * *
3             # * WebService::Upcoming *
4             # * *
5             # *****************************************************************************
6              
7              
8             # Package *********************************************************************
9             package WebService::Upcoming;
10              
11              
12             # Uses ************************************************************************
13 1     1   17031 use strict;
  1         3  
  1         42  
14 1     1   6 use warnings;
  1         2  
  1         34  
15 1     1   1131 use LWP::UserAgent;
  1         111981  
  1         341  
16             eval { require XML::Parser::Lite; };
17             eval { require XML::Mini::Document; } if (!_parser());
18             die("Could not load XML::Parser::Lite or XML::Mini::Document!\n") if
19             (!_parser());
20              
21              
22             # Exports *********************************************************************
23             our @ISA = ('LWP::UserAgent');
24             our $VERSION = '0.05';
25              
26              
27             # Statics *********************************************************************
28             my %Upco_Info;
29              
30              
31             # Code ************************************************************************
32             BEGIN
33             {
34 1     1   3 my $path;
35             my $objc;
36              
37 1         6 $path = (caller())[1];
38 1         10 $path =~ s#WebService/Upcoming.pm$##;
39 1         347 foreach $objc (glob($path.'WebService/Upcoming/Object/*.pm'))
40             {
41 8         5439 require $objc;
42              
43 8         65 $objc = substr($objc,length($path));
44 8         40 $objc =~ s#/#::#g;
45 8         32 $objc =~ s/\.pm$//g;
46 8         50 foreach ($objc->_info())
47             {
48 18         1466 $Upco_Info{$_->{'upco'}} =
49             {
50             'http' => $_->{'http'},
51             'objc' => $objc
52             };
53             }
54             }
55             }
56             sub new
57             {
58 0     0   0 my $clas;
59             my $keyy;
60 0         0 my $vers;
61 0         0 my $self;
62              
63 0         0 ($clas,$keyy,$vers) = @_;
64 0         0 $self = new LWP::UserAgent;
65 0         0 bless($self,$clas);
66              
67 0         0 $self->{'keyy'} = $keyy;
68 0   0     0 $self->{'vers'} = $vers || '1.0';
69 0         0 $self->agent("WebService::Upcoming/$VERSION");
70              
71 0         0 return $self;
72             }
73             sub key
74             {
75 0     0   0 my $self;
76             my $keyy;
77              
78 0         0 ($self,$keyy) = @_;
79 0 0       0 $self->{'keyy'} = $keyy if (defined($keyy));
80              
81 0         0 return $self->{'keyy'};
82             }
83             sub query
84             {
85 0     0   0 my $self;
86             my $upco;
87 0         0 my $args;
88 0         0 my $rqst;
89 0         0 my $rspn;
90 0         0 my $urix;
91              
92 0         0 ($self,$upco,$args) = @_;
93 0         0 $self->{'code'} = 0;
94 0         0 $self->{'text'} = '';
95 0 0       0 if ($self->{'vers'} ne '1.0')
96             {
97 0         0 $self->{'text'} = 'Unknown API version specified';
98 0         0 return undef;
99             }
100 0 0       0 if (!$upco)
101             {
102 0         0 $self->{'text'} = 'No Upcoming API method specified';
103 0         0 return undef;
104             }
105              
106             # Build the request ---------------------------------------------------
107 0 0       0 delete($args->{'username'}) if (!$args->{'username'});
108 0 0       0 delete($args->{'password'}) if (!$args->{'password'});
109 0         0 $args->{'method'} = $upco;
110 0         0 $args->{'api_key'} = $self->{'keyy'};
111 0         0 $urix = URI->new('http://upcoming.org/services/rest/');
112 0         0 $rqst = new HTTP::Request;
113 0         0 $rqst->header('Content-Type' => 'application/x-www-form-urlencoded');
114 0         0 $rqst->method($Upco_Info{$upco}->{'http'});
115 0 0       0 if (!$rqst->method())
    0          
    0          
116             {
117 0         0 $self->{'text'} = 'Unknown Upcoming API method: '.$upco;
118 0         0 return undef;
119             }
120             elsif ($rqst->method() eq 'GET')
121             {
122 0         0 $urix->query_form(%{$args});
  0         0  
123 0         0 $rqst->uri($urix);
124             }
125             elsif ($rqst->method() eq 'POST')
126             {
127 0         0 my $ctnt;
128              
129 0         0 $rqst->uri($urix);
130 0         0 $urix->query_form(%{$args});
  0         0  
131 0         0 $ctnt = $urix->query();
132 0 0       0 if (defined($ctnt))
133             {
134 0         0 $rqst->header('Content-Length' => length($ctnt));
135 0         0 $rqst->content($ctnt);
136             }
137             }
138             else
139             {
140 0         0 $self->{'text'} = 'Unknown HTTP method: '.$rqst->method();
141 0         0 return undef;
142             }
143              
144             # Get the response ----------------------------------------------------
145 0         0 $rspn = $self->request($rqst);
146 0         0 $self->{'code'} = $rspn->code();
147              
148             # HACK: Work around an empty-attribute bug in XML::Mini::Document 1.28
149 0 0       0 $rspn->{'_content'} =~ s/[\w\_\-]+=\"\"//g if
150             (_parser() eq 'Mini::Document');
151              
152 0         0 return $rspn->{'_content'};
153             }
154             sub parse
155             {
156 0     0   0 my $self;
157             my $upco;
158 0         0 my $rspn;
159 0         0 my $hash;
160 0         0 my $objc;
161 0         0 my @objc;
162 0         0 my @list;
163              
164 0         0 ($self,$upco,$rspn) = @_;
165 0         0 $self->{'text'} = '';
166              
167             # Parse the response --------------------------------------------------
168 0 0       0 if (_parser() eq 'Parser::Lite')
169             {
170 0         0 my $lite;
171             my @hash;
172              
173 0         0 $hash = {};
174             $lite = new XML::Parser::Lite('Handlers' =>
175             {
176             'Start' => sub
177             {
178 0     0   0 my $temp;
179              
180 0         0 shift;
181 0         0 push(@hash,$hash);
182 0         0 $temp = shift;
183 0 0       0 $hash->{$temp} = [$hash->{$temp}]
184             if (ref($hash->{$temp}) eq 'HASH');
185 0 0       0 if (ref($hash->{$temp}) eq 'ARRAY')
186             {
187 0         0 push(@{$hash->{$temp}},$hash = {});
  0         0  
188             }
189             else
190             {
191 0         0 $hash = $hash->{$temp} = {};
192             }
193 0         0 while ($temp = shift)
194             {
195 0         0 $hash->{$temp} = shift;
196             }
197             },
198             'End' => sub
199             {
200 0     0   0 shift;
201 0         0 $hash = pop(@hash);
202             }
203 0         0 });
204 0         0 $lite->parse($rspn);
205             }
206             else
207             {
208 0         0 my $mini;
209              
210 0         0 $mini = XML::Mini::Document->new();
211 0         0 $mini->parse($rspn);
212 0         0 $hash = $mini->toHash();
213             }
214              
215             # Response: Bad envelope
216 0 0       0 if (!defined($hash->{'rsp'}))
    0          
    0          
    0          
217             {
218 0         0 $self->{'text'} = 'Bad envelope from server: '.
219 0         0 join(', ',keys(%{$hash}));
220 0         0 return undef;
221             }
222              
223             # Response: Bad status
224             elsif ($hash->{'rsp'}->{'stat'} eq 'fail')
225             {
226 0         0 $self->{'text'} = 'Fail status from server';
227 0 0 0     0 $self->{'text'} = $hash->{'rsp'}->{'error'}->{'msg'} if
228             (($hash->{'rsp'}->{'error'}) &&
229             ($hash->{'rsp'}->{'error'}->{'msg'}));
230 0         0 return undef;
231             }
232              
233             # Response: Bad version
234             elsif ($hash->{'rsp'}->{'version'} ne '1.0')
235             {
236 0         0 $self->{'text'} = 'Unknown version from server: '.
237             $hash->{'rsp'}->{'version'};
238 0         0 return undef;
239             }
240              
241             # Response: Bad... something. What the hell was that?
242             elsif ($hash->{'rsp'}->{'stat'} ne 'ok')
243             {
244 0         0 $self->{'text'} = 'Unknown status from server: '.
245             $hash->{'rsp'}->{'stat'};
246 0         0 return undef;
247             }
248              
249             # Parse the envelope contents -----------------------------------------
250 0         0 $objc = $Upco_Info{$upco}->{'objc'};
251 0 0 0     0 return [] if ((!$objc) || (!$hash->{'rsp'}->{$objc->_name()}));
252 0 0       0 if (ref($hash->{'rsp'}->{$objc->_name()}) eq 'HASH')
253             {
254 0         0 @objc = ($hash->{'rsp'}->{$objc->_name()});
255             }
256             else
257             {
258 0         0 @objc = @{$hash->{'rsp'}->{$objc->_name()}};
  0         0  
259             }
260 0         0 foreach (@objc)
261             {
262 0         0 push(@list,$objc->new($_,$hash->{'rsp'}->{'version'}));
263             }
264 0         0 return \@list;
265             }
266             sub call
267             {
268 0     0   0 my $self;
269             my $upco;
270 0         0 my $args;
271 0         0 my $rspn;
272              
273 0         0 ($self,$upco,$args) = @_;
274 0         0 $rspn = $self->query($upco,$args);
275 0 0       0 return undef if (!defined($rspn));
276 0         0 return $self->parse($upco,$rspn);
277             }
278             sub err_code
279             {
280 0     0   0 return $_[0]->{'http'};
281             }
282             sub err_text
283             {
284 0     0   0 return $_[0]->{'text'};
285             }
286             sub _parser
287             {
288 2 50   2   7 return 'Parser::Lite' if (defined($XML::Parser::Lite::VERSION));
289 2 50       5 return 'Mini::Document' if (defined($XML::Mini::Document::VERSION));
290 2         1154 return undef;
291             }
292             1;
293             __END__