The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

WebService::ILS - Standardised library discovery/circulation services

SYNOPSIS

    use WebService::ILS::<Provider Subclass>;
    my $ils = WebService::ILS::<Provider Subclass>->new({
        client_id => $client_id,
        client_secret => $client_secret
    });
    my %search_params = (
        query => "Some keyword",
        sort => "rating",
    );
    my $result = $ils->search(\%search_params);
    foreach (@{ $result->{items} }) {
        ...
    }
    foreach (2..$result->{pages}) {
        $search_params{page} = $_;
        my $next_results = $ils->search(\%search_params);
        ...
    }

    or

    my $native_result = $ils->native_search(\%native_search_params);

DESCRIPTION

WebService::ILS is an attempt to create a standardised interface for online library services providers.

In addition, native API interface is provided.

Here we will describe constructor parameters and methods common to all service providers. Diversions and native interfaces are documented in corresponding modules.

Supported service providers

WebService::ILS::OverDrive::Library

OverDrive Library API https://developer.overdrive.com/discovery-apis

WebService::ILS::OverDrive::Patron

OverDrive Circulation API https://developer.overdrive.com/circulation-apis

INTERFACE

Error handling

Method calls will die on error. $@ will contain a multi-line string. See error_message() below.

Item record

Item record is returned by many methods, so we specify it here.

id
isbn
title
subtitle
description
author
publisher
publication_date
language
rating => user ratings metrics
popularity => checkout metrics
subjects => subject categories (tags)
facets => a hashref of facet => [values]
media => book, e-book, video, audio etc
formats => an arrayref of available formats
images => a hashref of size => url
encryption_key => for decryption purposes
drm => subject to drm

Not all fields are available for all service providers. Field values are not standardised.

CONSTRUCTOR

new (%params_hash or $params_hashref)

client_id => client (vendor) identifier
client_secret => secret key (password)
library_id => sometimes service providers provide access to differnt "libraries"

General constructor params:

user_agent => LWP::UserAgent or a derivative; usually not needed, one is created for you.
user_agent_params => LWP::UserAgent constructor params so you don't need to create user agent yourself
access_token => as returned from the provider authentication system
access_token_type => as returned from the provider authentication system

These are also read-only attributes

Not all of client/library params are required for all service providers.

ATTRIBUTES

user_agent

As provided to constructor, or auto created. Useful if one wants to change user agent attributes on the fly, eg

    $ils->user_agent->timeout(120);

DISCOVERY METHODS

search ($params_hashref)

Input params:

query => query (search) string
page_size => number of items per results page
page => wanted page number
sort => resultset sort option (see below)

Sort options are either an array or a comma separated string of options:

publication_date => date title was published
available_date => date title became available for users
rating => number of items per results page

Sort order can be added after option with ":", eg "publication_date:desc,rating:desc"

Returns search results record:

items => an array of item records
page_size => number of items per results page
page => results page number
pages => total number of pages

item_metadata ($item_id)

Returns item record

item_availability ($item_id)

Returns item availability record:

id
available => boolean
copies_available => number of copies available
copies_owned => number of copies owned
type => availability type, provider dependant

Not all fields are available for all service providers. For example, some will provide "copies_available", making "available" redundant, whereas others will just provide "available".

is_item_available ($item_id)

Returns boolean

Simplified version of item_availability()

INDIVIDUAL USER AUTHENTICATION AND METHODS

user_id / password

Provider authentication API is used to get an authorized session.

auth_by_user_id($user_id, $password)

An example:

    my $ils = WebService::ILS::Provider({
        client_id => $client_id,
        client_secret => $client_secret,
    });
    eval { $ils->auth_by_user_id( $user_id, $password ) };
    if ($@) { some_error_handling(); return; }
    $session{ils_access_token} = $ils->access_token;
    $session{ils_access_token_type} = $ils->access_token_type;
    ...
    Somewhere else in your app:
    my $ils = WebService::ILS::Provider({
        client_id => $client_id,
        client_secret => $client_secret,
        access_token => $session{ils_access_token},
        access_token_type => $session{ils_access_token_type},
    });
 
    my $checkouts = $ils->checkouts;

Authentication at the provider

User is redirected to the provider authentication url, and after authenticating at the provider redirected back with some kind of auth token. Requires url to handle return redirect from the provider.

It can be used as an alternative to FB and Google auth.

This is just to give an idea, specifics heavily depend on the provider

auth_url ($redirect_back_uri)

Returns provider authentication url to redirect to

auth_token_param_name ()

Returns auth code url param name

auth_by_token ($provider_token)

An example:

    my $ils = WebService::ILS::Provider({
        client_id => $client_id,
        client_secret => $client_secret,
    });
    my $redirect_url = $ils->auth_url("http://myapp.com/ils-auth");
    $response->redirect($redirect_url);
    ...
    After successful authentication at the provider, provider redirects
    back to specified app url (http://myapp.com/ils-auth)

    /ils-auth handler:
    my $auth_token = $req->param( $ils->auth_token_param_name )
        or some_error_handling(), return;
    local $@;
    eval { $ils->auth_by_token( $auth_token ) };
    if ($@) { some_error_handling(); return; }
    $session{ils_access_token} = $ils->access_token;
    $session{ils_access_token_type} = $ils->access_token_type;
    ...
    Somewhere else in your app:
    passing access token to the constructor as above

CIRCULATION METHODS

patron ()

Returns patron record:

id
active => boolean
copies_available => number of copies available
checkout_limit => number of checkouts allowed
hold_limit => number of holds allowed

holds ()

Returns holds record:

total => number of items on hold
items => list of individual items

In addition to Item record fields described above, item records will have:

placed_datetime => hold timestamp, with or without timezone
queue_position => user's position in the waiting queue, if available

place_hold ($item_id)

Returns holds item record (as described above)

In addition, total field will be incorported as well.

remove_hold ($item_id)

Returns true to indicate success

Returns true in case user does not have a hold on the item. Throws exception in case of any other failure.

checkouts ()

Returns checkout record:

total => number of items on hold
items => list of individual items

In addition to Item record fields described above, item records will have:

checkout_datetime => checkout timestamp, with or without timezone
expires => date (time) checkout expires
url => download/stream url
files => an arrayref of downloadable file details title, url, size

checkout ($item_id)

Returns checkout item record (as described above)

In addition, total field will be incorported as well.

return ($item_id)

Returns true to indicate success

Returns true in case user does not have the item checked out. Throws exception in case of any other failure.

NATIVE METHODS

All Discovery and Circulation methods (with exception of remove_hold() and return(), where it does not make sense) have native_*() counterparts, eg native_search(), native_item_availability(), native_checkout() etc.

In case of single item methods, native_item_availability(), native_checkout() etc, they take item_id as parameter. Otherwise, it's a hashref of HTTP request params (GET or POST).

Return value is a record as returned by API.

Individual provider subclasses provide additional provider specific native methods.

UTILITY METHODS

Error constants

ERROR_ACCESS_TOKEN
ERROR_NOT_AUTHENTICATED

error_message ($exception_string)

Returns error message probably suitable for displaying to the user

Example:

    my $res = eval { $ils->checkout($id) }; 
    if ($@) {
        my $msg = $ils->error_message($@);
        display($msg);
        log_error($@);
    }

is_access_token_error ($exception_string)

is_not_authenticated_error ($exception_string)

Returns true if the error is "Not authenticated"

TODO

Federated search

LICENSE

Copyright (C) Catalyst IT NZ Ltd Copyright (C) Bywater Solutions

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

AUTHOR

Srdjan Janković <srdjan@catalyst.net.nz>