File Coverage

blib/lib/WWW/MovieReviews/NYT.pm
Criterion Covered Total %
statement 85 123 69.1
branch 42 82 51.2
condition 10 21 47.6
subroutine 20 20 100.0
pod 4 5 80.0
total 161 251 64.1


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