293 lines
9.4 KiB
Perl
293 lines
9.4 KiB
Perl
package Koha::ERM::Providers::EBSCO;
|
|
|
|
use Modern::Perl;
|
|
|
|
use HTTP::Request;
|
|
use LWP::UserAgent;
|
|
use JSON qw( from_json decode_json encode_json );
|
|
use List::Util qw( first );
|
|
|
|
use Koha::Exceptions;
|
|
|
|
use Koha::ERM::EHoldings::Packages;
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $self = {};
|
|
return bless $self, $class;
|
|
}
|
|
|
|
sub config {
|
|
return {
|
|
custid => C4::Context->preference('ERMProviderEbscoCustomerID') || C4::Context->config('ERMProviderEbscoCustomerID'),
|
|
api_key => C4::Context->preference('ERMProviderEbscoApiKey') || C4::Context->config('ERMProviderEbscoApiKey'),
|
|
};
|
|
}
|
|
|
|
sub build_title {
|
|
my ( $self, $result ) = @_;
|
|
my $title = {
|
|
title_id => $result->{titleId},
|
|
publication_title => $result->{titleName},
|
|
# date_first_issue_online => ?,
|
|
# num_first_vol_online => ?,
|
|
# num_first_issue_online => ?,
|
|
# date_last_issue_online => ?,
|
|
# num_last_vol_online => ?,
|
|
# num_last_issue_online => ?,
|
|
# title_url => ?,
|
|
# embargo_info => ?,
|
|
# coverage_depth => ?,
|
|
# notes => ?,
|
|
publisher_name => $result->{publisherName},
|
|
publication_type => $result->{pubType},
|
|
# date_monograph_published_print => ?,
|
|
# date_monograph_published_online => ?,
|
|
# monograph_volume => ?,
|
|
# monograph_edition => ?,
|
|
# first_editor => ?,
|
|
# parent_publication_title_id => ?,
|
|
# preceding_publication_title_id => ?,
|
|
# access_type => ?,
|
|
};
|
|
if ( $result->{contributorsList} ) {
|
|
my @contributors = @{ $result->{contributorsList} };
|
|
my $first_author = first { $_->{type} eq 'author' || $_->{type} eq 'Author' } @contributors;
|
|
if ( $first_author ) {
|
|
$title->{first_author} = $first_author->{contributor};
|
|
}
|
|
}
|
|
for my $identifier ( @{ $result->{identifiersList} } ) {
|
|
|
|
# FIXME $identifier->{type} : 0 for ISSN and 1 for ISBN
|
|
if ( $identifier->{subtype} == 1 ) {
|
|
$title->{print_identifier} = $identifier->{id};
|
|
}
|
|
elsif ( $identifier->{subtype} == 2 ) {
|
|
$title->{online_identifier} = $identifier->{id};
|
|
}
|
|
}
|
|
for my $r ( @{ $result->{customerResourcesList} } ) {
|
|
if ( $r->{isSelected} ) {
|
|
$title->{is_selected} = 1;
|
|
last;
|
|
}
|
|
}
|
|
|
|
return $title;
|
|
}
|
|
|
|
sub build_vendor {
|
|
my ( $self, $result ) = @_;
|
|
my $vendor = {
|
|
vendor_id => $result->{vendorId},
|
|
name => $result->{vendorName},
|
|
package_type => $result->{packageType},
|
|
};
|
|
return $vendor;
|
|
}
|
|
|
|
sub build_package {
|
|
my ( $self, $result ) = @_;
|
|
my $local_package = $self->get_local_package(
|
|
$result->{vendorId} . '-' . $result->{packageId} );
|
|
my $package = {
|
|
package_id => $result->{vendorId} . '-' . $result->{packageId},
|
|
( $local_package
|
|
? ( koha_internal_id => $local_package->package_id )
|
|
: () ),
|
|
name => $result->{packageName},
|
|
content_type => $result->{contentType}, # This does not exist in /vendors/1/packages/2/titles/3
|
|
created_on => undef,
|
|
is_selected => $result->{isSelected},
|
|
package_type => $result->{packageType},
|
|
vendor_id => $result->{vendorId},
|
|
};
|
|
return $package;
|
|
}
|
|
|
|
sub build_resource {
|
|
my ( $self, $result ) = @_;
|
|
my $resource = {
|
|
resource_id => $result->{vendorId} . '-'
|
|
. $result->{packageId} . '-'
|
|
. $result->{titleId},
|
|
package_id => $result->{vendorId} . '-' . $result->{packageId},
|
|
title_id => $result->{titleId},
|
|
is_selected => $result->{isSelected},
|
|
started_on => $result->{managedCoverageList}->[0]->{beginCoverage},
|
|
ended_on => $result->{managedCoverageList}->[0]->{endCoverage},
|
|
};
|
|
return $resource;
|
|
}
|
|
|
|
sub build_additional_params {
|
|
my ( $self, $query_params ) = @_;
|
|
|
|
my $additional_params;
|
|
if ( $query_params->{q} ) {
|
|
my $q = from_json $query_params->{q};
|
|
while ( my ( $attr, $value ) = each %$q ) {
|
|
$additional_params->{$attr} = $value;
|
|
}
|
|
}
|
|
|
|
return $additional_params;
|
|
}
|
|
|
|
sub get_local_package {
|
|
my ( $self, $package_id ) = @_;
|
|
return Koha::ERM::EHoldings::Packages->find(
|
|
{ provider => 'ebsco', external_id => $package_id } );
|
|
}
|
|
|
|
sub embed {
|
|
my ( $self, $object, $info, $embed_header ) = @_;
|
|
$embed_header ||= q{};
|
|
|
|
my @embed_resources;
|
|
|
|
foreach my $embed_req ( split /\s*,\s*/, $embed_header ) {
|
|
if ( $embed_req eq 'vendor.name' ) {
|
|
$object->{vendor} = { name => $info->{vendorName}, };
|
|
}
|
|
elsif ( $embed_req eq 'vendor' ) {
|
|
$object->{vendor} = $self->build_vendor($info);
|
|
}
|
|
elsif ( $embed_req eq 'title' ) {
|
|
$object->{title} = $self->build_title($info);
|
|
}
|
|
elsif ( $embed_req eq 'resources+count' ) {
|
|
$object->{resources_count} = $info->{titleCount};
|
|
}
|
|
elsif ( $embed_req eq 'package' ) {
|
|
$object->{package} = $self->build_package($info);
|
|
}
|
|
elsif ( $embed_req eq 'package.name' ) {
|
|
$object->{package} = { name => $info->{packageName}, };
|
|
}
|
|
elsif ( $embed_req eq 'package_agreements.agreement' ) {
|
|
# How to deal with 'package_agreements.agreement'?
|
|
$object->{package_agreements} = [];
|
|
my $package_id = $info->{vendorId} . '-' . $info->{packageId};
|
|
my $local_package = $self->get_local_package($package_id);
|
|
if ( $local_package ) {
|
|
for my $package_agreement (
|
|
@{ $local_package->package_agreements->as_list } )
|
|
{
|
|
push @{ $object->{package_agreements} },
|
|
{
|
|
%{ $package_agreement->unblessed },
|
|
agreement => $package_agreement->agreement->unblessed,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
if ( $embed_req eq 'resources' || $embed_req eq 'resources.package' ) {
|
|
push @embed_resources, $embed_req;
|
|
}
|
|
}
|
|
|
|
if (@embed_resources) {
|
|
for my $r ( @{ $info->{customerResourcesList} } ) {
|
|
my $resource = {};
|
|
for my $embed_req ( @embed_resources ) {
|
|
if ( $embed_req eq 'resources' ) {
|
|
$resource = $self->build_resource($r);
|
|
}
|
|
elsif ( $embed_req eq 'resources.package' ) {
|
|
unless ( %$resource ) {
|
|
$resource = $self->build_resource($r);
|
|
}
|
|
$resource->{package} = $self->build_package($r);
|
|
}
|
|
}
|
|
push @{$object->{resources}}, $resource;
|
|
}
|
|
}
|
|
return $object;
|
|
}
|
|
|
|
sub build_query_pagination {
|
|
my ( $self, $params ) = @_;
|
|
my $per_page = $params->{_per_page}
|
|
// C4::Context->preference('RESTdefaultPageSize') // 20;
|
|
if ( $per_page == -1 || $per_page > 100 ) { $per_page = 100; }
|
|
my $page = $params->{_page} || 1;
|
|
|
|
return ( $per_page, $page );
|
|
}
|
|
|
|
sub build_query {
|
|
my ( $self, $url, $params ) = @_;
|
|
|
|
return $url unless $params && %$params;
|
|
while ( my ( $attr, $value ) = each %$params ) {
|
|
if ( $attr eq 'name' ) {
|
|
$url .= '&search=' . $value;
|
|
}
|
|
elsif ( $attr eq 'content_type' ) {
|
|
$url .= '&contenttype=' . $value;
|
|
}
|
|
elsif ( $attr eq 'selection_type' ) {
|
|
$url .= '&selection=' . $value;
|
|
}
|
|
elsif ( $attr eq 'publication_title' ) {
|
|
$url .= '&search=' . $value;
|
|
}
|
|
elsif ( $attr eq 'publication_type' ) {
|
|
$url .= '&resourcetype=' . $value;
|
|
}
|
|
}
|
|
return $url;
|
|
}
|
|
|
|
sub request {
|
|
my ( $self, $method, $url, $params, $payload ) = @_;
|
|
|
|
$url = $self->build_query($url, $params) if $params;
|
|
|
|
my $config = $self->config;
|
|
my $base_url = 'https://api.ebsco.io/rm/rmaccounts/' . $config->{custid};
|
|
my $request = HTTP::Request->new(
|
|
$method => $base_url . $url,
|
|
undef, ( $payload ? encode_json($payload) : undef )
|
|
);
|
|
$request->header( 'x-api-key' => $config->{api_key} );
|
|
$request->header( 'content-type' => 'application/json; charset=UTF-8' );
|
|
my $ua = LWP::UserAgent->new;
|
|
my $response = $ua->simple_request($request);
|
|
if ( $response->code >= 400 ) {
|
|
my $result = decode_json( $response->decoded_content );
|
|
my $message;
|
|
if ( ref($result) eq 'ARRAY' ) {
|
|
for my $r (@$result) {
|
|
$message .= $r->{message};
|
|
}
|
|
}
|
|
else {
|
|
$message = $result->{message} || $result->{Message} || q{};
|
|
if ( $result->{errors} ) {
|
|
for my $e ( @{ $result->{errors} } ) {
|
|
$message .= $e->{message};
|
|
}
|
|
}
|
|
}
|
|
warn sprintf "ERROR - EBSCO API %s returned %s - %s\n", $url, $response->code, $message;
|
|
if ( $response->code == 404 ) {
|
|
Koha::Exceptions::ObjectNotFound->throw($message);
|
|
} elsif ( $response->code == 401 ) {
|
|
Koha::Exceptions::Authorization::Unauthorized->throw($message);
|
|
} else {
|
|
die sprintf "ERROR requesting EBSCO API\n%s\ncode %s: %s\n", $url, $response->code,
|
|
$message;
|
|
}
|
|
} elsif ( $response->code == 204 ) { # No content
|
|
return
|
|
}
|
|
|
|
return decode_json( $response->decoded_content );
|
|
}
|
|
|
|
1;
|