Bug 17602: RecordedBooks Integration to Koha
authorSrdjan <srdjan@catalyst.net.nz>
Fri, 23 Sep 2016 06:08:30 +0000 (18:08 +1200)
committerNick Clemens <nick@bywatersolutions.com>
Mon, 1 Oct 2018 13:56:38 +0000 (13:56 +0000)
This patch introduces the required sysprefs and Koha::ExternalContent::RecordedBooks

Koha::ExternalContent::RecordedBooks - a wrapper around
WebService::ILS::RecordedBooks::PartnerPatron

RecordedBooks* sysprefs

Nothing functional to test with this patch yet.
But you can run the tests that come with it

 t/db_dependent/Koha_ExternalContent_RecordedBooks.t

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Koha/ExternalContent/RecordedBooks.pm [new file with mode: 0644]
installer/data/mysql/atomicupdate/recordedbooks.sql [new file with mode: 0644]
installer/data/mysql/sysprefs.sql
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref
t/db_dependent/Koha_ExternalContent_RecordedBooks.t [new file with mode: 0755]

diff --git a/Koha/ExternalContent/RecordedBooks.pm b/Koha/ExternalContent/RecordedBooks.pm
new file mode 100644 (file)
index 0000000..20a8fe4
--- /dev/null
@@ -0,0 +1,111 @@
+# Copyright 2016 Catalyst
+#
+# 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 3 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.
+
+package Koha::ExternalContent::RecordedBooks;
+
+use Modern::Perl;
+use Carp;
+
+use base qw(Koha::ExternalContent);
+use WebService::ILS::RecordedBooks::PartnerPatron;
+use WebService::ILS::RecordedBooks::Partner;
+use C4::Context;
+use Koha::Logger;
+
+use constant logger => Koha::Logger->get();
+
+__PACKAGE__->mk_accessors(qw(domain is_identified));
+
+=head1 NAME
+
+Koha::ExternalContent::RecordedBooks
+
+=head1 SYNOPSIS
+
+    use Koha::ExternalContent::RecordedBooks;
+    my $od_client = Koha::ExternalContent::RecordedBooks->new();
+    my $od_auth_url = $od_client->auth_url();
+
+=head1 DESCRIPTION
+
+A (very) thin wrapper around C<WebService::ILS::RecordedBooks::Patron>
+
+Takes "RecordedBooks*" Koha preferences
+
+=cut
+
+sub new {
+    my $class  = shift;
+    my $params = shift || {};
+
+    my $self = $class->SUPER::new($params);
+    unless ($params->{client}) {
+        my $client_secret  = C4::Context->preference('RecordedBooksClientSecret')
+          or croak("RecordedBooksClientSecret pref not set");
+        my $library_id     = C4::Context->preference('RecordedBooksLibraryID')
+          or croak("RecordedBooksLibraryID pref not set");
+        my $domain         = C4::Context->preference('RecordedBooksDomain');
+        my $patron = $params->{koha_session_id} ? $self->koha_patron : undef;
+        my $email;
+        if ($patron) {
+            $email = $patron->email
+              or $self->logger->warn("User with no email, cannot identify with RecordedBooks");
+        }
+        my $client;
+        if ($email) {
+            local $@;
+            $client = eval { WebService::ILS::RecordedBooks::PartnerPatron->new(
+                client_secret     => $client_secret,
+                library_id        => $library_id,
+                domain            => $domain,
+                user_id           => $email,
+                user_agent_params => { agent => $class->agent_string }
+            ) };
+            $self->logger->warn("Invalid RecordedBooks user $email ($@)") if $@;
+            $self->is_identified($client);
+        }
+        $client ||= WebService::ILS::RecordedBooks::Partner->new(
+                client_secret     => $client_secret,
+                library_id        => $library_id,
+                domain            => $domain,
+        );
+        $self->client( $client );
+    }
+    return $self;
+}
+
+=head1 METHODS
+
+L<WebService::ILS::RecordedBooks::PartnerPatron> methods used without mods:
+
+=over 4
+
+=item C<error_message()>
+
+=back
+
+=cut
+
+use vars qw{$AUTOLOAD};
+sub AUTOLOAD {
+    my $self = shift;
+    (my $method = $AUTOLOAD) =~ s/.*:://;
+    return $self->client->$method(@_);
+}
+sub DESTROY { }
+
+1;
diff --git a/installer/data/mysql/atomicupdate/recordedbooks.sql b/installer/data/mysql/atomicupdate/recordedbooks.sql
new file mode 100644 (file)
index 0000000..2caa400
--- /dev/null
@@ -0,0 +1,4 @@
+INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+VALUES ('RecordedBooksClientSecret','','30','Client key for RecordedBooks integration','YesNo'),
+       ('RecordedBooksLibraryID','','','Library ID for RecordedBooks integration','Integer'),
+       ('RecordedBooksDomain','','','RecordedBooks domain','Free');
index e51ba36..3151b4b 100644 (file)
@@ -218,6 +218,9 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
 ('IndependentBranches','0',NULL,'If ON, increases security between libraries','YesNo'),
 ('IndependentBranchesPatronModifications','0', NULL, 'Show only modification request for the logged in branch','YesNo'),
 ('IntranetCatalogSearchPulldown','0', NULL, 'Show a search field pulldown for \"Search the catalog\" boxes','YesNo'),
+('RecordedBooksClientSecret','','30','Client key for RecordedBooks integration','YesNo'),
+('RecordedBooksDomain','','','RecordedBooks domain','Free'),
+('RecordedBooksLibraryID','','','Library ID for RecordedBooks integration','Integer'),
 ('OnSiteCheckouts','0','','Enable/Disable the on-site checkouts feature','YesNo'),
 ('OnSiteCheckoutsForce','0','','Enable/Disable the on-site for all cases (Even if a user is debarred, etc.)','YesNo'),
 ('InProcessingToShelvingCart','0','','If set, when any item with a location code of PROC is \'checked in\', it\'s location code will be changed to CART.','YesNo'),
index 9701280..671c166 100644 (file)
@@ -362,6 +362,18 @@ Enhanced Content:
             - If you enable access, you must register auth return url of
             - http(s)://my.opac.hostname/cgi-bin/koha/external/overdrive/auth.pl
             - with OverDrive.
+    RecordedBooks:
+        -
+            - Include RecordedBooks availability information with the client secret
+            - pref: RecordedBooksClientSecret
+            - .
+        -
+            - Show items from the RecordedBooks catalog of library ID
+            - pref: RecordedBooksLibraryID
+            - .
+        -
+            - RecordedBooks domain
+            - pref: RecordedBooksDomain
     Coce Cover images cache:
         -
             - pref: Coce
diff --git a/t/db_dependent/Koha_ExternalContent_RecordedBooks.t b/t/db_dependent/Koha_ExternalContent_RecordedBooks.t
new file mode 100755 (executable)
index 0000000..7f21be9
--- /dev/null
@@ -0,0 +1,55 @@
+use Modern::Perl;
+
+use t::lib::Mocks;
+use t::lib::TestBuilder;
+use Test::More tests => 3;                      # last test to print
+use C4::Auth;
+use Koha::Database;
+
+use Module::Load::Conditional qw( can_load );
+SKIP: {
+    skip "cannot filnd WebService::ILS::RecordedBooks::PartnerPatron", 3
+      unless can_load( modules => {'WebService::ILS::RecordedBooks::PartnerPatron' => undef} );
+
+    use_ok('Koha::ExternalContent::RecordedBooks');
+
+    my $ocd_user_email = $ENV{RECORDEDBOOKS_TEST_USER_EMAIL};
+    SKIP: {
+        skip "Env RECORDEDBOOKS_TEST_USER_EMAIL not set", 2 unless $ocd_user_email;
+
+        my $ocd_secret = $ENV{RECORDEDBOOKS_TEST_CLIENT_SECRET}
+          || C4::Context->preference('RecordedBooksClientSecret');
+        my $ocd_library_id = $ENV{RECORDEDBOOKS_TEST_LIBRARY_ID}
+          || C4::Context->preference('RecordedBooksLibraryID');
+        my $ocd_domain = $ENV{RECORDEDBOOKS_TEST_DOMAIN}
+          || C4::Context->preference('RecordedBooksDomain');
+        skip "Env RECORDEDBOOKS_TEST_CLIENT_SECRET RECORDEDBOOKS_TEST_LIBRARY_ID RECORDEDBOOKS_TEST_DOMAIN not set", 2
+          unless $ocd_secret && $ocd_library_id && $ocd_domain;
+
+        my $schema = Koha::Database->schema;
+        $schema->storage->txn_begin;
+        my $builder = t::lib::TestBuilder->new();
+
+        t::lib::Mocks::mock_preference('RecordedBooksClientSecret', $ocd_secret);
+        t::lib::Mocks::mock_preference('RecordedBooksLibraryID', $ocd_library_id);
+        t::lib::Mocks::mock_preference('RecordedBooksDomain', $ocd_domain);
+
+        my $patron = $builder->build({
+            source => 'Borrower',
+            value => {
+                email => $ocd_user_email,
+            }
+        });
+
+        my $session = C4::Auth::get_session("");
+        $session->param('number', $patron->{borrowernumber});
+        $session->flush;
+        my $client = Koha::ExternalContent::RecordedBooks->new({koha_session_id => $session->id});
+
+        my $user_agent_string = $client->user_agent->agent();
+        ok ($user_agent_string =~ m/^Koha/, 'User Agent string is set')
+          or diag("User Agent string: $user_agent_string");
+
+        ok ($client->search({query => "school"}), 'search()');
+    }
+}