File Coverage

blib/lib/WebService/Yahoo/BOSS.pm
Criterion Covered Total %
statement 27 61 44.2
branch 0 10 0.0
condition 0 12 0.0
subroutine 9 16 56.2
pod 3 4 75.0
total 39 103 37.8


line stmt bran cond sub pod time code
1             package WebService::Yahoo::BOSS;
2              
3             =head1 NAME
4              
5             WebService::Yahoo::BOSS - Interface to the Yahoo BOSS Search API
6              
7             =head1 SYNOPSIS
8              
9             use WebService::Yahoo::BOSS;
10              
11             $boss = WebService::Yahoo::BOSS->new( ckey => $ckey, csecret => $csecret );
12              
13             $response = $boss->Web( q => 'microbrew award winner 2010', ... );
14              
15             $response = $boss->PlaceFinder( q => 'Fleet Street, London', ... );
16              
17            
18             foreach my $result (@{ $response->results }) {
19             print $result->title, "\n";
20             }
21              
22              
23             =head1 DESCRIPTION
24              
25             Provides an interface to the Yahoo BOSS (Build Your Own Search) web service API.
26              
27             Mad props to Yahoo for putting out a premium search api which encourages
28             innovative use.
29              
30             This is a work in progress, so patches welcome!
31              
32             =head2 Interaction
33              
34             Each service has a corresponding method call. The call takes the same
35             parameters as described in the Yahoo BOSS documentation.
36              
37             Each method returns a L object that has the
38             following methods:
39              
40             $response->totalresults; # total number of available results
41             $response->count; # number of results in this set
42             $response->start; # typically same as start argument in request
43             $response->results; # reference to array of result objects
44              
45             The result objects accessed via the C methods are instances of
46             a C class that corresponds to the method
47             called.
48              
49             =head1 METHODS
50              
51             =cut
52              
53 3     3   5978 use Moo;
  3         44621  
  3         16  
54              
55 3     3   7102 use Any::URI::Escape;
  3         8782  
  3         178  
56 3     3   2998 use LWP::UserAgent;
  3         204314  
  3         107  
57 3     3   31 use URI;
  3         7  
  3         74  
58 3     3   2275 use Net::OAuth;
  3         2008  
  3         104  
59 3     3   1868 use Data::Dumper;
  3         13261  
  3         187  
60 3     3   2137 use Data::UUID;
  3         6418  
  3         222  
61 3     3   20 use Carp qw(croak);
  3         5  
  3         197  
62              
63 3     3   1961 use WebService::Yahoo::BOSS::Response;
  3         10  
  3         2293  
64              
65              
66             our $VERSION = '1.03';
67              
68             my $Ug = Data::UUID->new;
69              
70             $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
71              
72              
73             =head2 new
74              
75             $boss = WebService::Yahoo::BOSS->new(
76              
77             # required
78             ckey => $ckey,
79             csecret => $csecret,
80              
81             # optional
82             url => 'http://yboss.yahooapis.com',
83             ua => LWP::UserAgent->new(...),
84             );
85              
86             =cut
87              
88             has 'ckey' => ( is => 'ro', required => 1 );
89             has 'csecret' => ( is => 'ro', required => 1 );
90              
91             has 'url' => (
92             is => 'ro',
93             default => "http://yboss.yahooapis.com",
94             );
95              
96             has 'ua' => (
97             is => 'ro',
98             default => sub {
99             LWP::UserAgent->new(
100             agent => __PACKAGE__ . '_' . $VERSION,
101             keep_alive => 1, # cache connection
102             );
103             }
104             );
105              
106             # last HTTP::Response e.g. to enable introspection of error details
107             has 'http_response' => (
108             is => 'rw'
109             );
110              
111              
112             sub _create_boss_request {
113 0     0     my ($self, $api_path, $args) = @_;
114              
115             # Create request
116 0           my $request = Net::OAuth->request("request token")->new(
117             consumer_key => $self->ckey,
118             consumer_secret => $self->csecret,
119             request_url => $self->url . $api_path,
120             request_method => 'GET',
121             signature_method => 'HMAC-SHA1',
122             timestamp => time,
123             nonce => $Ug->to_string( $Ug->create ),
124             extra_params => $args,
125             callback => '',
126             );
127              
128 0           $request->sign;
129              
130 0           return $request;
131             }
132              
133              
134             sub _perform_boss_request {
135 0     0     my ($self, $request) = @_;
136              
137 0           my $res = $self->ua->get( $request->to_url );
138 0           $self->http_response($res);
139 0 0         unless ( $res->is_success ) {
140 0           die sprintf "%s requesting %s: %s",
141             $res->status_line, $request->to_url, Dumper($res);
142             }
143 0           return $res->decoded_content;
144             }
145              
146              
147             sub _parse_boss_response {
148 0     0     my ($self, $response_content, $result_class) = @_;
149 0           return WebService::Yahoo::BOSS::Response->parse( $response_content, $result_class );
150             }
151              
152              
153             sub ask_boss {
154 0     0 0   my ($self, $api_path, $args, $result_class) = @_;
155              
156 0           my $request = $self->_create_boss_request($api_path, $args);
157 0           my $response_content = $self->_perform_boss_request($request);
158 0           my $response = $self->_parse_boss_response($response_content, $result_class);
159              
160 0           return $response;
161             }
162              
163             =head2 Web
164              
165             Yahoo web search index results with basic url, title, and abstract data.
166              
167             $response = $boss->Web( q => 'microbrew award winner 2010',
168             start => 0,
169             exclude => 'pilsner', );
170              
171             For more information about the arguments and result attributes see
172             L
173              
174             The results are L objects.
175              
176             =cut
177              
178             sub Web {
179 0     0 1   my ( $self, %args ) = @_;
180              
181             croak "q parameter not defined"
182 0 0         unless defined $args{q};
183              
184 0   0       $args{count} ||= 10;
185 0   0       $args{filter} ||= '-porn';
186 0   0       $args{format} ||= 'json';
187             croak 'only json format supported'
188 0 0         unless $args{format} eq 'json';
189              
190 0           return $self->ask_boss('/ysearch/web', \%args, 'WebService::Yahoo::BOSS::Response::Web');
191             }
192              
193             =head2 Images
194              
195             Image search. Image Search includes images from the Yahoo Image Search index and Flickr.
196              
197             $response = $boss->Images( q => 'microbrew award winner 2010',
198             start => 0,
199             exclude => 'pilsner', );
200              
201             For more information about the arguments and result attributes see
202             L
203              
204             The results are L objects.
205              
206             =cut
207              
208             sub Images {
209 0     0 1   my ( $self, %args ) = @_;
210              
211             croak "q parameter not defined"
212 0 0         unless defined $args{q};
213              
214 0   0       $args{count} ||= 10;
215 0   0       $args{filter} ||= '-porn';
216 0   0       $args{format} ||= 'json';
217             croak 'only json format supported'
218 0 0         unless $args{format} eq 'json';
219              
220 0           return $self->ask_boss('/ysearch/images', \%args, 'WebService::Yahoo::BOSS::Response::Images');
221             }
222              
223             =head2 PlaceFinder
224              
225             $response = $boss->PlaceFinder(
226             q => '701 First Ave., Sunnyvale, CA 94089',
227             );
228              
229             For more information about the arguments and result attributes see
230             L
231              
232             The results are L objects.
233              
234             =cut
235              
236             sub PlaceFinder {
237 0     0 1   my ( $self, %args ) = @_;
238              
239 0           $args{flags} .= "J"; # JSON
240              
241 0           return $self->ask_boss('/geo/placefinder', \%args, 'WebService::Yahoo::BOSS::Response::PlaceFinder');
242             }
243              
244              
245             1;
246              
247             =head1 SEE ALSO
248              
249             L
250              
251             L
252              
253             =head1 SOURCE CODE
254              
255             Development version of the source code is available at L. Patches are welcome.
256              
257             =head1 AUTHOR
258              
259             "Fred Moyer", Efred@slwifi.comE
260              
261             The PlaceFinder service, and general refactoring and optimization, by Tim Bunce. Image search by Runar Buvik.
262              
263             =head1 COPYRIGHT AND LICENSE
264              
265             Copyright (C) 2011 by Silver Lining Networks
266              
267             This library is free software; you can redistribute it and/or modify
268             it under the same terms as Perl itself, either Perl version 5.10.1 or,
269             at your option, any later version of Perl 5 you may have available.
270              
271              
272             =cut