{ "translatorID": "1300cd65-d23a-4bbf-93e5-a3c9e00d1066", "label": "Primo", "creator": "Matt Burton, Avram Lyon, Etienne Cavalié, Rintze Zelle, Philipp Zumstein, Sebastian Karcher, Aurimas Vinckevicius", "target": "/primo_library/|/nebis/|^https?://www\\.recherche-portal\\.ch/zbz/", "minVersion": "2.1.9", "maxVersion": "", "priority": 101, "inRepository": true, "translatorType": 4, "browserSupport": "gcsbv", "lastUpdated": "2020-02-04 01:29:32" } /* ***** BEGIN LICENSE BLOCK ***** This file is part of Zotero. Zotero is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Zotero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Zotero. If not, see . ***** END LICENSE BLOCK ***** */ /* Supports Primo 2: Université de Nice, France (http://catalogue.unice.fr/) (looks like this is Primo3 now, too) Supports Primo 3 Boston College (http://www.bc.edu/libraries/), Oxford Libraries (http://solo.ouls.ox.ac.uk/) Primos with showPNX.jsp installed: (1) http://purdue-primo-prod.hosted.exlibrisgroup.com/primo_library/libweb/action/search.do?vid=PURDUE (2) http://primo.bib.uni-mannheim.de/primo_library/libweb/action/search.do?vid=MAN_UB (3) http://limo.libis.be/primo_library/libweb/action/search.do?vid=LIBISnet&fromLogin=true (4.a) http://virtuose.uqam.ca/primo_library/libweb/action/search.do?vid=UQAM (5) http://searchit.princeton.edu/primo_library/libweb/action/dlDisplay.do?docId=PRN_VOYAGER2778598&vid=PRINCETON&institution=PRN */ function getSearchResults(doc) { // order dictates preference var linkXPaths = ['.//li[starts-with(@id,"exlidResult") and substring(@id,string-length(@id)-10)="-DetailsTab"]/a[@href]', // details link './/h2[@class="EXLResultTitle"]/a[@href]']; // title link var resultsXPath = '//*[self::tr or self::div][starts-with(@id, "exlidResult") and ' + 'number(substring(@id,12))=substring(@id,12)][' + linkXPaths.join(' or ') + ']'; // Z.debug(resultsXPath); var results = ZU.xpath(doc, resultsXPath); results.titleXPath = './/h2[@class="EXLResultTitle"]'; results.linkXPaths = linkXPaths; return results; } function detectWeb(doc) { if (getSearchResults(doc).length) { return 'multiple'; } var contentDiv = doc.getElementsByClassName('EXLFullResultsHeader'); if (!contentDiv.length) contentDiv = doc.getElementsByClassName('EXLFullDisplay'); if (!contentDiv.length) contentDiv = doc.getElementsByClassName('EXLFullView'); if (contentDiv.length) return 'book'; return false; } function doWeb(doc, url) { var searchResults = getSearchResults(doc); if (searchResults.length) { var items = {}, itemIDs = {}, title, link, linkXPaths = searchResults.linkXPaths; for (var i = 0, n = searchResults.length; i < n; i++) { title = ZU.xpathText(searchResults[i], searchResults.titleXPath); for (var j = 0, m = linkXPaths.length; j < m; j++) { link = ZU.xpath(searchResults[i], linkXPaths[j])[0]; if (link) { break; } } if (!link || !title || !(title = ZU.trimInternal(title))) continue; items[link.href] = title; itemIDs[link.href] = { id: i, docID: getDocID(link.href) }; } Z.selectItems(items, function (selectedItems) { if (!selectedItems) return true; var urls = []; for (var i in selectedItems) { urls.push({ url: i, id: itemIDs[i].id, docID: itemIDs[i].docID }); } fetchPNX(urls); return true; }); } else { fetchPNX([{ url: url, id: 0, docID: getDocID(url) }]); } } function getDocID(url) { var id = url.match(/\bdoc(?:Id)?=([^&]+)/i); if (id) return id[1]; else return false; } // keeps track of which URL format works for retrieving PNX record // and applies the correct transformation function var PNXUrlGenerator = new function () { var functions = [ // showPNX.js // using docIDs instead of IDs tied to a session // e.g. http://searchit.princeton.edu/primo_library/libweb/showPNX.jsp?id=PRN_VOYAGER7343340 function (urlObj) { return getUrlWithId(urlObj.url, urlObj.docID); }, // fall back to IDs // from: http://primo.bib.uni-mannheim.de/primo_library/libweb/action/search.do?... // to: http://primo.bib.uni-mannheim.de/primo_library/libweb/showPNX.jsp?id= function (urlObj) { return getUrlWithId(urlObj.url, urlObj.id); }, // simply add &showPnx=true function (urlObj) { var url = urlObj.url.split('#'); if (!url[0].includes("?")) { url[0] += '?'; } else { url[0] += '&'; } return url[0] + 'showPnx=true'; } ]; function getUrlWithId(url, id) { url = url.match(/(https?:\/\/[^?#]+\/)[^?#]+\/[^/]*(?:[?#]|$)/); if (!url) return false; return url[1] + 'showPNX.jsp?id=' + id; } this.currentFunction = 0; this.confirmed = false; this.getUrl = function (data) { var fun = functions[this.currentFunction]; if (!fun) return false; return fun(data); }; this.nextFunction = function () { if (!this.confirmed && this.currentFunction < functions.length) { Z.debug("Function " + this.currentFunction + " did not work."); this.currentFunction++; return true; } else { return false; } }; }; // retrieve PNX records for given items sequentially function fetchPNX(itemData) { if (!itemData.length) return; // do this until we run out of URLs var data = itemData.shift(); var url = PNXUrlGenerator.getUrl(data); // format URL if still possible if (!url) { if (PNXUrlGenerator.nextFunction()) { itemData.unshift(data); } else if (!PNXUrlGenerator.confirmed) { // in case we can't find PNX for a particular item, // go to the next and start looking from begining Z.debug("Could not determine PNX url from " + data.url); PNXUrlGenerator.currentFunction = 0; } fetchPNX(itemData); return; } var gotPNX = false; Z.debug("Trying " + url); ZU.doGet(url, function (text) { text = text.trim(); if (text.substr(0, 5) != '