File Coverage

blib/lib/WWW/MovieReviews/NYT.pm
Criterion Covered Total %
statement 75 113 66.3
branch 42 82 51.2
condition 10 21 47.6
subroutine 19 19 100.0
pod 4 5 80.0
total 150 240 62.5


line stmt bran cond sub pod time code
1             package WWW::MovieReviews::NYT;
2              
3             $WWW::MovieReviews::NYT::VERSION = '0.05';
4              
5             =head1 NAME
6              
7             WWW::MovieReviews::NYT - Interface to NewYorkTimes Movie Reviews API.
8              
9             =head1 VERSION
10              
11             Version 0.05
12              
13             =cut
14              
15 6     6   17790 use 5.006;
  6         13  
  6         186  
16 6     6   22 use strict; use warnings;
  6     6   8  
  6         155  
  6         21  
  6         9  
  6         108  
17 6     6   3498 use Data::Dumper;
  6         44348  
  6         369  
18 6     6   259011 use LWP::UserAgent;
  6         537005  
  6         178  
19 6     6   3214 use HTTP::Request::Common;
  6         10160  
  6         8950  
20              
21             my $API_VERSION = 'v2';
22             my $API_URL = {
23             1 => "http://api.nytimes.com/svc/movies/${API_VERSION}/reviews/search.xml",
24             2 => "http://api.nytimes.com/svc/movies/${API_VERSION}/reviews/",
25             3 => "http://api.nytimes.com/svc/movies/${API_VERSION}/reviews/reviewer/",
26             4 => "http://api.nytimes.com/svc/movies/${API_VERSION}/critics/",
27             };
28              
29             =head1 DESCRIPTION
30              
31             With the Movie Reviews API,you can search New York Times movie reviews by keyword
32             and get lists of NYT Critics' Picks.Usage is limited to 5000 requests per day
33             (rate limits are subject to change). Currently supports version v2. As of now it
34             only gets result in XML format.
35              
36             The Movie Reviews service uses a RESTful style. Four request types are available:
37              
38             +-----+----------------------------------------------+
39             | No. | Type |
40             +-----+----------------------------------------------+
41             | 1 | Search reviews by keyword. |
42             | 2 | Get lists of reviews and NYT Critics' Picks. |
43             | 3 | Get reviews by reviewer. |
44             | 4 | Get information about reviewers. |
45             +-----+----------------------------------------------+
46              
47             =head1 CONSTRUCTOR
48              
49             The constructor expects your application API, which you can get it for FREE from
50             The New York Times Developer site. You need to create an account first with them.
51             You only need to pick any username of your choice and password to get it started.
52             Once you have the account setup you can then request for API Key and accept their
53             Terms and Condition for usage. Here is the link for L.
54              
55             use strict; use warnings;
56             use WWW::MovieReviews::NYT;
57              
58             my $api_key = 'Your_API_Key';
59             my $movie = WWW::MovieReviews::NYT->new($api_key);
60              
61             =cut
62              
63             sub new {
64 5     5 0 60 my ($class, $key) = @_;
65              
66 5 100       21 die("ERROR: API Key is missing.\n") unless defined $key;
67 4         41 my $self = { key => $key,
68             browser => LWP::UserAgent->new()
69             };
70 4         842629 bless $self, $class;
71 4         15 return $self;
72             }
73              
74             =head1 METHODS
75              
76             =head2 by_keyword()
77              
78             Search the reviews by given keyword. Possible parameters listed below:
79              
80             +------------------+-----------------------------------------+------------------------+
81             | Name | Description | Example |
82             +------------------+-----------------------------------------+------------------------+
83             | query | Search keyword; matches movie title. | 'wild+west' |
84             | critics-pick | Limits by NYT Critics Picks status. | Y | N |
85             | thausand-best | Limits by Best 1,000 Movies status. | Y | N |
86             | dvd | Limits by format. | Y | N |
87             | reviewer | Limits by a specific NYT critic. | monohla.dargis |
88             | publication-date | Limits by date or range of dates. | YYYY-MM-DD;YYYY-MM-DD |
89             | opening-date | Limits by date or range of dates. | YYYY-MM-DD;YYYY-MM-DD |
90             | offset | Sets the starting point of the results. | Multiple of 20. |
91             | order | Sets the sort order of the results. | by-title |
92             | | | or by-publication-date |
93             | | | or by-opening-date |
94             | | | or by-dvd-release-date |
95             +------------------+-----------------------------------------+------------------------+
96              
97             You can specify up to three search parameters (order, limit and offset do not
98             count toward this maximum, but query does).
99              
100             use strict; use warnings;
101             use WWW::MovieReviews::NYT;
102              
103             my $api_key = 'Your_API_Key';
104             my $movie = WWW::MovieReviews::NYT->new($api_key);
105             print $movie->by_keyword({'query' => 'wild+west'});
106              
107             =cut
108              
109             # http://api.nytimes.com/svc/movies/v2/reviews/search.xml?query=big&thousand-best=Y&opening-date=1930-01-01;2000-01-01
110             sub by_keyword {
111 13     13 1 5582 my ($self, $param) = @_;
112              
113 13         24 _validate_by_keyword_param($param);
114              
115 0         0 my ($url, $request, $response);
116 0         0 $url = sprintf("%s?api-key=%s", $API_URL->{1}, $self->{key});
117 0 0       0 $url .= sprintf("&query=%s", $param->{'query'}) if exists($param->{'query'});
118 0 0       0 $url .= sprintf("&critics-pick=%s", $param->{'critics-pick'}) if exists($param->{'critics-pick'});
119 0 0       0 $url .= sprintf("&thausand-best=%s", $param->{'thausand-best'}) if exists($param->{'thausand-best'});
120 0 0       0 $url .= sprintf("&dvd=%s", $param->{'dvd'}) if exists($param->{'dvd'});
121 0 0       0 $url .= sprintf("&reviewer=%s", $param->{'reviewer'}) if exists($param->{'reviewer'});
122 0 0       0 $url .= sprintf("&publication-date=%s", $param->{'publication-date'}) if exists($param->{'publication-date'});
123 0 0       0 $url .= sprintf("&opening-date=%s", $param->{'opening-date'}) if exists($param->{'opening-date'});
124 0 0       0 $url .= sprintf("&offset=%d", $param->{'offset'}) if exists($param->{'offset'});
125 0 0       0 $url .= sprintf("&order=%s", $param->{'order'}) if exists($param->{'order'});
126 0         0 $request = HTTP::Request->new(GET=>$url);
127 0         0 $response = $self->{browser}->request($request);
128              
129 0 0       0 die("ERROR: Couldn't connect to [$url].\n") unless $response->is_success;
130              
131 0         0 return $response->content;
132             }
133              
134             =head2 by_reviews_critics()
135              
136             Search by reviews and NYT critics. Possible parameters listed below:
137              
138             +---------------+-----------------------------------------+-------------------------+
139             | Name | Description | Example |
140             +---------------+-----------------------------------------+-------------------------+
141             | resource-type | All reviews or NYT Critics Picks. | all | picks | dvd-picks |
142             | offset | Sets the starting point of the results. | Multiple of 20. |
143             | order | Sets the sort order of the results. | by-title |
144             | | | or by-publication-date |
145             | | | or by-opening-date |
146             | | | or by-dvd-release-date |
147             +---------------+-----------------------------------------+-------------------------+
148              
149             use strict; use warnings;
150             use WWW::MovieReviews::NYT;
151              
152             my $api_key = 'Your_API_Key';
153             my $movie = WWW::MovieReviews::NYT->new($api_key);
154             print $movie->by_reviews_critics({'resource-type' => 'all', 'order' => 'by-title'});
155              
156             =cut
157              
158             # http://api.nytimes.com/svc/movies/v2/reviews/dvd-picks.xml?order=by-date&offset=40
159             sub by_reviews_critics {
160 6     6 1 1541 my ($self, $param) = @_;
161              
162 6         11 _validate_by_reviews_critics_param($param);
163              
164 0         0 my ($url, $request, $response);
165 0         0 $url = sprintf("%s%s.xml?api-key=%s", $API_URL->{2}, $param->{'resource-type'}, $self->{key});
166 0 0       0 $url .= sprintf("&offset=%d", $param->{'offset'}) if exists($param->{'offset'});
167 0 0       0 $url .= sprintf("&order=%s", $param->{'order'}) if exists($param->{'order'});
168 0         0 $request = HTTP::Request->new(GET=>$url);
169 0         0 $response = $self->{browser}->request($request);
170              
171 0 0       0 die("ERROR: Couldn't connect to [$url].\n") unless $response->is_success;
172              
173 0         0 return $response->content;
174             }
175              
176             =head2 by_reviewer()
177              
178             Search by reviewer. Possible parameters listed below:
179              
180             +---------------+-----------------------------------------+------------------------+
181             | Name | Description | Example |
182             +---------------+-----------------------------------------+------------------------+
183             | reviewer-name | The name of the Times reviewer. | manohla-dargis |
184             | critics-pick | Limits by NYT Critics Picks status. | Y | N |
185             | offset | Sets the starting point of the results. | Multiple of 20. |
186             | order | Sets the sort order of the results. | by-title |
187             | | | or by-publication-date |
188             | | | or by-opening-date |
189             | | | or by-dvd-release-date |
190             +---------------+-----------------------------------------+------------------------+
191              
192             use strict; use warnings;
193             use WWW::MovieReviews::NYT;
194              
195             my $api_key = 'Your_API_Key';
196             my $movie = WWW::MovieReviews::NYT->new($api_key);
197             print $movie->by_reviewer({'reviewer-name' => 'manohla-dargis',
198             'critics-pick' => 'Y',
199             'order' => 'by-title'});
200              
201             =cut
202              
203             # http://api.nytimes.com/svc/movies/v2/reviews/reviewer/manohla-dargis/all.xml?order=by-title
204             sub by_reviewer {
205 7     7 1 1850 my ($self, $param) = @_;
206              
207 7         15 _validate_by_reviewer_param($param);
208              
209 0         0 my ($url, $request, $response);
210 0         0 $url = sprintf("%s%s/all.xml?api-key=%s", $API_URL->{3}, $param->{'reviewer-name'}, $self->{key});
211 0 0       0 $url .= sprintf("&critics-pick=%s", $param->{'critics-pick'}) if exists($param->{'critics-pick'});
212 0 0       0 $url .= sprintf("&offset=%d", $param->{'offset'}) if exists($param->{'offset'});
213 0 0       0 $url .= sprintf("&order=%s", $param->{'order'}) if exists($param->{'order'});
214 0         0 $request = HTTP::Request->new(GET=>$url);
215 0         0 $response = $self->{browser}->request($request);
216              
217 0 0       0 die("ERROR: Couldn't connect to [$url].\n") unless $response->is_success;
218              
219 0         0 return $response->content;
220             }
221              
222             =head2 get_reviewer_details()
223              
224             Get reviewer details. Possible parameters listed below:
225              
226             +---------------+--------------------------------------------+-----------------------------+
227             | Name | Description | Example |
228             +---------------+--------------------------------------------+-----------------------------+
229             | resource-type | A set of reviewers or a specific reviewer. | all | full-time | part-time |
230             | | | reviewer | [reviewer-name] |
231             +---------------+--------------------------------------------+-----------------------------+
232              
233             use strict; use warnings;
234             use WWW::MovieReviews::NYT;
235              
236             my $api_key = 'Your_API_Key';
237             my $movie = WWW::MovieReviews::NYT->new($api_key);
238             print $movie->get_reviewer_details('all');
239              
240             =cut
241              
242             # http://api.nytimes.com/svc/movies/v2/critics/a-o-scott.xml
243             sub get_reviewer_details {
244 2     2 1 627 my ($self, $type) = @_;
245              
246 2         6 _validate_resource_type($type);
247              
248 0         0 my ($url, $request, $response);
249 0         0 $url = sprintf("%s%s.xml?api-key=%s", $API_URL->{4}, $type, $self->{key});
250 0         0 $request = HTTP::Request->new(GET=>$url);
251 0         0 $response = $self->{browser}->request($request);
252              
253 0 0       0 die("ERROR: Couldn't connect to [$url].\n") unless $response->is_success;
254              
255 0         0 return $response->content;
256             }
257              
258             sub _validate_by_keyword_param {
259 13     13   10 my ($param) = @_;
260              
261 13 100       30 die("ERROR: Missing input parameters.\n") unless defined $param;
262 12 100       34 die("ERROR: Input param has to be a ref to HASH.\n") if (ref($param) ne 'HASH');
263 11 100       25 die("ERROR: Missing key query.\n") unless exists($param->{'query'});
264 10 100 100     53 die("ERROR: Invalid value for key reviewer [". $param->{'reviewer'} . "].\n")
265             if (defined($param->{'reviewer'}) && ($param->{'reviewer'} !~ /\b[a-z\.\-]+\b/i));
266              
267 9         22 _validate_y_n('critics-pick', $param->{'critics-pick'});
268 8         18 _validate_y_n('thausand-best', $param->{'thausand-best'});
269 7         14 _validate_y_n('dvd', $param->{'dvd'});
270 6         12 _validate_date('publication-date', $param->{'publication-date'});
271 4         8 _validate_date('opening-date', $param->{'opening-date'});
272 2         7 _validate_key_offset($param->{'offset'});
273 1         4 _validate_key_order($param->{'order'});
274             }
275              
276             sub _validate_by_reviews_critics_param {
277 6     6   7 my ($param) = @_;
278              
279 6 100       17 die("ERROR: Missing input parameters.\n") unless defined $param;
280 5 100       16 die("ERROR: Input param has to be a ref to HASH.\n") if (ref($param) ne 'HASH');
281 4 100       12 die("ERROR: Missing key resource-type.\n") unless exists($param->{'resource-type'});
282 3 100       17 die("ERROR: Invalid value for key resource-type [". $param->{'resource-type'} . "].\n")
283             unless ($param->{'resource-type'} =~ /\ball\b|\bpicks\b|\bdvd\-picks\b/i);
284              
285 2         6 _validate_key_offset($param->{'offset'});
286 1         4 _validate_key_order($param->{'order'});
287             }
288              
289             sub _validate_by_reviewer_param {
290 7     7   8 my ($param) = @_;
291              
292 7 100       17 die("ERROR: Missing input parameters.\n") unless defined $param;
293 6 100       17 die("ERROR: Input param has to be a ref to HASH.\n") if (ref($param) ne 'HASH');
294 5 100       14 die("ERROR: Missing key reviewer-name.\n") unless exists($param->{'reviewer-name'});
295 4 100       24 die("ERROR: Invalid value for key reviewer-name [". $param->{'reviewer-name'} . "].\n")
296             unless ($param->{'reviewer-name'} =~ /\b[a-z\.\-]+\b/i);
297              
298 3         9 _validate_y_n('critics-pick', $param->{'critics-pick'});
299 2         6 _validate_key_offset($param->{'offset'});
300 1         4 _validate_key_order($param->{'order'});
301             }
302              
303             sub _validate_date {
304 10     10   15 my ($key, $value) = @_;
305              
306 10 100       17 return unless defined $value;
307              
308 4         3 my @values;
309 4 100       18 ($value =~ /\;/)
310             ?
311             (@values = split /\;/,$value)
312             :
313             (@values = ($value));
314              
315 4         8 foreach (@values) {
316 6 100 66     50 die("ERROR: Invalid value for key $key [$value].\n")
317             if (defined($_) && ($_ !~ /^\d{4}\-\d{2}\-\d{2}$/));
318             }
319             }
320              
321             sub _validate_y_n {
322 27     27   37 my ($key, $value) = @_;
323              
324 27 100       51 return unless defined $value;
325              
326 4 50 33     42 die("ERROR: Invalid value for key $key [$value].\n") if (defined($value) && ($value !~ /^[y|n]$/i));
327             }
328              
329             sub _validate_key_offset {
330 6     6   9 my ($offset) = @_;
331              
332 6 100       17 return unless defined $offset;
333              
334 3 50 33     62 die("ERROR: Invalid value for key offset [$offset].\n")
      33        
      33        
335             unless (defined($offset)
336             &&
337             ($offset =~ /^\d{1,}$/)
338             &&
339             (($offset == 0) || ($offset%20 == 0)));
340             }
341              
342             sub _validate_key_order {
343 3     3   6 my ($order) = @_;
344              
345 3 50 33     37 die("ERROR: Invalid value for key order [$order].\n")
346             if (defined($order)
347             &&
348             ($order !~ /\bby\-title\b|\bby\-publication\-date\b|\bby\-opening\-date\b|\bby\-dvd\-release\-date\b/i));
349             }
350              
351             sub _validate_resource_type {
352 2     2   3 my ($type) = @_;
353              
354 2 100       10 die("ERROR: Missing key resource-type.\n") unless defined $type;
355 1 50       20 die("ERROR: Invalid value for key resource-type [$type].\n")
356             unless ($type =~ /\ball\b|\bfull\-time\b|\bpart\-time\b|\breviewer\b|[a..z\.\-]+/i);
357             }
358              
359             =head1 AUTHOR
360              
361             Mohammad S Anwar, C<< >>
362              
363             =head1 REPOSITORY
364              
365             L
366              
367             =head1 BUGS
368              
369             Please report any bugs or feature requests to C, or
370             through the web interface at L.
371             I will be notified and then you'll automatically be notified of progress on your bug as I make
372             changes.
373              
374             =head1 SUPPORT
375              
376             You can find documentation for this module with the perldoc command.
377              
378             perldoc WWW::MovieReviews::NYT
379              
380             You can also look for information at:
381              
382             =over 4
383              
384             =item * RT: CPAN's request tracker
385              
386             L
387              
388             =item * AnnoCPAN: Annotated CPAN documentation
389              
390             L
391              
392             =item * CPAN Ratings
393              
394             L
395              
396             =item * Search CPAN
397              
398             L
399              
400             =back
401              
402             =head1 LICENSE AND COPYRIGHT
403              
404             Copyright 2011 Mohammad S Anwar.
405              
406             This program is free software; you can redistribute it and/or modify it under the terms of
407             either: the GNU General Public License as published by the Free Software Foundation; or the
408             Artistic License.
409              
410             See http://dev.perl.org/licenses/ for more information.
411              
412             =head1 DISCLAIMER
413              
414             This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
415             without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
416              
417             =cut
418              
419             1; # End of WWW::MovieReviews::NYT