Syndetics: handle variations in reviews XML output
[koha_ffzg] / 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( $isbn );
58
59 =back
60
61 Get Summary data from Syndetics
62
63 =cut
64
65 sub get_syndetics_index {
66     my ( $isbn,$upc,$oclc ) = @_;
67
68     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
69     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
70
71     my $url = "http://www.syndetics.com/index.aspx?isbn=$isbn/INDEX.XML&client=$syndetics_client_code&type=xw10&upc=$upc&oclc=$oclc";
72
73     my $ua = LWP::UserAgent->new;
74     $ua->timeout(10);
75     $ua->env_proxy;
76     my $response = $ua->get($url);
77     unless ($response->content_type =~ /xml/) {
78         return;
79     }
80
81     my $content = $response->content;
82     warn "could not retrieve $url" unless $content;
83     my $xmlsimple = XML::Simple->new();
84     $response = $xmlsimple->XMLin(
85         $content,
86     ) unless !$content;
87
88     my $syndetics_elements;
89     for my $available_type ('SUMMARY','TOC','FICTION','AWARDS1','SERIES1','SPSUMMARY','SPREVIEW','AVSUMMARY','DBCHAPTER','LJREVIEW','PWREVIEW','SLJREVIEW','CHREVIEW','BLREVIEW','HBREVIEW','KIREVIEW','CRITICASREVIEW','ANOTES') {
90         if (exists $response->{$available_type} && $response->{$available_type} =~ /$available_type/) {
91             $syndetics_elements->{$available_type} = $available_type;
92             #warn "RESPONSE: $available_type : $response->{$available_type}";
93         }
94     }
95     return $syndetics_elements if $syndetics_elements;
96 }
97
98 sub get_syndetics_summary {
99     my ( $isbn,$upc,$oclc ) = @_;
100
101     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
102     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
103
104     my $url = "http://www.syndetics.com/index.aspx?isbn=$isbn/SUMMARY.XML&client=$syndetics_client_code&type=xw10&upc=$upc&oclc=$oclc";
105     my $ua = LWP::UserAgent->new;
106     $ua->timeout(10);
107     $ua->env_proxy;
108     my $response = $ua->get($url);
109     unless ($response->content_type =~ /xml/) {
110         return;
111     }  
112
113     my $content = $response->content;
114
115     warn "could not retrieve $url" unless $content;
116     my $xmlsimple = XML::Simple->new();
117     $response = $xmlsimple->XMLin(
118         $content,
119         forcearray => [ qw(Fld520) ],
120     ) unless !$content;
121     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
122     my $summary;
123     $summary = \@{$response->{VarFlds}->{VarDFlds}->{Notes}->{Fld520}} if $response;
124     return $summary if $summary;
125 }
126
127 sub get_syndetics_toc {
128     my ( $isbn,$upc,$oclc ) = @_;
129
130     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
131     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
132
133     my $url = "http://www.syndetics.com/index.aspx?isbn=$isbn/TOC.XML&client=$syndetics_client_code&type=xw10&upc=$upc&oclc=$oclc";
134     my $ua = LWP::UserAgent->new;
135     $ua->timeout(10);
136     $ua->env_proxy;
137         
138     my $response = $ua->get($url);
139     unless ($response->content_type =~ /xml/) {
140         return;
141     }  
142
143     my $content = $response->content;
144     warn "could not retrieve $url" unless $content;
145     my $xmlsimple = XML::Simple->new();
146     $response = $xmlsimple->XMLin(
147         $content,
148         forcearray => [ qw(Fld970) ],
149     ) unless !$content;
150     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
151     my $toc;
152     $toc = \@{$response->{VarFlds}->{VarDFlds}->{SSIFlds}->{Fld970}} if $response;
153     return $toc if $toc;
154 }
155
156 sub get_syndetics_excerpt {
157     my ( $isbn,$upc,$oclc ) = @_;
158
159     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
160     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
161
162     my $url = "http://www.syndetics.com/index.aspx?isbn=$isbn/DBCHAPTER.XML&client=$syndetics_client_code&type=xw10&upc=$upc&oclc=$oclc";
163     my $ua = LWP::UserAgent->new;
164     $ua->timeout(10);
165     $ua->env_proxy;
166     my $response = $ua->get($url);
167     unless ($response->content_type =~ /xml/) {
168         return;
169     }  
170         
171     my $content = $response->content;
172     warn "could not retrieve $url" unless $content;
173     my $xmlsimple = XML::Simple->new();
174     $response = $xmlsimple->XMLin(
175         $content,
176         forcearray => [ qw(Fld520) ],
177     ) unless !$content;
178     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
179     my $excerpt;
180     $excerpt = \@{$response->{VarFlds}->{VarDFlds}->{Notes}->{Fld520}} if $response;
181     return XMLout($excerpt, NoEscape => 1) if $excerpt;
182 }
183
184 sub get_syndetics_reviews {
185     my ( $isbn,$upc,$oclc,$syndetics_elements ) = @_;
186
187     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
188     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
189     my @reviews;
190     my $review_sources = [
191     {title => 'Library Journal Review', file => 'LJREVIEW.XML', element => 'LJREVIEW'},
192     {title => 'Publishers Weekly Review', file => 'PWREVIEW.XML', element => 'PWREVIEW'},
193     {title => 'School Library Journal Review', file => 'SLJREVIEW.XML', element => 'SLJREVIEW'},
194     {title => 'CHOICE Review', file => 'CHREVIEW.XML', element => 'CHREVIEW'},
195     {title => 'Booklist Review', file => 'BLREVIEW.XML', element => 'BLREVIEW'},
196     {title => 'Horn Book Review', file => 'HBREVIEW.XML', element => 'HBREVIEW'},
197     {title => 'Kirkus Book Review', file => 'KIREVIEW.XML', element => 'KIREVIEW'},
198     {title => 'Criticas Review', file => 'CRITICASREVIEW.XML', element => 'CRITICASREVIEW'},
199     {title => 'Spanish Review', file => 'SPREVIEW.XML', element => 'SPREVIEW'},
200     ];
201
202     for my $source (@$review_sources) {
203         if ($syndetics_elements->{$source->{element}} and $source->{element} =~ $syndetics_elements->{$source->{element}}) {
204
205         } else {
206             #warn "Skipping $source->{element} doesn't match $syndetics_elements->{$source->{element}} \n";
207             next;
208         }
209         my $url = "http://www.syndetics.com/index.aspx?isbn=$isbn/$source->{file}&client=$syndetics_client_code&type=xw10&upc=$upc&oclc=$oclc";
210
211         my $ua = LWP::UserAgent->new;
212         $ua->timeout(10);
213         $ua->env_proxy;
214  
215         my $response = $ua->get($url);
216         unless ($response->content_type =~ /xml/) {
217             next;
218         }
219
220         my $content = $response->content;
221         warn "could not retrieve $url" unless $content;
222         my $xmlsimple = XML::Simple->new();
223         eval {
224         $response = $xmlsimple->XMLin(
225             $content,
226             ForceContent => 1,
227             forcearray => [ qw(Fld520) ]
228         ) unless !$content;
229         };
230             
231         for my $subfield_a (@{$response->{VarFlds}->{VarDFlds}->{Notes}->{Fld520}}) {
232             my @content;
233             # this is absurd, but sometimes this data serializes differently
234             if (exists $subfield_a->{content}) {
235                 if (ref($subfield_a->{content} eq 'ARRAY')) {
236                     for my $content (@{$subfield_a->{content}}) {
237                         push @content, {content => $content};
238                     }
239                 } else {
240                     push @content, {content => $subfield_a->{content}};
241                 }
242             }
243             elsif(ref($subfield_a->{a}->{content}) eq 'ARRAY') {
244                 for my $content (@{$subfield_a->{a}->{content}}) {
245                     push @content, {content => $content};
246                 }
247             }
248             else {
249                 push @content, {content => $subfield_a->{a}->{content}};
250             }
251             push @reviews, {title => $source->{title}, reviews => \@content};
252         }
253     }
254     return \@reviews;
255 }
256
257 sub get_syndetics_editions {
258     my ( $isbn,$upc,$oclc ) = @_;
259
260     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
261     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
262
263     my $url = "http://www.syndetics.com/index.aspx?isbn=$isbn/FICTION.XML&client=$syndetics_client_code&type=xw10&upc=$upc&oclc=$oclc";
264     my $ua = LWP::UserAgent->new;
265     $ua->timeout(10);
266     $ua->env_proxy;
267
268     my $response = $ua->get($url);
269     unless ($response->content_type =~ /xml/) {
270         return;
271     }  
272
273     my $content = $response->content;
274
275     warn "could not retrieve $url" unless $content;
276     my $xmlsimple = XML::Simple->new();
277     $response = $xmlsimple->XMLin(
278         $content,
279         forcearray => [ qw(Fld020) ],
280     ) unless !$content;
281     # manipulate response USMARC VarFlds VarDFlds Notes Fld520 a
282     my $similar_items;
283     $similar_items = \@{$response->{VarFlds}->{VarDFlds}->{NumbCode}->{Fld020}} if $response;
284     return $similar_items if $similar_items;
285 }
286
287 sub get_syndetics_anotes {
288     my ( $isbn,$upc,$oclc) = @_;
289
290     # grab the AWSAccessKeyId: mine is '0V5RRRRJZ3HR2RQFNHR2'
291     my $syndetics_client_code = C4::Context->preference('SyndeticsClientCode');
292
293     my $url = "http://www.syndetics.com/index.aspx?isbn=$isbn/ANOTES.XML&client=$syndetics_client_code&type=xw10&upc=$upc&oclc=$oclc";
294     my $ua = LWP::UserAgent->new;
295     $ua->timeout(10);
296     $ua->env_proxy;
297
298     my $response = $ua->get($url);
299     unless ($response->content_type =~ /xml/) {
300         return;
301     }
302
303     my $content = $response->content;
304
305     warn "could not retrieve $url" unless $content;
306     my $xmlsimple = XML::Simple->new();
307     $response = $xmlsimple->XMLin(
308         $content,
309         forcearray => [ qw(Fld980) ],
310         ForceContent => 1,
311     ) unless !$content;
312     my @anotes;
313     for my $fld980 (@{$response->{VarFlds}->{VarDFlds}->{SSIFlds}->{Fld980}}) {
314         # this is absurd, but sometimes this data serializes differently
315         if(ref($fld980->{a}->{content}) eq 'ARRAY') {
316             for my $content (@{$fld980->{a}->{content}}) {
317                 push @anotes, {content => $content};
318                 
319             }
320         }
321         else {
322             push @anotes, {content => $fld980->{a}->{content}};
323         }
324     }
325     return \@anotes;
326 }
327
328 1;
329 __END__
330
331 =head1 NOTES
332
333 =head1 AUTHOR
334
335 Joshua Ferraro <jmf@liblime.com>
336
337 =cut