File Coverage

blib/lib/WWW/LibraryThing/Covers.pm
Criterion Covered Total %
statement 21 76 27.6
branch 0 24 0.0
condition 0 15 0.0
subroutine 7 12 58.3
pod 2 2 100.0
total 30 129 23.2


line stmt bran cond sub pod time code
1             package WWW::LibraryThing::Covers;
2              
3 1     1   35245 use 5.006;
  1         3  
  1         35  
4 1     1   6 use strict;
  1         43  
  1         102  
5 1     1   6 use warnings;
  1         6  
  1         29  
6              
7 1     1   1237 use LWP::UserAgent;
  1         2060304  
  1         42  
8 1     1   1938 use Image::Size;
  1         6288  
  1         78  
9 1     1   2050 use Time::HiRes qw/sleep time/;
  1         1942  
  1         5  
10              
11             =encoding utf8
12              
13             =head1 NAME
14              
15             WWW::LibraryThing::Covers - Interface to LibraryThing book cover API
16              
17             =head1 VERSION
18              
19             Version 0.0002
20              
21             =cut
22              
23             our $VERSION = '0.0002';
24              
25             # defaults
26 1     1   237 use constant BASE_URL => 'http://covers.librarything.com/devkey';
  1         2  
  1         724  
27              
28             =head1 SYNOPSIS
29              
30             use WWW::LibraryThing::Covers;
31              
32             my %config = (api_key => 'd231aa37c9b4f5d304a60a3d0ad1dad4',
33             directory => 'images',
34             size => 'large');
35              
36             my $lt_covers = WWW::LibraryThing::Covers->new(%config);
37            
38             $lt_covers->get('0977920151');
39              
40             =head1 DESCRIPTION
41              
42             Retrieves book covers from LibraryThing based on ISBN-10 numbers.
43              
44             Please checkout the terms of use first.
45              
46             =head1 CONSTRUCTOR
47              
48             =head2 new
49              
50             Create a WWW::LibraryThing::Covers object with the following parameters:
51              
52             =over 4
53              
54             =item api_key
55              
56             Your LibraryThing API key (required).
57              
58             =item directory
59              
60             Output directory for the cover images.
61              
62             =item size
63              
64             Default size for cover images (optional, defaults to medium).
65             Possible values are large, medium and small.
66              
67             =item not_found
68              
69             Defines behaviour for cover images not available. LibraryThing returns
70             a transparent 1×1 pixel GIF image.
71              
72             =item delay
73              
74             Delay between requests. Defaults to 1 second as this is required
75             for automatic downloads.
76              
77             =item user_agent
78              
79             LWP::UserAgent object (optional).
80              
81             =back
82              
83             =cut
84              
85             sub new {
86 0     0 1   my ($class, $self);
87              
88 0           $class = shift;
89 0           $self = {@_};
90              
91 0 0         unless ($self->{api_key}) {
92 0           die "LibraryThing API key required.";
93             }
94              
95 0   0       $self->{not_found} ||= '';
96 0   0       $self->{size} ||= 'medium';
97            
98 0 0         unless (exists $self->{delay}) {
99 0           $self->{delay} = 1;
100             }
101              
102             # last access time
103 0   0       $self->{last_access} ||= 0;
104              
105 0           bless $self, $class;
106              
107 0           return $self;
108             }
109              
110             =head1 METHODS
111              
112             =head2 get
113              
114             Retrieves an image for given isbn and size (optional).
115              
116             The image is stored as ISBN.jpg in the directory provided
117             to the constructor or just returned as scalar reference
118             otherwise.
119              
120             The actual return value in case of success is a list
121             with three members:
122              
123             =over
124              
125             =item *
126              
127             Filename or scalar reference of the image data.
128              
129             =item *
130              
131             Image width.
132              
133             =item *
134              
135             Image size.
136              
137             =back
138              
139             Returns undef in case of errors.
140              
141             Returns 0 if constructor parameter not_found is set to return_zero
142             and cover image is not available.
143              
144             =cut
145              
146             sub get {
147 0     0 1   my ($self, $isbn, $size) = @_;
148 0           my ($url, $response, $image_ref, $width, $height, $ret);
149              
150 0   0       $size ||= $self->{size};
151 0   0       $self->{user_agent} ||= $self->_user_agent;
152              
153 0           $url = join('/', BASE_URL, $self->{api_key}, $size, 'isbn', $isbn);
154            
155 0 0         if ($self->{delay}) {
156 0           $self->_delay();
157             }
158              
159 0           $response = $self->{user_agent}->get($url);
160              
161 0 0         if ($response->is_success) {
162 0           $image_ref = \$response->content;
163              
164             # sanity checks
165 0 0         if (length($$image_ref) == 0) {
166 0           return undef;
167             }
168              
169             # check whether we got a really image or just a 1x1 placeholder
170 0           ($width, $height) = imgsize($image_ref);
171              
172 0 0 0       if ($width == 1 && $height == 1) {
173 0 0         if ($self->{not_found} eq 'return_zero') {
174 0           return 0;
175             }
176             }
177              
178 0 0         if ($self->{directory}) {
179 0 0         if ($ret = $self->_store_image($isbn, \$response->content)) {
180 0           return ($ret, $width, $height);
181             }
182             else {
183 0           return undef;
184             }
185             }
186             else {
187 0           return (\$response->content, $width, $height);
188             }
189             }
190             else {
191 0           return undef;
192             }
193             }
194              
195             sub _store_image {
196 0     0     my ($self, $isbn, $data) = @_;
197 0           my ($file);
198              
199 0           $file = join('/', $self->{directory}, "$isbn.jpg");
200              
201 0 0         unless (open (DLFILE, '>', $file)) {
202 0           return undef;
203             }
204            
205 0           print DLFILE $$data;
206 0           close DLFILE;
207              
208 0           return $file;
209             }
210              
211             sub _delay {
212 0     0     my $self = shift;
213 0           my $now;
214              
215 0           $now = time();
216              
217 0 0         if ($self->{last_access} > 0) {
218 0 0         if ($now - $self->{last_access} < $self->{delay}) {
219 0           sleep($now - $self->{last_access});
220             }
221             }
222              
223 0           $self->{last_access} = $now;
224             }
225              
226             sub _user_agent {
227 0     0     my $self = shift;
228 0           my ($lwp, $lwp_agent);
229              
230 0           $lwp = LWP::UserAgent->new;
231 0           $lwp_agent = $lwp->agent;
232 0           $lwp->agent(__PACKAGE__ . "/$VERSION ($lwp_agent)");
233            
234 0           $self->{user_agent} = $lwp;
235             }
236              
237             1;
238              
239             =head1 AUTHOR
240              
241             Stefan Hornburg (Racke), C<< >>
242              
243             =head1 BUGS
244              
245             Please report any bugs or feature requests to C, or through
246             the web interface at L. I will be notified, and then you'll
247             automatically be notified of progress on your bug as I make changes.
248              
249             =head1 SUPPORT
250              
251             You can find documentation for this module with the perldoc command.
252              
253             perldoc WWW::LibraryThing::Covers
254              
255              
256             You can also look for information at:
257              
258             =over 4
259              
260             =item * RT: CPAN's request tracker (report bugs here)
261              
262             L
263              
264             =item * AnnoCPAN: Annotated CPAN documentation
265              
266             L
267              
268             =item * CPAN Ratings
269              
270             L
271              
272             =item * Search CPAN
273              
274             L
275              
276             =back
277              
278              
279             =head1 ACKNOWLEDGEMENTS
280              
281              
282             =head1 LICENSE AND COPYRIGHT
283              
284             Copyright 2011,2012 Stefan Hornburg (Racke).
285              
286             This program is free software; you can redistribute it and/or modify it
287             under the terms of either: the GNU General Public License as published
288             by the Free Software Foundation; or the Artistic License.
289              
290             See http://dev.perl.org/licenses/ for more information.
291              
292              
293             =cut
294              
295             1; # End of WWW::LibraryThing::Covers