diff --git a/src/crossref.js b/src/crossref.js index 9c9f2e3f..81bed1b1 100644 --- a/src/crossref.js +++ b/src/crossref.js @@ -1,6 +1,69 @@ +import Wikicite, { debug } from './wikicite'; +import Citation from './citation'; +import Progress from './progress'; +/* global Services */ /* global Zotero */ +/* global window */ export default class Crossref{ + + /** + * Sync source item citations with Wikidata. + * @param {SourceItemWrapper[]} sourceItems - One or more source items to sync citations for. + */ + static async addCrossrefCitationsToItems(sourceItems){ + + const sourceItemsWithDOI = sourceItems.filter((sourceItem) => sourceItem.getPID('DOI')); + + if (sourceItemsWithDOI.length == 0){ + Services.prompt.alert( + window, + Wikicite.getString('wikicite.crossref.get-citations.no-doi-title'), + Wikicite.getString('wikicite.crossref.get-citations.no-doi-message') + ); + return; + } + else if(sourceItemsWithDOI.length < sourceItems.length){ + const confirmed = Services.prompt.confirm( + window, + 'Some items do not have DOIs', // Wikicite.getString('wikicite.crossref.get-citations.no-doi-title'), + 'Get CrossRef citations for items with DOIs?'// Wikicite.getString('wikicite.crossref.get-citations.no-doi-message') + ); + if (!confirmed){ + return; + } + } + + const progress = new Progress( + 'loading', + Wikicite.getString('wikicite.crossref.get-citations.loading') + ); + + try{ + // fix: this await is broken by an error + await Promise.allSettled(sourceItemsWithDOI.forEach(async (sourceItem) => { + const newCitedItems = await Crossref.getCitations(sourceItem.doi); + if (newCitedItems.length > 0){ + const newCitations = newCitedItems.map((newItem) => new Citation({item: newItem, ocis: []}, sourceItem)); + sourceItem.addCitations(newCitations); + } + })); + } + catch (error){ + progress.updateLine( + 'error', + Wikicite.getString('wikicite.crossref.get-citations.none') + ); + debug(error); + return; + } + + progress.updateLine( + 'done', + Wikicite.getString('wikicite.crossref.get-citations.done') + ); + } + static async getCitations(doi) { const JSONResponse = await Crossref.getDOI(doi); @@ -14,7 +77,7 @@ export default class Crossref{ return parsedReferences.filter(Boolean); } else{ - Zotero.debug("Item found in Crossref but doesn't contain any references"); + debug("Item found in Crossref but doesn't contain any references"); } } return []; @@ -44,7 +107,7 @@ export default class Crossref{ // set libraryID to false so we don't save this item in the Zotero library jsonItems = await translation.translate({libraryID: false}); } catch { - Zotero.debug('No items returned for identifier ' + identifier); + debug('No items returned for identifier ' + identifier); } if (jsonItems) { @@ -70,11 +133,11 @@ export default class Crossref{ } else if(crossrefItem.unstructured){ // todo: Implement reference text parsing here - Zotero.debug("Couldn't parse Crossref reference - unstructured references are not yet supported. " + JSON.stringify(crossrefItem)); + debug("Couldn't parse Crossref reference - unstructured references are not yet supported. " + JSON.stringify(crossrefItem)); return null; } else{ - Zotero.debug("Couldn't determine type of Crossref reference - doesn't contain `journal-title` or `volume-title` field. " + JSON.stringify(crossrefItem)); + debug("Couldn't determine type of Crossref reference - doesn't contain `journal-title` or `volume-title` field. " + JSON.stringify(crossrefItem)); return null; } jsonItem.date = crossrefItem.year; @@ -105,7 +168,7 @@ export default class Crossref{ JSONResponse = JSON.parse(response.responseText); } catch { - Zotero.debug("Couldn't access URL: " + url); + debug("Couldn't access URL: " + url); } return JSONResponse; diff --git a/src/sourceItemWrapper.js b/src/sourceItemWrapper.js index 04bb3969..ebe9e380 100644 --- a/src/sourceItemWrapper.js +++ b/src/sourceItemWrapper.js @@ -430,36 +430,8 @@ class SourceItemWrapper extends ItemWrapper { // if provided, sync to wikidata, export to croci, etc, only for that citation // if not, do it for all - async getFromCrossref() { - if (this.doi){ - const progress = new Progress( - 'loading', - Wikicite.getString('wikicite.crossref.get-citations.loading') - ); - const newCitedItems = await Crossref.getCitations(this.doi); - if (newCitedItems.length > 0){ - const newCitations = newCitedItems.map((newItem) => new Citation({item: newItem, ocis: []}, this)); - this.addCitations(newCitations); - progress.updateLine( - 'done', - Wikicite.getString('wikicite.crossref.get-citations.done') - ); - } - else{ - progress.updateLine( - 'error', - Wikicite.getString('wikicite.crossref.get-citations.none') - ); - } - } - else{ - // Should never be called because the menu option is only enabled when the item has a DOI - Services.prompt.alert( - window, - Wikicite.getString('wikicite.crossref.get-citations.no-doi-title'), - Wikicite.getString('wikicite.crossref.get-citations.no-doi-message') - ); - } + getFromCrossref() { + Crossref.addCrossrefCitationsToItems([this]); } getFromOcc() { diff --git a/src/zoteroOverlay.jsx b/src/zoteroOverlay.jsx index f6d5a7f1..6c03be0d 100644 --- a/src/zoteroOverlay.jsx +++ b/src/zoteroOverlay.jsx @@ -1,4 +1,5 @@ import Wikicite, { debug } from './wikicite'; +import Citation from './citation'; import Citations from './citations'; import CitationsBoxContainer from './containers/citationsBoxContainer'; import Crossref from './crossref'; @@ -264,12 +265,15 @@ const zoteroOverlay = { } }, - getFromCrossref: function(menuName) { + getFromCrossref: async function(menuName) { // get items selected // filter items with doi // generate batch call to crossref // only add items not available locally yet - Crossref.getCitations(); + const items = await this.getSelectedItems(menuName, true); + if (items.length){ + Crossref.addCrossrefCitationsToItems(items); + } }, getFromOCC: function(menuName) { @@ -729,7 +733,7 @@ const zoteroOverlay = { doc.getElementById('citation-menu-fetch-qid').disabled = false; doc.getElementById('citation-menu-file-export').disabled = false; doc.getElementById('citation-menu-croci-export').disabled = !sourceItem.doi || !targetItem.doi; - doc.getElementById('citation-menu-oci-crossref').disabled = !ociSuppliers.includes('crossref'); + doc.getElementById('citation-menu-oci-crossref').disabled = !sourceItem.doi || !ociSuppliers.includes('crossref'); doc.getElementById('citation-menu-oci-occ').disabled = !ociSuppliers.includes('occ'); doc.getElementById('citation-menu-oci-wikidata').disabled = !ociSuppliers.includes('wikidata'); },