2d0bdc80fd
Show any relevant results from the OverDrive ebook/audiobook service on the OPAC search. This is done by showing a link with "Found xx results in the library's OverDrive collection" at the top of search results and linking to a page that shows the full results. This requires an OverDrive developer account, and is enabled by setting the OverDriveClientKey and OverDriveClientSecret system preferences. In addition, this patch adds the OverDriveLibraryID system preference. Signed-off-by: Srdjan <srdjan@catalyst.net.nz> Signed-off-by: Henry Bankhead <hbankhead@losgatosca.gov> Signed-off-by: Chris Cormack <chris@bigballofwax.co.nz> Signed-off-by: Owen Leonard <oleonard@myacpl.org> Signed-off-by: Katrin Fischer <Katrin.Fischer.83@web.de> Signed-off-by: Galen Charlton <gmc@esilibrary.com>
141 lines
3.4 KiB
Perl
141 lines
3.4 KiB
Perl
package C4::External::OverDrive;
|
|
|
|
# Copyright (c) 2013 ByWater
|
|
#
|
|
# This file is part of Koha.
|
|
#
|
|
# Koha is free software; you can redistribute it and/or modify it under the
|
|
# terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or ( at your option ) any later
|
|
# version.
|
|
#
|
|
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with Koha; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use JSON;
|
|
use Koha::Cache;
|
|
use HTTP::Request;
|
|
use HTTP::Request::Common;
|
|
use LWP::Authen::Basic;
|
|
use LWP::UserAgent;
|
|
|
|
BEGIN {
|
|
require Exporter;
|
|
our $VERSION = 3.07.00.049;
|
|
our @ISA = qw( Exporter ) ;
|
|
our @EXPORT = qw(
|
|
IsOverDriveEnabled
|
|
GetOverDriveToken
|
|
);
|
|
}
|
|
|
|
sub _request {
|
|
my ( $request ) = @_;
|
|
my $ua = LWP::UserAgent->new( "Koha " . C4::Context->KOHAVERSION );
|
|
|
|
my $response;
|
|
eval {
|
|
$response = $ua->request( $request ) ;
|
|
};
|
|
if ( $@ ) {
|
|
warn "OverDrive request failed: $@";
|
|
return;
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
=head1 NAME
|
|
|
|
C4::External::OverDrive - Retrieve OverDrive content availability information
|
|
|
|
=head2 FUNCTIONS
|
|
|
|
This module provides content search for OverDrive,
|
|
|
|
=over
|
|
|
|
=item IsOverDriveEnabled
|
|
|
|
Returns 1 if all of the necessary system preferences for OverDrive are set.
|
|
|
|
=back
|
|
|
|
=cut
|
|
|
|
sub IsOverDriveEnabled {
|
|
return (
|
|
C4::Context->preference( 'OverDriveClientKey' ) &&
|
|
C4::Context->preference( 'OverDriveClientSecret' )
|
|
);
|
|
}
|
|
|
|
=item GetOverDriveToken
|
|
|
|
Fetches an OAuth2 auth token for the OverDrive API, reusing an existing token in
|
|
Memcache if possible.
|
|
|
|
Returns the token ( as "bearer ..." ) or undef on failure.
|
|
|
|
=back
|
|
|
|
=cut
|
|
|
|
sub GetOverDriveToken {
|
|
my $key = C4::Context->preference( 'OverDriveClientKey' );
|
|
my $secret = C4::Context->preference( 'OverDriveClientSecret' );
|
|
|
|
return unless ( $key && $secret ) ;
|
|
|
|
my $cache;
|
|
|
|
eval { $cache = Koha::Cache->new() };
|
|
|
|
my $token;
|
|
$cache and $token = $cache->get_from_cache( "overdrive_token" ) and return $token;
|
|
|
|
my $request = HTTP::Request::Common::POST( 'https://oauth.overdrive.com/token', [
|
|
grant_type => 'client_credentials'
|
|
] ) ;
|
|
$request->header( Authorization => LWP::Authen::Basic->auth_header( $key, $secret ) );
|
|
|
|
my $response = _request( $request ) or return;
|
|
if ( $response->header('Content-Type') !~ m!application/json! ) {
|
|
warn "Could not connect to OverDrive: " . $response->message;
|
|
return;
|
|
}
|
|
my $contents = from_json( $response->decoded_content );
|
|
|
|
if ( !$response->is_success ) {
|
|
warn "Could not log into OverDrive: " . ( $contents ? $contents->{'error_description'} : $response->decoded_content );
|
|
return;
|
|
}
|
|
|
|
$token = $contents->{'token_type'} . ' ' . $contents->{'access_token'};
|
|
|
|
# Fudge factor to prevent spurious failures
|
|
$cache->set_in_cache( 'overdrive_token', $token, $contents->{'expires_in'} - 5 );
|
|
|
|
return $token;
|
|
}
|
|
|
|
1;
|
|
__END__
|
|
|
|
=head1 NOTES
|
|
|
|
=cut
|
|
|
|
=head1 AUTHOR
|
|
|
|
Jesse Weaver <pianohacker@gmail.com>
|
|
|
|
=cut
|