/* Primo VE HathiTrust Availability Add-On for CARLI I-Share - 12/15/2020
* adapted from https://github.com/UMNLibraries/primo-explore-hathitrust-availability
*
* NOTE: Be sure to add 'hathiTrustAvailability' to the
* angular.module() function at the top of the custom.js file,
* i.e., add it to the array that also includes 'angularLoad', e.g.:
*
* var app = angular.module('viewCustom', ['angularLoad', 'hathiTrustAvailability']);
*
* There are several optional configuration choices you can set for the app.component "template":
*
* Customizing the Availability Message - The default availability message that displays in the Brief
* Results list and the Full Record page is "Full Text Available at HathiTrust". You can override
* this by setting the msg attribute:
*
*
*
* Selectively Suppress Full-text Links - By default, the component will display full-text links
* for any resource.
*
* --If you want it avoid looking for full-text availability on records for which you already have online
* access, add the hide-online attribute to the component:
*
*
*
* --You can also suppress full-text links for journals, if desired, with hide-if-journal option:
*
*
*
* Copyright Status - By default, the component will display only when the item is out of copyright
* and therefore should be accessible.
*
* --If you want to display full-text links to any HathiTrust record, regardless of copyright status,
* use the ignore-copyright attribute:
*
*
*
* --If your institution is a HathiTrust partner institution and you want the availability links
* in Primo VE to use HathiTrust's automatic login process, add your SAML IdP's entity ID:
*
*
*
* E.g.,
* app.component('prmSearchResultAvailabilityLineAfter', {
* template: ''
* });
*
*/
app.component('prmSearchResultAvailabilityLineAfter', {
template: ''
});
angular.module('hathiTrustAvailability', []).constant('hathiTrustBaseUrl', 'https://catalog.hathitrust.org/api/volumes/brief/json/').config(['$sceDelegateProvider', 'hathiTrustBaseUrl', function ($sceDelegateProvider, hathiTrustBaseUrl) {
var urlWhitelist = $sceDelegateProvider.resourceUrlWhitelist();
urlWhitelist.push(hathiTrustBaseUrl + '**');
$sceDelegateProvider.resourceUrlWhitelist(urlWhitelist);
}]).factory('hathiTrust', ['$http', '$q', 'hathiTrustBaseUrl', function ($http, $q, hathiTrustBaseUrl) {
var svc = {};
var lookup = function lookup(ids) {
if (ids.length) {
var hathiTrustLookupUrl = hathiTrustBaseUrl + ids.join('|');
return $http.jsonp(hathiTrustLookupUrl, {
cache: true,
jsonpCallbackParam: 'callback'
}).then(function (resp) {
return resp.data;
});
} else {
return $q.resolve(null);
}
};
// find a HT record URL for a given list of identifiers (regardless of copyright status)
svc.findRecord = function (ids) {
return lookup(ids).then(function (bibData) {
for (var i = 0; i < ids.length; i++) {
var recordId = Object.keys(bibData[ids[i]].records)[0];
if (recordId) {
return $q.resolve(bibData[ids[i]].records[recordId].recordURL);
}
}
return $q.resolve(null);
}).catch(function (e) {
console.error(e);
});
};
// find a public-domain HT record URL for a given list of identifiers
svc.findFullViewRecord = function (ids) {
var handleResponse = function handleResponse(bibData) {
var fullTextUrl = null;
for (var i = 0; !fullTextUrl && i < ids.length; i++) {
var result = bibData[ids[i]];
for (var j = 0; j < result.items.length; j++) {
var item = result.items[j];
if (item.usRightsString.toLowerCase() === 'full view') {
fullTextUrl = result.records[item.fromRecord].recordURL;
break;
}
}
}
return $q.resolve(fullTextUrl);
};
return lookup(ids).then(handleResponse).catch(function (e) {
console.error(e);
});
};
return svc;
}]).controller('hathiTrustAvailabilityController', ['hathiTrust', function (hathiTrust) {
var self = this;
self.$onInit = function () {
if (!self.msg) self.msg = 'Full Text Available at HathiTrust';
// prevent appearance/request iff 'hide-online'
if (self.hideOnline && isOnline()) {
return;
}
// prevent appearance/request iff 'hide-if-journal'
if (self.hideIfJournal && isJournal()) {
return;
}
// look for full text at HathiTrust
updateHathiTrustAvailability();
};
var isJournal = function isJournal() {
var format = self.prmSearchResultAvailabilityLine.result.pnx.addata.format[0];
return !(format.toLowerCase().indexOf('journal') == -1); // format.includes("Journal")
};
var isOnline = function isOnline() {
var delivery = self.prmSearchResultAvailabilityLine.result.delivery || [];
if (!delivery.GetIt1) return delivery.deliveryCategory.indexOf('Alma-E') !== -1;
return self.prmSearchResultAvailabilityLine.result.delivery.GetIt1.some(function (g) {
return g.links.some(function (l) {
return l.isLinktoOnline;
});
});
};
var formatLink = function formatLink(link) {
return self.entityId ? link + '?signon=swle:' + self.entityId : link;
};
var isOclcNum = function isOclcNum(value) {
return value.match(/^(\(ocolc\))\d+$/i);
};
var updateHathiTrustAvailability = function updateHathiTrustAvailability() {
var hathiTrustIds = (self.prmSearchResultAvailabilityLine.result.pnx.addata.oclcid || []).filter(isOclcNum).map(function (id) {
return 'oclc:' + id.toLowerCase().replace('(ocolc)', '');
});
hathiTrust[self.ignoreCopyright ? 'findRecord' : 'findFullViewRecord'](hathiTrustIds).then(function (res) {
if (res) self.fullTextLink = formatLink(res);
});
};
}]).component('hathiTrustAvailability', {
require: {
prmSearchResultAvailabilityLine: '^prmSearchResultAvailabilityLine'
},
bindings: {
entityId: '@',
ignoreCopyright: '<',
hideIfJournal: '<',
hideOnline: '<',
msg: '@?'
},
controller: 'hathiTrustAvailabilityController',
template: '\
\
\
\
\
{{ ::$ctrl.msg }}\
\
\
'
});
/* END HathiTrust Availability add-on */