Permalink
Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up
translators/Summon 2.js
Find file
Copy path
Fetching contributors…
Cannot retrieve contributors at this time
{ | |
"translatorID": "6c61897b-ca44-4ce6-87c1-2da68b44e6f7", | |
"label": "Summon 2", | |
"creator": "Caistarrin Mystical and Aurimas Vinckevicius", | |
"target": "^https?://([^/]+\\.)?summon\\.serialssolutions\\.com/", | |
"minVersion": "4.0", | |
"maxVersion": "", | |
"priority": 150, | |
"inRepository": true, | |
"translatorType": 4, | |
"browserSupport": "gcsib", | |
"lastUpdated": "2017-06-24 21:11:06" | |
} | |
/* | |
Summon 2.0 Translator | |
Copyright (C) 2014 ProQuest LLC | |
This program 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. | |
This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
function detectWeb(doc, url) { | |
var results = doc.getElementById('results'); | |
var displayMultiple = false; | |
if (results) { | |
var ul = results.firstElementChild.firstElementChild; | |
if (ul) { | |
// This is currently broken in Zotero. | |
// Scrolling down one page ends up triggering Page Modified event | |
// 111 times and makes the page unusable after a while. | |
//Zotero.monitorDOMChanges(ul, {childList: true}); | |
// temporary hack to display multiples | |
displayMultiple = true; | |
} | |
} | |
var detailPage = doc.getElementsByClassName('detailPage')[0]; | |
if (detailPage) { | |
// Changes from visible to not by adding class ng-hide | |
Zotero.monitorDOMChanges(detailPage, {attributes: true, attributeFiler: ['class']}); | |
if (detailPage.offsetHeight) { | |
// Visible details page | |
var id = getIDFromUrl(url); | |
if (id) return 'book'; | |
} | |
} | |
if (getSearchResults(doc, true) || displayMultiple) { | |
return "multiple"; | |
} | |
} | |
function getIDFromUrl(url) { | |
var m = url.match(/[&?]id=([^&#]+)/); | |
return m && m[1]; | |
} | |
function getSearchResults(doc, checkOnly) { | |
var results = doc.getElementById('results'); | |
if (!results) return false; | |
var titles = results.getElementsByClassName('customPrimaryLinkContainer'); | |
var items = {}, found = false; | |
var numRollups = 0; | |
for (var i=0; i<titles.length; i++) { | |
var isRollup = !!ZU.xpath(titles[i], './ancestor::div[contains(@class, "rollup")]').length; | |
// That class gets reused a bit | |
if (!isRollup && titles[i].nodeName.toUpperCase() != 'H1') continue; | |
var index; | |
if (isRollup) { | |
index = 'r' + numRollups; | |
numRollups++; | |
} else { | |
index = i - numRollups; | |
} | |
var title = titles[i].getElementsByTagName('a')[0]; | |
if (title) title = ZU.trimInternal(title.textContent); | |
if (!title) continue; | |
if (checkOnly) return true; | |
found = true; | |
items['_' + index] = title; | |
} | |
return found ? items : false; | |
} | |
function doWeb(doc, url) { | |
var dbName = ZU.xpath(doc, '//div[contains(@class, "header")]//img[contains(@class, "logo")]/@alt')[0]; | |
if (dbName) dbName = dbName.value; | |
if (detectWeb(doc, url) == 'multiple') { | |
Zotero.selectItems(getSearchResults(doc), function(items) { | |
if (!items) { | |
return true; | |
} | |
var indexes = [] | |
for (var item in items) { | |
indexes.push(item.substr(1)); | |
} | |
fetchData(getApiData(doc, url, indexes), dbName) | |
}); | |
} else { | |
var id = getIDFromUrl(url); | |
var url = '/api/search?fids=' + encodeURIComponent(id); | |
fetchData({urlSet: [url], indexBlocks: { 1: ['0'] }}, dbName); | |
} | |
} | |
function fetchData(apiData, dbName) { | |
var documents = []; | |
ZU.doGet(apiData.urlSet, function (text, _, chunkUrl) { | |
var obj = JSON.parse(text); | |
var page = chunkUrl.match(/[?&]pn=(\d+)/); | |
if (page) { | |
page = page[1]; | |
} else if (/[?&]fids=/.test(chunkUrl)) { | |
// For single pages | |
page = 1; | |
} | |
var indexes = apiData.indexBlocks[page]; | |
for (var j = 0; j < indexes.length; j++) { | |
var i = indexes[j]; | |
if (i.charAt(0) == 'r') { | |
// Rollup. Drop 'r' for actual index | |
documents.push(obj.rollups.newspaper.documents[i.substr(1)]); | |
} | |
else { | |
documents.push(obj.documents[i]); | |
} | |
} | |
}, | |
function () { // All done | |
// Grab database name for Library Catalog field | |
getRefData(documents, dbName); | |
} | |
); | |
} | |
var pageSize = 10; // Number of results to fetch per page | |
function getApiData(doc, url, indexes) { | |
url = doc.location.href; | |
//Z.debug(url) | |
var urlArray = url.split('?'); | |
var apiURL = '/api/search?' | |
+ urlArray.pop().replace(/(^|&)fvf=([^&#]*)/, function(m, sep, fvf) { | |
return sep + 'fvf[]=' + fvf.replace(/\||%7c/gi, '&fvf[]='); | |
}) | |
+ '&ps=' + pageSize; | |
// Split up selected indeces into blocks set by pageSize then fetch each block | |
// independently and concatenate them later | |
var urlSet = []; | |
var indexBlocks = {}; | |
for (var i = 0; i < indexes.length; i++) { | |
var page, // Page number for given index (these don't have to end up continuous). 1 based | |
pageIndex = indexes[i]; // Item index in a given page. 0 based | |
if (pageIndex.charAt(0) == 'r') { | |
// All rollups are on first page | |
page = 1; | |
} else { | |
pageIndex *= 1; // convert to integer from string | |
page = Math.ceil((pageIndex + 1) / pageSize); // +1 because 0 based | |
pageIndex %= pageSize; | |
} | |
if (!indexBlocks[page]) { | |
// New set | |
indexBlocks[page] = []; | |
urlSet.push(apiURL + "&pn=" + page); | |
} | |
indexBlocks[page].push('' + pageIndex); // make sure it's string so it's easier to check for 'r' later | |
} | |
return {"urlSet": urlSet, "indexBlocks": indexBlocks}; | |
} | |
function getRefData(documents, uniName) { | |
for (var i = 0; i < documents.length; i++) { | |
var ref = documents[i]; | |
var item = new Zotero.Item(getRefType(ref)); | |
item.creators = getAuthors(ref); | |
if (item.creators.length && ref.subtitle | |
&& ref.subtitle.indexOf(item.creators[0].lastName) != -1 | |
) { | |
item.title = ZU.cleanTags(ref.title); | |
// Frequently the book's subtitle (and full title) will include the author. | |
// Clean it up in those cases | |
var subtitle = ZU.cleanTags(ref.subtitle) | |
.replace( | |
new RegExp( | |
'(?:\\s*[-–—/:])?\\s*' // Possibly separated by / but account for other characters too | |
+ '(?:ed(?:itor|\\.)?,?\\s+)?' // Could be an editor. Perhaps others? | |
+ '(?:' + ZU.quotemeta(item.creators[0].lastName) // Not sure which one could come first | |
+ (item.creators[0].firstName | |
? '|' + ZU.quotemeta(item.creators[0].firstName) | |
: '') | |
+ ')' | |
+ '.*', // Toss everything afterwards | |
'i' // ignore case (mostly for editor part) | |
), | |
'' | |
); | |
if (subtitle) item.title += ': ' + subtitle; | |
} else { | |
item.title = ZU.cleanTags(ref.full_title); | |
} | |
item.libraryCatalog = uniName + ", Summon 2.0"; | |
item.ISBN = ref.isbn; | |
item.publisher = ref.publisher; | |
item.publicationTitle = ref.publication_title; | |
item.numPages = ref.page_count; | |
item.tags = ref.subject_terms; | |
item.series = ref.publication_series_title; | |
if (ref.lc_call_numbers) { | |
item.callNumber = ref.lc_call_numbers[0]; | |
} | |
if (ref.volumes) { | |
item.volume = ref.volumes[0]; | |
} | |
if (ref.issues) { | |
item.issue = ref.issues[0]; | |
} | |
if (ref.uris) { | |
item.url = ref.uris[0]; | |
} | |
if (ref.languages) { | |
item.language = ref.languages[0]; | |
} | |
if (ref.copyrights) { | |
item.rights = ref.copyrights[0]; | |
} | |
if (ref.dois) { | |
item.DOI = ref.dois[0]; | |
} | |
if (ref.abstracts && ref.abstracts.length > 0) { | |
item.abstractNote = ref.abstracts[0].abstract; | |
} | |
if (ref.issns) { | |
item.ISSN = ref.issns[0]; | |
} | |
else if (ref.eissns) { | |
item.ISSN = ref.eissns[0]; | |
} | |
if (ref.publication_places) { | |
item.place = ref.publication_places[0]; | |
} | |
else if (ref.dissertation_schools) { | |
item.place = ref.dissertation_schools[0]; | |
} | |
item.pages = ref.pages; | |
if (!item.pages && ref.start_pages) { | |
item.pages = ref.start_pages[0] | |
+ (ref.end_pages && ref.end_pages.length > 0 | |
? "-" + ref.end_pages[0] | |
: "" | |
); | |
} | |
item.date = ref.publication_date; | |
if (!item.date && ref.publication_years) { | |
item.date = ref.publication_years[ref.publication_years.length - 1]; | |
} | |
if (ref.editions && ref.editions.length > 0 | |
&& ref.editions[0] != "1" | |
&& ref.editions[0].indexOf("1st") != 0 | |
&& ref.editions[0].toLowerCase().indexOf("first") != 0 | |
) { | |
// we don't care about the first edition | |
item.edition = ref.editions[0]; | |
} | |
item.complete(); | |
} | |
} | |
function getAuthors(ref) { | |
var itemAuthors = []; | |
var types = ['authors','corporate_authors']; | |
for (var j=0; j<types.length; j++) { | |
var isCorporate = types[j] != 'authors'; | |
var refAuthors = ref[types[j]]; | |
for (var i = 0; i < refAuthors.length; i++) { | |
var a = refAuthors[i]; | |
if (a.givenname && a.surname) { | |
itemAuthors.push({ | |
firstName: a.givenname, | |
lastName: a.surname, | |
creatorType: "author" | |
}); | |
} | |
else { | |
var name = a.fullname || a.name || ""; | |
if (name == ref.publisher) continue; | |
if (name.length > 0) { | |
if (isCorporate) { | |
itemAuthors.push({ | |
lastName: name, | |
creatorType: "author", | |
fieldMode: 1 | |
}); | |
} | |
else { | |
itemAuthors.push(ZU.cleanAuthor(name, "author", name.indexOf(',') > -1)); | |
} | |
} | |
} | |
} | |
} | |
return itemAuthors; | |
} | |
function getRefType(ref) { | |
switch (ref.content_type) { | |
case "Audio Recording": | |
case "Music Recording": | |
return "audioRecording"; | |
case "Book": | |
case "eBook": | |
return "book"; | |
case "Book Chapter": | |
return "bookSection"; | |
case "Case": | |
return "case"; | |
case "Conference Proceeding": | |
return "conferencePaper"; | |
case "Dissertation": | |
return "thesis"; | |
case "Image": | |
case "Photograph": | |
return "artwork"; | |
case "Magazine": | |
case "Magazine Article": | |
return "magazineArticle"; | |
case "Manuscript": | |
return "manuscript"; | |
case "Map": | |
return "map"; | |
case "Newspaper Article": | |
case "Newspaper": | |
return "newspaperArticle"; | |
break; | |
case "Presentation": | |
return "presentation"; | |
case "Reference": | |
case "Publication Article": | |
return "encyclopediaArticle"; | |
case "Report": | |
case "Technical Report": | |
case "Data Set": | |
case "Market Research": | |
case "Trade Publication Article": | |
case "Paper": | |
return "report"; | |
case "Video Recording": | |
return "videoRecording"; | |
case "Web Resource": | |
return "webpage"; | |
case "Poem": | |
case "Electronic Resource": | |
if (ref.isbn) { | |
return "book"; | |
} | |
return "journalArticle"; | |
case "Journal Article": | |
case "Journal": | |
case "eJournal": | |
case "Book Review": | |
case "Newsletter": | |
case "Archival Material": | |
case "Computer File": | |
case "Course Reading": | |
case "Government Document": | |
case "Kit": | |
case "Microform": | |
case "Music Score": | |
case "Publication": | |
case "Realia": | |
case "Research Guide": | |
case "Special Collection": | |
case "Standard": | |
case "Transcript": | |
default: | |
return "journalArticle"; | |
} | |
} | |
/** BEGIN TEST CASES **/ | |
var testCases = [ | |
{ | |
"type": "web", | |
"url": "http://dartmouth.summon.serialssolutions.com/?#!/search/document?ho=t&l=en&q=buddha&id=FETCHMERGED-dartmouth_catalog_b412227382", | |
"defer": true, | |
"items": [ | |
{ | |
"itemType": "book", | |
"title": "Buddha", | |
"creators": [ | |
{ | |
"firstName": "Osamu", | |
"lastName": "Tezuka", | |
"creatorType": "author" | |
} | |
], | |
"date": "2003", | |
"ISBN": "9781932234442", | |
"language": "English", | |
"libraryCatalog": "Dartmouth College Library, Summon 2.0", | |
"numPages": "8 v.", | |
"place": "New York, N.Y", | |
"publisher": "Vertical", | |
"attachments": [], | |
"notes": [], | |
"seeAlso": [] | |
} | |
] | |
}, | |
{ | |
"type": "web", | |
"url": "http://dartmouth.summon.serialssolutions.com/?#!/search?ho=t&q=buddha&l=en", | |
"defer": true, | |
"items": "multiple" | |
} | |
] | |
/** END TEST CASES **/ |