File Coverage

blib/lib/WWW/Scraper/ISBN/Bookstore_Driver.pm
Criterion Covered Total %
statement 62 62 100.0
branch 7 14 50.0
condition 4 12 33.3
subroutine 8 8 100.0
pod 1 1 100.0
total 82 97 84.5


\s*!si; \s*!si; \s*!si; \s*!si; \s*!si; \s*!si; \s*!si; .*?!si;
line stmt bran cond sub pod time code
1             package WWW::Scraper::ISBN::Bookstore_Driver;
2              
3 6     6   105860 use strict;
  6         19  
  6         232  
4 6     6   28 use warnings;
  6         11  
  6         219  
5              
6 6     6   30 use vars qw($VERSION @ISA);
  6         8  
  6         501  
7             $VERSION = '0.03';
8              
9             #--------------------------------------------------------------------------
10              
11             =head1 NAME
12              
13             WWW::Scraper::ISBN::Bookstore_Driver - Search driver for The Bookstore 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 Bookstore online book catalog
22              
23             =cut
24              
25             #--------------------------------------------------------------------------
26              
27             ###########################################################################
28             # Inheritence
29              
30 6     6   29 use base qw(WWW::Scraper::ISBN::Driver);
  6         7  
  6         3102  
31              
32             ###########################################################################
33             # Modules
34              
35 6     6   9124 use WWW::Mechanize;
  6         730088  
  6         262  
36              
37             ###########################################################################
38             # Constants
39              
40 6     6   58 use constant SEARCH => 'http://www.bookstore.co.uk/TBP.Direct/PurchaseProduct/OrderProduct/CustomerSelectProduct/SearchProducts.aspx?d=bookstore&s=C&r=10000046&ui=0&bc=0&productGroupId=&keywordSearch=';
  6         9  
  6         416  
41 6     6   22 use constant PRODUCT => 'http://www.bookstore.co.uk';
  6         8  
  6         4264  
42              
43             #--------------------------------------------------------------------------
44              
45             ###########################################################################
46             # Public Interface
47              
48             =head1 METHODS
49              
50             =over 4
51              
52             =item C
53              
54             Creates a query string, then passes the appropriate form fields to the
55             Bookstore server.
56              
57             The returned page should be the correct catalog page for that ISBN. If not the
58             function returns zero and allows the next driver in the chain to have a go. If
59             a valid page is returned, the following fields are returned via the book hash:
60              
61             isbn (now returns isbn13)
62             isbn10
63             isbn13
64             ean13 (industry name)
65             author
66             title
67             book_link
68             image_link
69             thumb_link
70             description
71             pubdate
72             publisher
73             binding (if known)
74             pages (if known)
75             width (if known) (in millimetres)
76             height (if known) (in millimetres)
77             depth (if known) (in millimetres)
78              
79             The book_link and image_link refer back to the Bookstore website.
80              
81             =back
82              
83             =cut
84              
85             sub search {
86 3     3 1 17479 my $self = shift;
87 3         7 my $isbn = shift;
88 3         11 $self->found(0);
89 3         41 $self->book(undef);
90              
91             # validate and convert into EAN13 format
92 3         24 my $ean = $self->convert_to_ean13($isbn);
93 3 50       83 return $self->handler("Invalid ISBN specified [$isbn]")
94             unless($ean);
95              
96             #print STDERR "\n# isbn=[$isbn] => ean=[$ean]\n";
97 3         5 $isbn = $ean;
98              
99 3         21 my $mech = WWW::Mechanize->new();
100 3         12241 $mech->agent_alias( 'Linux Mozilla' );
101              
102             #print STDERR "\n# url=[".(SEARCH . $isbn)."]\n";
103              
104 3         176 eval { $mech->get( SEARCH . $isbn ) };
  3         13  
105 3 50 33     8803465 return $self->handler("The Bookstore website appears to be unavailable.")
      33        
106             if($@ || !$mech->success() || !$mech->content());
107              
108             # The Results page
109 3         161 my $html = $mech->content();
110             #print STDERR "\n# html=[\n$html\n]\n";
111              
112 3         131 my ($link) = $html =~ m!
\s*
113              
114             #print STDERR "\n# link=[".(PRODUCT . $link)."]\n";
115              
116 3 50       10 return $self->handler("Failed to find that book on The Bookstore website. [$isbn]")
117             unless($link);
118              
119 3         5 eval { $mech->get( PRODUCT . $link ) };
  3         17  
120 3 50 33     2831791 return $self->handler("The Bookstore website appears to be unavailable.")
      33        
121             if($@ || !$mech->success() || !$mech->content());
122              
123             # The Book page
124 3         161 $html = $mech->content();
125              
126 3 50       5305 return $self->handler("Failed to find that book on The Bookstore website. [$isbn]")
127             if($html =~ m!Sorry, we couldn't find any matches for!si);
128            
129             #print STDERR "\n# html=[\n$html\n]\n";
130              
131 3         8 my $data;
132              
133 3         4464 ($data->{isbn13}) = $html =~ m!ISBN/Cat.No\s*(\d+)[^<]*
134 3         4637 ($data->{isbn10}) = $html =~ m!ISBN-10\s*(\d+)[^<]*
135 3         4544 ($data->{title}) = $html =~ m!Title([^<]+)
136 3         4464 ($data->{author}) = $html =~ m!Author/Artist([^<]+)
137 3         4671 ($data->{publisher}) = $html =~ m!Publisher([^<]+)
138 3         4649 ($data->{pubdate}) = $html =~ m!Publication Date([^<]+)
139 3         4472 ($data->{format}) = $html =~ m!Format([^<]+)
140 3         7267 ($data->{description}) = $html =~ m!]*>\s*Summary\s*
]*>([^<]+)
141              
142 3         4526 ($data->{image}) = $html =~ m!
143 3         17 ($data->{thumb}) = $data->{image};
144              
145 3         54 ($data->{binding},$data->{height},$data->{width},$data->{depth},$data->{pages})
146             = $data->{format} =~ m!([^;]+);\s*H:(\d+);\s*W:(\d+);\s*D:(\d+);\s*(\d+)p\.!si;
147              
148             #use Data::Dumper;
149             #print STDERR "\n# " . Dumper($data);
150              
151 3 50       24 return $self->handler("Could not extract data from Bookstore result page.")
152             unless(defined $data);
153              
154             # trim top and tail
155 3 50       24 foreach (keys %$data) { next unless(defined $data->{$_});$data->{$_} =~ s/^\s+//;$data->{$_} =~ s/\s+$//; }
  45         81  
  45         134  
  45         218  
156              
157 3         44 my $bk = {
158             'ean13' => $data->{isbn13},
159             'isbn13' => $data->{isbn13},
160             'isbn10' => $data->{isbn10},
161             'isbn' => $data->{isbn13},
162             'author' => $data->{author},
163             'title' => $data->{title},
164             'book_link' => $mech->uri(),
165             'image_link' => $data->{image},
166             'thumb_link' => $data->{thumb},
167             'description' => $data->{description},
168             'pubdate' => $data->{pubdate},
169             'publisher' => $data->{publisher},
170             'binding' => $data->{binding},
171             'pages' => $data->{pages},
172             'width' => $data->{width},
173             'height' => $data->{height},
174             'depth' => $data->{depth},
175             'html' => $html
176             };
177              
178             #use Data::Dumper;
179             #print STDERR "\n# book=".Dumper($bk);
180              
181 3         226 $self->book($bk);
182 3         52 $self->found(1);
183 3         28 return $self->book;
184             }
185              
186             1;
187              
188             __END__