File Coverage

blib/lib/WWW/Scraper/ISBN/LOC_Driver.pm
Criterion Covered Total %
statement 73 84 86.9
branch 8 18 44.4
condition 4 9 44.4
subroutine 6 6 100.0
pod 1 1 100.0
total 92 118 77.9


line stmt bran cond sub pod time code
1             package WWW::Scraper::ISBN::LOC_Driver;
2              
3 6     6   94859 use strict;
  6         12  
  6         226  
4 6     6   27 use warnings;
  6         9  
  6         360  
5              
6             our $VERSION = '0.26';
7              
8             #--------------------------------------------------------------------------
9              
10             ###########################################################################
11             # Inheritence
12              
13             our @ISA = qw(WWW::Scraper::ISBN::Driver);
14              
15             ###########################################################################
16             # Modules
17              
18 6     6   3168 use HTTP::Request::Common;
  6         128654  
  6         475  
19 6     6   7934 use LWP::UserAgent;
  6         112580  
  6         184  
20 6     6   2787 use WWW::Scraper::ISBN::Driver;
  6         4181  
  6         5256  
21              
22             ###########################################################################
23             # Public Interface
24              
25             sub search {
26 1     1 1 169 my $self = shift;
27 1         1 my $isbn = shift;
28 1         2 my %data;
29              
30 1         5 $self->found(0);
31 1         18 $self->book(undef);
32              
33             # first, initialize the session:
34 1         8 my $post_url = "http://www.loc.gov/cgi-bin/zgate?ACTION=INIT&FORM_HOST_PORT=/prod/www/data/z3950/locils.html,z3950.loc.gov,7090";
35 1         4 my $ua = new LWP::UserAgent;
36 1         3209 my $res = $ua->request(GET $post_url);
37 1         1785121 my $doc = '';
38              
39             # get page
40             # removes blank lines, DOS line feeds, and leading spaces.
41 1         8 $doc = join "\n", grep { /\S/ } split /\n/, $res->as_string();
  142         473  
42 1         14 $doc =~ s/\r//g;
43 1         4 $doc =~ s/^\s+//g;
44              
45 1         3 my $sessionID = '';
46              
47 1 50       24 unless ( ($sessionID) = ($doc =~ //i) ) {
48 0 0       0 print "Error starting LOC Query session.\n" if $self->verbosity;
49 0         0 $self->error("Cannot start LOC query session.\n");
50 0         0 $self->found(0);
51 0         0 return 0;
52             }
53              
54 1         3 $post_url = "http://www.loc.gov/cgi-bin/zgate";
55 1         13 $res = $ua->request(
56             POST $post_url,
57             Referer => $post_url,
58             Content => [
59             TERM_1 => $isbn,
60             USE_1 => '7',
61             ESNAME => 'F',
62             ACTION => 'SEARCH',
63             DBNAME => 'VOYAGER',
64             MAXRECORDS => '20',
65             RECSYNTAX => '1.2.840.10003.5.10',
66             STRUCT_1 => '1',
67             STRUCT_2 => '1',
68             STRUCT_3 => '1',
69             SESSION_ID => $sessionID
70             ]
71             );
72              
73 1         333574 $doc = '';
74              
75             # get page
76             # removes blank lines, DOS line feeds, and leading spaces.
77 1         7 $doc = join "\n", grep { /\S/ } split /\n/, $res->as_string();
  37         366  
78 1         9 $doc =~ s/\r//g;
79 1         4 $doc =~ s/^\s+//g;
80              
81 1 50       34 if ( (my $book_data) = ($doc =~ /.*
(.*)<\/PRE>.*/is) ) { 
82 1 50       20 print $book_data if ($self->verbosity > 1);
83              
84 1         19 my @author_lines;
85             my $other_authors;
86              
87             # get author field
88 1 50 33     12 while ($book_data =~ s/uthor(s)?:\s+(\D+?)(?:, [0-9-.]*|\.)$/if (($1) && ($1 eq "s")) { "uthors:"; } else { "" }/me) {
  1         11  
  0         0  
  1         8  
89 1         4 my $temp = $2;
90 1         4 $temp =~ s/ ([A-Z])$/ $1./; # trailing middle initial
91 1         6 push @author_lines, $temp;
92             }
93              
94 1         3 @author_lines = sort @author_lines;
95 1         3 foreach my $line(@author_lines) {
96 1         12 $line =~ s/(\w+), (.*)/$2 $1/;
97             }
98 1         5 $data{author} = join ", ", @author_lines;
99              
100             # get other fields
101 1         9 ($data{title}) = $book_data =~ /Title:\s+((.*)\n(\s+(.*)\n)*)/;
102 1         8 ($data{edition}) = $book_data =~ /Edition:\s+(.*)\n/;
103 1         6 ($data{volume}) = $book_data =~ /Volume:\s+(.*)\n/;
104 1         6 ($data{dewey}) = $book_data =~ /Dewey No.:\s+(.*)\n/;
105 1         11 ($data{publisher},$data{pubdate}) = $book_data =~ /Published:\s+[^:]+:\s+(.*), c(\d+)\.\n/;
106 1         10 ($data{pages},$data{height}) = $book_data =~ /Description:\s+\w+,\s+(\d+)\s+:[^;]+;\s+(\d+)\s*cm.\n/;
107 1         38 ($data{isbn10},$data{binding}) = $book_data =~ /ISBN:\s+(\d+)\s+\(([^\)]+)\)\n/;
108              
109             # trim and clean data
110 1         7 for my $key (keys %data) {
111 11 100       22 next unless($data{$key});
112 10         18 $data{$key} =~ s/\n//g;
113 10         28 $data{$key} =~ s/ +/ /g;
114             }
115              
116             # reformat and default fields
117 1         9 $data{title} =~ s/(.*) \/(.*)/$1/;
118 1         4 $data{height} *= 10; # cm => mm
119 1   50     5 $data{author} ||= '';
120 1   50     5 $data{edition} ||= 'n/a';
121 1   50     11 $data{volume} ||= 'n/a';
122              
123             # print data if in verbose mode
124 1 50       6 if($self->verbosity > 1) {
125 0         0 for my $key (keys %data) {
126 0         0 printf "%-8s %s\n", "$key:", $data{$key};
127             }
128             }
129              
130             # store book data
131 1         18 my $bk = {
132             'isbn' => $isbn,
133             'isbn13' => $isbn,
134             'ean13' => $isbn
135             };
136              
137 1 50       6 $bk->{isbn10} = $data{isbn10} if(length($data{isbn10}) == 10);
138 1         17 $bk->{$_} = $data{$_} for(qw(author title edition volume dewey publisher pubdate pages height binding));
139              
140 1         7 $self->book($bk);
141 1         14 $self->found(1);
142 1         10 return $self->book;
143              
144             } else {
145 0 0         print "Error extracting data from LOC result page.\n" if $self->verbosity;
146 0           $self->error("Could not extract data from LOC result page.\n");
147 0           $self->found(0);
148 0           return 0;
149             }
150             }
151              
152             1;
153              
154             __END__