File Coverage

blib/lib/WWW/Scraper/ISBN/OpenLibrary_Driver.pm
Criterion Covered Total %
statement 30 79 37.9
branch 0 24 0.0
condition 0 24 0.0
subroutine 10 11 90.9
pod 1 1 100.0
total 41 139 29.5


line stmt bran cond sub pod time code
1             package WWW::Scraper::ISBN::OpenLibrary_Driver;
2              
3 5     5   286592 use strict;
  5         34  
  5         147  
4 5     5   30 use warnings;
  5         12  
  5         189  
5              
6 5     5   30 use vars qw($VERSION @ISA);
  5         11  
  5         419  
7             $VERSION = '0.10';
8              
9             #--------------------------------------------------------------------------
10              
11             =head1 NAME
12              
13             WWW::Scraper::ISBN::OpenLibrary_Driver - Search driver for OpenLibrary online book catalog.
14              
15             =head1 SYNOPSIS
16              
17             See parent class documentation (L)
18              
19             =head1 DESCRIPTION
20              
21             Searches for book information from OpenLibrary online book catalog
22              
23             =cut
24              
25             #--------------------------------------------------------------------------
26              
27             ###########################################################################
28             # Inheritence
29              
30 5     5   39 use base qw(WWW::Scraper::ISBN::Driver);
  5         22  
  5         2589  
31              
32             ###########################################################################
33             # Modules
34              
35 5     5   9395 use WWW::Mechanize;
  5         770184  
  5         218  
36 5     5   3505 use JSON;
  5         49496  
  5         32  
37              
38             ###########################################################################
39             # Constants
40              
41 5     5   713 use constant SEARCH => 'http://openlibrary.org/api/books?jscmd=data&format=json&bibkeys=ISBN:';
  5         12  
  5         304  
42 5     5   33 use constant LB2G => 453.59237; # number of grams in a pound (lb)
  5         12  
  5         284  
43 5     5   30 use constant OZ2G => 28.3495231; # number of grams in an ounce (oz)
  5         11  
  5         227  
44 5     5   40 use constant IN2MM => 25.4; # number of inches in a millimetre (mm)
  5         13  
  5         4196  
45              
46             #--------------------------------------------------------------------------
47              
48             ###########################################################################
49             # Public Interface
50              
51             =head1 METHODS
52              
53             =over 4
54              
55             =item C
56              
57             Creates a query string, then passes the appropriate form fields to the OpenLibrary
58             server.
59              
60             The returned page should be the correct catalog page for that ISBN. If not the
61             function returns zero and allows the next driver in the chain to have a go. If
62             a valid page is returned, the following fields are returned via the book hash:
63              
64             isbn (now returns isbn13)
65             isbn10
66             isbn13
67             ean13 (industry name)
68             author
69             title
70             book_link
71             image_link
72             pubdate
73             publisher
74             binding (if known)
75             pages (if known)
76             weight (if known) (in grammes)
77             width (if known) (in millimetres)
78             height (if known) (in millimetres)
79             depth (if known) (in millimetres)
80              
81             The book_link and image_link refer back to the OpenLibrary website.
82              
83             =back
84              
85             =cut
86              
87             sub search {
88 0     0 1   my $self = shift;
89 0           my $isbn = shift;
90 0           my $data;
91 0           $self->found(0);
92 0           $self->book(undef);
93              
94 0           my $mech = WWW::Mechanize->new();
95 0           $mech->agent_alias( 'Linux Mozilla' );
96              
97 0           eval { $mech->get( SEARCH . $isbn ) };
  0            
98 0 0 0       return $self->handler("OpenLibrary website appears to be unavailable.")
      0        
99             if($@ || !$mech->success() || !$mech->content());
100              
101 0           my $code = decode_json($mech->content());
102             #use Data::Dumper;
103             #print STDERR "\n# code=".Dumper($code);
104              
105             return $self->handler("Failed to find that book on OpenLibrary website.")
106 0 0         unless($code->{'ISBN:'.$isbn});
107              
108 0           $data->{isbn13} = $code->{'ISBN:'.$isbn}{identifiers}{isbn_13}[0];
109 0           $data->{isbn10} = $code->{'ISBN:'.$isbn}{identifiers}{isbn_10}[0];
110              
111             return $self->handler("Failed to find that book on OpenLibrary website.")
112 0 0 0       unless($isbn eq $data->{isbn13} || $isbn eq $data->{isbn10});
113              
114             #use Data::Dumper;
115             #print STDERR "\n# " . Dumper($data);
116              
117 0           $data->{isbn13} = $code->{'ISBN:'.$isbn}{identifiers}{isbn_13}[0];
118 0           $data->{isbn10} = $code->{'ISBN:'.$isbn}{identifiers}{isbn_10}[0];
119 0           $data->{image} = $code->{'ISBN:'.$isbn}{cover}{large};
120 0           $data->{thumb} = $code->{'ISBN:'.$isbn}{cover}{small};
121 0           $data->{author} = $code->{'ISBN:'.$isbn}{authors}[0]{name};
122 0           $data->{title} = $code->{'ISBN:'.$isbn}{title};
123 0           $data->{publisher} = $code->{'ISBN:'.$isbn}{publishers}[0]{name};
124 0           $data->{pubdate} = $code->{'ISBN:'.$isbn}{publish_date};
125 0           $data->{pages} = $code->{'ISBN:'.$isbn}{number_of_pages};
126 0           $data->{url} = $code->{'ISBN:'.$isbn}{url};
127 0           $data->{weight} = $code->{'ISBN:'.$isbn}{weight};
128              
129 0 0 0       if($data->{weight}&& $data->{weight} =~ /([\d.]+)\s*(?:lbs|pounds)/) {
    0 0        
    0 0        
130 0           $data->{weight} = int($1 * LB2G);
131             } elsif($data->{weight} && $data->{weight} =~ /([\d.]+)\s*(?:ozs|ounces)/) {
132 0           $data->{weight} = int($1 * OZ2G);
133             } elsif($data->{weight} && $data->{weight} =~ /([\d.]+)\s*(?:g|grams)/) {
134 0           $data->{weight} = int($1);
135             } else {
136 0           $data->{weight} = undef;
137             }
138              
139 0           eval { $mech->get( $data->{url} ) };
  0            
140 0 0 0       return $self->handler("OpenLibrary website appears to be unavailable.")
      0        
141             if($@ || !$mech->success() || !$mech->content());
142              
143             # The Book page
144 0           my $html = $mech->content();
145             #print STDERR "\n# html=[\n$html\n]\n";
146              
147             # catch any data not in the JSON
148             ($data->{height},$data->{width},$data->{depth})
149 0           = $html =~ m!
Dimensions
\s*
([\d.]+)\s+x\s+([\d.]+)\s+x\s+([\d.]+)\s+inches!si;
150 0           ($data->{binding}) = $html =~ m!
Format
\s*
([^<]+)!si;
151              
152 0 0         $data->{height} = int($data->{height} * IN2MM) if($data->{height});
153 0 0         $data->{width} = int($data->{width} * IN2MM) if($data->{width});
154 0 0         $data->{depth} = int($data->{depth} * IN2MM) if($data->{depth});
155              
156             #use Data::Dumper;
157             #print STDERR "\n# " . Dumper($data);
158              
159 0 0         return $self->handler("Could not extract data from OpenLibrary result page.")
160             unless(defined $data);
161              
162             # trim top and tail
163 0 0         foreach (keys %$data) { next unless(defined $data->{$_});$data->{$_} =~ s/^\s+//;$data->{$_} =~ s/\s+$//; }
  0            
  0            
  0            
164              
165             my $bk = {
166             'ean13' => $data->{isbn13},
167             'isbn13' => $data->{isbn13},
168             'isbn10' => $data->{isbn10},
169             'isbn' => $data->{isbn13},
170             'author' => $data->{author},
171             'title' => $data->{title},
172             'book_link' => $mech->uri(),
173             'image_link' => $data->{image},
174             'thumb_link' => $data->{thumb},
175             'pubdate' => $data->{pubdate},
176             'publisher' => $data->{publisher},
177             'binding' => $data->{binding},
178             'pages' => $data->{pages},
179             'weight' => $data->{weight},
180             'width' => $data->{width},
181             'height' => $data->{height},
182             'depth' => $data->{depth},
183 0           'json' => $code,
184             'html' => $html
185             };
186              
187             #use Data::Dumper;
188             #print STDERR "\n# book=".Dumper($bk);
189              
190 0           $self->book($bk);
191 0           $self->found(1);
192 0           return $self->book;
193             }
194              
195             1;
196             __END__