Add Syndetics AuthorNotes, Awards, Series
[koha.git] / C4 / External / Syndetics.pm
1 package C4::External::Syndetics;
2 # Copyright (C) 2006 LibLime
3 # <jmf at liblime dot 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 with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA  02111-1307 USA
19
20 use XML::Simple;
21 use LWP::Simple;
22 use LWP::UserAgent;
23 use HTTP::Request::Common;
24
25 use strict;
26 use warnings;
27
28 use vars qw($VERSION @ISA @EXPORT);
29
30 BEGIN {
31     require Exporter;
32     $VERSION = 0.03;
33     @ISA = qw(Exporter);
34     @EXPORT = qw(
35         &get_syndetics_index
36         &get_syndetics_summary
37         &get_syndetics_toc
38         &get_syndetics_editions
39         &get_syndetics_excerpt
40         &get_syndetics_reviews
41         &get_syndetics_anotes
42     );
43 }
44
45 =head1 NAME
46
47 C4::External::Syndetics - Functions for retrieving Syndetics content in Koha
48
49 =head1 FUNCTIONS
50
51 This module provides facilities for retrieving Syndetics.com content in Koha
52
53 =head2 get_syndetics_summary
54
55 =over 4
56
57 my $syndetics_summary= &get_syndetics_summary( $xisbn );
58
59 =back
60
61 Get Summary data from Syndetics
62
63 =cut
64
65 sub get_syndetics_index {
66     my ( $isbn ) = @_;
67
68     #normalize the ISBN
69     $isbn = _normalize_match_point ($isbn);
70
71     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
72     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
73
74     my $url = "http://syndetics.com/index.aspx?isbn=$isbn/INDEX.XML&client=$syndetics_client_code&type=xw10";
75     my $ua = LWP::UserAgent->new;
76     $ua->timeout(10);
77     $ua->env_proxy;
78     my $response = $ua->get($url);
79     unless ($response->content_type =~ /xml/) {
80         return;
81     }
82
83     my $content = $response->content;
84     warn "could not retrieve $url" unless $content;
85     my $xmlsimple = XML::Simple->new();
86     $response = $xmlsimple->XMLin(
87         $content,
88     ) unless !$content;
89
90     my $syndetics_elements;
91     for my $available_type ('SUMMARY','TOC','FICTION','AWARDS1','SERIES1','SPSUMMARY','SPREVIEW','AVSUMMARY','DBCHAPTER','LJREVIEW','PWREVIEW','SLJREVIEW','CHREVIEW','BLREVIEW','HBREVIEW','KIREVIEW','CRITICASREVIEW','ANOTES') {
92         if (exists $response->{$available_type} && $response->{$available_type} =~ /$available_type/) {
93             $syndetics_elements->{$available_type} = $available_type;
94             #warn "RESPONSE: $available_type : $response->{$available_type}";
95         }
96     }
97     return $syndetics_elements if $syndetics_elements;
98 }
99
100 sub get_syndetics_summary {
101     my ( $isbn ) = @_;
102
103     #normalize the ISBN
104     $isbn = _normalize_match_point ($isbn);
105
106     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
107     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
108
109     my $url = "http://syndetics.com/index.aspx?isbn=$isbn/SUMMARY.XML&client=$syndetics_client_code&type=xw10";
110     my $ua = LWP::UserAgent->new;
111     $ua->timeout(10);
112     $ua->env_proxy;
113     my $response = $ua->get($url);
114     unless ($response->content_type =~ /xml/) {
115         return;
116     }  
117
118     my $content = $response->content;
119
120     warn "could not retrieve $url" unless $content;
121     my $xmlsimple = XML::Simple->new();
122     $response = $xmlsimple->XMLin(
123         $content,
124         forcearray => [ qw(Fld520) ],
125     ) unless !$content;
126     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
127     my $summary;
128     $summary = \@{$response->{VarFlds}->{VarDFlds}->{Notes}->{Fld520}} if $response;
129     return $summary if $summary;
130 }
131
132 sub get_syndetics_toc {
133     my ( $isbn ) = @_;
134
135     #normalize the ISBN
136     $isbn = _normalize_match_point ($isbn);
137
138     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
139     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
140
141     my $url = "http://syndetics.com/index.aspx?isbn=$isbn/TOC.XML&client=$syndetics_client_code&type=xw10";
142     my $ua = LWP::UserAgent->new;
143     $ua->timeout(10);
144     $ua->env_proxy;
145         
146     my $response = $ua->get($url);
147     unless ($response->content_type =~ /xml/) {
148         return;
149     }  
150
151     my $content = $response->content;
152     warn "could not retrieve $url" unless $content;
153     my $xmlsimple = XML::Simple->new();
154     $response = $xmlsimple->XMLin(
155         $content,
156         forcearray => [ qw(Fld970) ],
157     ) unless !$content;
158     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
159     my $toc;
160     $toc = \@{$response->{VarFlds}->{VarDFlds}->{SSIFlds}->{Fld970}} if $response;
161     return $toc if $toc;
162 }
163
164 sub get_syndetics_excerpt {
165     my ( $isbn ) = @_;
166
167     #normalize the ISBN
168     $isbn = _normalize_match_point ($isbn);
169
170     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
171     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
172
173     my $url = "http://syndetics.com/index.aspx?isbn=$isbn/DBCHAPTER.XML&client=$syndetics_client_code&type=xw10";
174     my $ua = LWP::UserAgent->new;
175     $ua->timeout(10);
176     $ua->env_proxy;
177     my $response = $ua->get($url);
178     unless ($response->content_type =~ /xml/) {
179         return;
180     }  
181         
182     my $content = $response->content;
183     warn "could not retrieve $url" unless $content;
184     my $xmlsimple = XML::Simple->new();
185     $response = $xmlsimple->XMLin(
186         $content,
187         forcearray => [ qw(Fld520) ],
188     ) unless !$content;
189     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
190     my $excerpt;
191     $excerpt = \@{$response->{VarFlds}->{VarDFlds}->{Notes}->{Fld520}} if $response;
192     return XMLout($excerpt) if $excerpt;
193 }
194
195 sub get_syndetics_reviews {
196     my ( $isbn, $syndetics_elements ) = @_;
197
198     #normalize the ISBN
199     $isbn = _normalize_match_point ($isbn);
200
201     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
202     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
203     my @reviews;
204     my $review_sources = [
205     {title => 'Library Journal Review', file => 'LJREVIEW.XML', element => 'LJREVIEW'},
206     {title => 'Publishers Weekly Review', file => 'PWREVIEW.XML', element => 'PWREVIEW'},
207     {title => 'School Library Journal Review', file => 'SLJREVIEW.XML', element => 'SLJREVIEW'},
208     {title => 'CHOICE Review', file => 'CHREVIEW.XML', element => 'CHREVIEW'},
209     {title => 'Booklist Review', file => 'BLREVIEW.XML', element => 'BLREVIEW'},
210     {title => 'Horn Book Review', file => 'HBREVIEW.XML', element => 'HBREVIEW'},
211     {title => 'Kirkus Book Review', file => 'KIREVIEW.XML', element => 'KIREVIEW'},
212     {title => 'Criticas Review', file => 'CRITICASREVIEW.XML', element => 'CRITICASREVIEW'},
213     {title => 'Spanish Review', file => 'SPREVIEW.XML', element => 'SPREVIEW'},
214     ];
215
216     for my $source (@$review_sources) {
217         if ($syndetics_elements->{$source->{element}} and $source->{element} =~ $syndetics_elements->{$source->{element}}) {
218
219         } else {
220             #warn "Skipping $source->{element} doesn't match $syndetics_elements->{$source->{element}} \n";
221             next;
222         }
223         my $url = "http://syndetics.com/index.aspx?isbn=$isbn/$source->{file}&client=$syndetics_client_code&type=xw10";
224
225         my $ua = LWP::UserAgent->new;
226         $ua->timeout(10);
227         $ua->env_proxy;
228  
229         my $response = $ua->get($url);
230         unless ($response->content_type =~ /xml/) {
231             next;
232         }
233
234         my $content = $response->content;
235         warn "could not retrieve $url" unless $content;
236         my $xmlsimple = XML::Simple->new();
237         eval {
238         $response = $xmlsimple->XMLin(
239             $content,
240             ForceContent => 1,
241             forcearray => [ qw(Fld520) ]
242         ) unless !$content;
243         };
244             
245         for my $subfield_a (@{$response->{VarFlds}->{VarDFlds}->{Notes}->{Fld520}}) {
246             my @content;
247             # this is absurd, but sometimes this data serializes differently
248             if(ref($subfield_a->{a}->{content}) eq 'ARRAY') {
249                 for my $content (@{$subfield_a->{a}->{content}}) {
250                     push @content, {content => $content};
251                 }
252             }
253             else {
254                 push @content, {content => $subfield_a->{a}->{content}};
255             }
256             push @reviews, {title => $source->{title}, reviews => \@content};
257         }
258     }
259     return \@reviews;
260 }
261
262 sub get_syndetics_editions {
263     my ( $isbn ) = @_;
264
265     #normalize the ISBN
266     $isbn = _normalize_match_point ($isbn);
267
268     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
269     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
270
271     my $url = "http://syndetics.com/index.aspx?isbn=$isbn/FICTION.XML&client=$syndetics_client_code&type=xw10";
272     my $ua = LWP::UserAgent->new;
273     $ua->timeout(10);
274     $ua->env_proxy;
275
276     my $response = $ua->get($url);
277     unless ($response->content_type =~ /xml/) {
278         return;
279     }  
280
281     my $content = $response->content;
282
283     warn "could not retrieve $url" unless $content;
284     my $xmlsimple = XML::Simple->new();
285     $response = $xmlsimple->XMLin(
286         $content,
287         forcearray => [ qw(Fld020) ],
288     ) unless !$content;
289     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
290     my $similar_items;
291     $similar_items = \@{$response->{VarFlds}->{VarDFlds}->{NumbCode}->{Fld020}} if $response;
292     return $similar_items if $similar_items;
293 }
294
295 sub get_syndetics_anotes {
296     my ( $isbn ) = @_;
297
298     #normalize the ISBN
299     $isbn = _normalize_match_point ($isbn);
300
301     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
302     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
303
304     my $url = "http://syndetics.com/index.aspx?isbn=$isbn/ANOTES.XML&client=$syndetics_client_code&type=xw10";
305     my $ua = LWP::UserAgent->new;
306     $ua->timeout(10);
307     $ua->env_proxy;
308
309     my $response = $ua->get($url);
310     unless ($response->content_type =~ /xml/) {
311         return;
312     }
313
314     my $content = $response->content;
315
316     warn "could not retrieve $url" unless $content;
317     my $xmlsimple = XML::Simple->new();
318     $response = $xmlsimple->XMLin(
319         $content,
320         forcearray => [ qw(Fld980) ],
321         ForceContent => 1,
322     ) unless !$content;
323     my @anotes;
324     for my $fld980 (@{$response->{VarFlds}->{VarDFlds}->{SSIFlds}->{Fld980}}) {
325         # this is absurd, but sometimes this data serializes differently
326         if(ref($fld980->{a}->{content}) eq 'ARRAY') {
327             for my $content (@{$fld980->{a}->{content}}) {
328                 push @anotes, {content => $content};
329                 
330             }
331         }
332         else {
333             push @anotes, {content => $fld980->{a}->{content}};
334         }
335     }
336     return \@anotes;
337 }
338
339 sub _normalize_match_point {
340     my $match_point = shift;
341     (my $normalized_match_point) = $match_point =~ /([\d-]*[X]*)/;
342     $normalized_match_point =~ s/-//g;
343
344     return $normalized_match_point;
345 }
346
347 1;
348 __END__
349
350 =head1 NOTES
351
352 =head1 AUTHOR
353
354 Joshua Ferraro <jmf@liblime.com>
355
356 =cut