BakerTaylor.pm - Initial implementation of B+T jacket cover and bookstore links.
[koha.git] / C4 / External / BakerTaylor.pm
1 package C4::External::BakerTaylor;
2 # Copyright (C) 2008 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 use C4::Context;
25 use C4::Debug;
26
27 use strict;
28 use warnings;
29
30 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
31 use vars qw($user $pass $agent $image_url $link_url);
32
33 BEGIN {
34         require Exporter;
35         $VERSION = 0.01;
36         @ISA = qw(Exporter);
37         @EXPORT_OK = qw(&availability &content_cafe &image_url &link_url &http_jacket_link);
38         %EXPORT_TAGS = (all=>\@EXPORT_OK);
39 }
40 INIT {
41         &initialize;
42 }
43
44 sub initialize {
45         $user     = (@_ ? shift : C4::Context->preference('BakerTaylorUsername')    ) || ''; # LL17984
46         $pass     = (@_ ? shift : C4::Context->preference('BakerTaylorPassword')    ) || ''; # CC82349
47         $link_url = (@_ ? shift : C4::Context->preference('BakerTaylorBookstoreURL'));
48         # https://ocls.mylibrarybookstore.com/MLB/actions/searchHandler.do?nextPage=bookDetails&parentNum=10923&key=
49         $image_url = "http://contentcafe2.btol.com/buynow/Jacket.aspx?UserID=$user&Password=$pass&Product=";
50         $agent = "Koha/$VERSION [en] (Linux)";
51                         #"Mozilla/4.76 [en] (Win98; U)",        #  if for some reason you want to go stealth, you might prefer this
52 }
53
54 sub image_url ($) {
55         ($user and $pass) or return undef;
56         return $image_url . (@_ ? shift : '');
57 }
58 sub link_url ($) {
59         $link_url or return undef;
60         return $link_url  . (@_ ? shift : '');
61 }
62 sub http_jacket_link ($) {
63         my $isbn = shift or return undef;
64         my $image = availability($isbn);
65         my $alt = "Buy this book";
66         $image and $image = qq(<img class="btjacket" alt="Buy this book" src="$image" />);
67         my $link = &link_url($isbn);
68         unless ($link) {return $image || '';}
69         return sprintf qq(<a class="btlink" href="%s">%s</a>),$link,($image||$alt);
70 }
71
72 sub availability ($) {
73         my $isbn = shift or return undef;
74         ($user and $pass) or return undef;
75         $isbn =~ s/(p|-)//g;    # sanitize
76         my $url = "http://contentcafe2.btol.com/ContentCafe/InventoryAvailability.asmx/CheckInventory?UserID=$user&Password=$pass&Value=$isbn";
77         $debug and warn __PACKAGE__ . " request:\n$url\n";
78         my $content = get($url);
79         $debug and print STDERR $content, "\n";
80         warn "could not retrieve $url" unless $content;
81         my $xmlsimple = XML::Simple->new();
82         my $result = $xmlsimple->XMLin($content);
83         if ($result->{Error}) {
84                 warn "Error returned to " . __PACKAGE__ . " : " . $result->{Error};
85         }
86         my $avail = $result->{Availability};
87         return ($avail and $avail !~ /^false$/i) ? &image_url($isbn) : 0;
88 }
89
90 sub content_cafe ($) {
91         my $isbn = shift or return undef;
92         my $ua = LWP::UserAgent->new(
93                 agent => $agent,
94                 keep_alive => 1,
95                 env_proxy  => 1,
96         );
97         my $available = 1;
98         my $uri = "http://contentcafe2.btol.com/ContentCafe/InventoryAvailability.asmx/CheckInventory?UserID=$user&Password=$pass&Value=$isbn";
99         my $req = HTTP::Request->new(GET => $uri);
100         $req->header (
101                 'Accept' => 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*',
102                 'Accept-Charset' => 'iso-8859-1,*,utf-8',
103                 'Accept-Language' => 'en-US' );
104         my $res = $ua->request($req);
105         my $content = $res->content();
106         if ($content =~ /This book is temporarily unavailable/) {
107                 return undef;
108         }
109         return $available;
110 }
111
112 1;
113
114 __END__
115
116 =head1 NAME
117
118 C4::External::BakerTaylor - Functions for retrieving content from Baker and Taylor, inventory availability and "Content Cafe".
119 The settings for this module are controlled by System Preferences:
120
121 These can be overridden for testing purposes using the initialize function.
122
123 =head1 FUNCTIONS
124
125 =head1 availability($isbn);
126
127 =head2 $isbn is a isbn string
128
129 =head1 NOTES
130
131 A request with failed authentication might see this back from Baker + Taylor: 
132
133 <?xml version="1.0" encoding="utf-8"?>
134 <InventoryAvailability xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" DateTime="2008-03-07T22:01:25.6520429-05:00" xmlns="http://ContentCafe2.btol.com">
135   <Key Type="Undefined">string</Key>
136   <Availability>false</Availability>
137   <Error>Invalid UserID</Error>
138 </InventoryAvailability>
139
140 Such response will trigger a warning for each request (potentially many).  Point being, do not leave this module configured with incorrect username and password in production.
141
142 =head1 SEE ALSO
143
144 C4::Amazon
145 LWP::UserAgent
146
147 =head1 AUTHOR
148
149 Joe Atzberger
150 atz AT liblime DOT com
151
152 =cut