File: | C4/XISBN.pm |
Coverage: | 23.4% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package C4::XISBN; | |||||
2 | # Copyright (C) 2007 LibLime | |||||
3 | # Joshua Ferraro <jmf@liblime.com> | |||||
4 | # | |||||
5 | # This file is part of Koha. | |||||
6 | # | |||||
7 | # Koha is free software; you can redistribute it and/or modify it under the | |||||
8 | # terms of the GNU General Public License as published by the Free Software | |||||
9 | # Foundation; either version 2 of the License, or (at your option) any later | |||||
10 | # version. | |||||
11 | # | |||||
12 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
13 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
14 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
15 | # | |||||
16 | # You should have received a copy of the GNU General Public License along | |||||
17 | # with Koha; if not, write to the Free Software Foundation, Inc., | |||||
18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||||
19 | ||||||
20 | 2 2 2 | 2594 5 42 | use XML::Simple; | |||
21 | #use LWP::Simple; | |||||
22 | 2 2 2 | 174 3 1272 | use C4::Biblio; | |||
23 | 2 2 2 | 9 2 869 | use C4::Koha; | |||
24 | 2 2 2 | 460 20 215 | use C4::External::Syndetics qw(get_syndetics_editions); | |||
25 | 2 2 2 | 24 16 49 | use LWP::UserAgent; | |||
26 | 2 2 2 | 38 15 140 | use HTTP::Request::Common; | |||
27 | ||||||
28 | 2 2 2 | 20 13 133 | use strict; | |||
29 | #use warnings; FIXME - Bug 2505 | |||||
30 | 2 2 2 | 19 13 343 | use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); | |||
31 | ||||||
32 | BEGIN { | |||||
33 | 2 | 19 | require Exporter; | |||
34 | 2 | 12 | $VERSION = 3.01; | |||
35 | 2 | 44 | @ISA = qw(Exporter); | |||
36 | 2 | 2194 | @EXPORT_OK = qw( | |||
37 | &get_xisbns | |||||
38 | &get_biblionumber_from_isbn | |||||
39 | ); | |||||
40 | } | |||||
41 | ||||||
42 | sub get_biblionumber_from_isbn { | |||||
43 | 0 | my $isbn = shift; | ||||
44 | 0 | $isbn.='%'; | ||||
45 | 0 | my @biblionumbers; | ||||
46 | 0 | my $dbh=C4::Context->dbh; | ||||
47 | 0 | my $query = "SELECT biblionumber FROM biblioitems WHERE isbn LIKE ? LIMIT 10"; | ||||
48 | 0 | my $sth = $dbh->prepare($query); | ||||
49 | 0 | $sth->execute($isbn); | ||||
50 | 0 | return $sth->fetchall_arrayref({}); | ||||
51 | } | |||||
52 - 60 | =head1 NAME C4::XISBN - Functions for retrieving XISBN content in Koha =head1 FUNCTIONS This module provides facilities for retrieving ThingISBN and XISBN content in Koha =cut | |||||
61 | ||||||
62 | sub _get_biblio_from_xisbn { | |||||
63 | 0 | my $xisbn = shift; | ||||
64 | 0 | $xisbn.='%'; | ||||
65 | 0 | my $dbh = C4::Context->dbh; | ||||
66 | 0 | my $query = "SELECT biblionumber FROM biblioitems WHERE isbn LIKE ?"; | ||||
67 | 0 | my $sth = $dbh->prepare($query); | ||||
68 | 0 | $sth->execute($xisbn); | ||||
69 | 0 | my $xbib_data = $sth->fetchrow_hashref(); | ||||
70 | 0 | my $xbiblio; | ||||
71 | 0 | if ($xbib_data->{biblionumber}) { | ||||
72 | 0 | $xbiblio = GetBiblioData($xbib_data->{biblionumber}); | ||||
73 | 0 | $xbiblio->{normalized_isbn} = GetNormalizedISBN($xbiblio->{isbn}); | ||||
74 | } | |||||
75 | 0 | return ($xbiblio); | ||||
76 | } | |||||
77 | ||||||
78 - 82 | =head1 get_xisbns($isbn); =head2 $isbn is an ISBN string =cut | |||||
83 | ||||||
84 | sub get_xisbns { | |||||
85 | 0 | my ( $isbn ) = @_; | ||||
86 | 0 | my ($response,$thing_response,$xisbn_response,$syndetics_response); | ||||
87 | # THINGISBN | |||||
88 | 0 | if ( C4::Context->preference('ThingISBN') ) { | ||||
89 | 0 | my $url = "http://www.librarything.com/api/thingISBN/".$isbn; | ||||
90 | 0 | $thing_response = _get_url($url,'thingisbn'); | ||||
91 | } | |||||
92 | ||||||
93 | 0 | if ( C4::Context->preference("SyndeticsEnabled") && C4::Context->preference("SyndeticsEditions") ) { | ||||
94 | 0 | my $syndetics_preresponse = &get_syndetics_editions($isbn); | ||||
95 | 0 | my @syndetics_response; | ||||
96 | 0 | for my $response (@$syndetics_preresponse) { | ||||
97 | 0 | push @syndetics_response, {content => $response->{a}}; | ||||
98 | } | |||||
99 | 0 | $syndetics_response = {isbn => \@syndetics_response}; | ||||
100 | } | |||||
101 | ||||||
102 | # XISBN | |||||
103 | 0 | if ( C4::Context->preference('XISBN') ) { | ||||
104 | 0 | my $affiliate_id=C4::Context->preference('OCLCAffiliateID'); | ||||
105 | 0 | my $limit = C4::Context->preference('XISBNDailyLimit') || 999; | ||||
106 | 0 | my $reached_limit = _service_throttle('xisbn',$limit); | ||||
107 | 0 | my $url = "http://xisbn.worldcat.org/webservices/xid/isbn/".$isbn."?method=getEditions&format=xml&fl=form,year,lang,ed"; | ||||
108 | 0 | $url.="&ai=".$affiliate_id if $affiliate_id; | ||||
109 | 0 | unless ($reached_limit) { | ||||
110 | 0 | $xisbn_response = _get_url($url,'xisbn'); | ||||
111 | } | |||||
112 | } | |||||
113 | ||||||
114 | 0 0 0 0 | $response->{isbn} = [ @{ $xisbn_response->{isbn} or [] }, @{ $syndetics_response->{isbn} or [] }, @{ $thing_response->{isbn} or [] } ]; | ||||
115 | 0 | my @xisbns; | ||||
116 | 0 | my $unique_xisbns; # a hashref | ||||
117 | ||||||
118 | # loop through each ISBN and scope to the local collection | |||||
119 | 0 0 | for my $response_data( @{ $response->{ isbn } } ) { | ||||
120 | 0 | next if $response_data->{'content'} eq $isbn; | ||||
121 | 0 | next if $isbn eq $response_data; | ||||
122 | 0 | next if $unique_xisbns->{ $response_data->{content} }; | ||||
123 | 0 | $unique_xisbns->{ $response_data->{content} }++; | ||||
124 | 0 | my $xbiblio= _get_biblio_from_xisbn($response_data->{content}); | ||||
125 | 0 | push @xisbns, $xbiblio if $xbiblio; | ||||
126 | } | |||||
127 | 0 | return \@xisbns; | ||||
128 | } | |||||
129 | ||||||
130 | sub _get_url { | |||||
131 | 0 | my ($url,$service_type) = @_; | ||||
132 | 0 | my $ua = LWP::UserAgent->new( | ||||
133 | timeout => 2 | |||||
134 | ); | |||||
135 | ||||||
136 | 0 | my $response = $ua->get($url); | ||||
137 | 0 | if ($response->is_success) { | ||||
138 | 0 | warn "WARNING could not retrieve $service_type $url" unless $response; | ||||
139 | 0 | if ($response) { | ||||
140 | 0 | my $xmlsimple = XML::Simple->new(); | ||||
141 | 0 | my $content = $xmlsimple->XMLin( | ||||
142 | $response->content, | |||||
143 | ForceArray => [ qw(isbn) ], | |||||
144 | ForceContent => 1, | |||||
145 | ); | |||||
146 | 0 | return $content; | ||||
147 | } | |||||
148 | } else { | |||||
149 | 0 | warn "WARNING: URL Request Failed " . $response->status_line . "\n"; | ||||
150 | } | |||||
151 | ||||||
152 | } | |||||
153 | ||||||
154 | ||||||
155 | # Throttle services to the specified amount | |||||
156 | sub _service_throttle { | |||||
157 | 0 | my ($service_type,$daily_limit) = @_; | ||||
158 | 0 | my $dbh = C4::Context->dbh; | ||||
159 | 0 | my $sth = $dbh->prepare("SELECT service_count FROM services_throttle WHERE service_type=?"); | ||||
160 | 0 | $sth->execute($service_type); | ||||
161 | 0 | my $count = 1; | ||||
162 | ||||||
163 | 0 | while (my $counter = $sth->fetchrow_hashref()) { | ||||
164 | 0 | $count = $counter->{service_count} if $counter->{service_count}; | ||||
165 | } | |||||
166 | ||||||
167 | # we're over the limit | |||||
168 | 0 | return 1 if $count >= $daily_limit; | ||||
169 | ||||||
170 | # not over the limit | |||||
171 | 0 | $count++; | ||||
172 | 0 | $sth = $dbh->do("UPDATE services_throttle SET service_count=$count WHERE service_type='xisbn'"); | ||||
173 | 0 | return undef; | ||||
174 | } | |||||
175 | ||||||
176 | 1; |