UNPKG

zotero-categorise

Version:

A command-line tool to manage Zotero collections by placing items into specific collections based on their title, description, and tags.

137 lines (126 loc) 4.86 kB
import Zotero from 'zotero-lib'; export type ZoteroItem = { key: string; title: string; abstractNote: string; tags: [{ tag: string }]; collections: string[]; }; type ZoteroCollections = { terms: { term: string; type: string }[]; collection: string; collection_name: string; situation: string; }[]; function getCollectionLetters(collection: string) { if (collection.includes('/')) { const words = collection.split('/'); return words[words.length - 1]; } return collection; } async function addItemToCollection( item: string | ZoteroItem, zotero: Zotero, listCollections: ZoteroCollections, testmode: boolean, FinalOutput: string, ignoretag: string[], addtag?: string[] ) { let result: ZoteroItem; let itemId = typeof item === 'string' ? item : item.key; try { if (typeof item === 'string') { result = await zotero.item({ key: item }); } else { result = item; } for (const ignore of ignoretag) { for (const elTag of result.tags) { if (elTag.tag.toLowerCase() === ignore.toLowerCase()) { FinalOutput += 'Item ' + itemId + ' has the tag "' + ignore + '" so it will be ignored' + '\n'; console.log('Item ' + itemId + ' has the tag "' + ignore + '" so it will be ignored'); return FinalOutput; } } } if (addtag?.length) { for (const ell of addtag) { result.tags.push({ tag: ell }); } await zotero.update_item({ key: itemId, json: { tags: result.tags }, verbose: false, }); FinalOutput += 'Add tag ' + addtag + ' to item ' + itemId + '\n'; console.log('Add tag ' + addtag + ' to item ' + itemId); } FinalOutput += 'Get item data :' + itemId + '\n'; console.log('Get item data :' + itemId); if (!result) throw new Error('not found'); // check if the item is already in the collection for (const el of listCollections) { if (!result.collections) el.situation = 'is_attachment'; else if (result.collections.includes(getCollectionLetters(el.collection))) el.situation = 'already_exist'; } const alreadyCollections = listCollections.filter( (item: { situation: string }) => item.situation === 'already_exist' || item.situation === 'is_attachment' ); const alreadyCollectionsFiltered = alreadyCollections.map((item) => getCollectionLetters(item.collection)); FinalOutput += `Subcollections that already have the item ${itemId}: ` + JSON.stringify(alreadyCollectionsFiltered) + '\n'; console.log(`Subcollections that already have the item ${itemId}: ` + JSON.stringify(alreadyCollectionsFiltered)); // get the item data and check if it contains the terms of the sub collections for (const element of listCollections) { if (element.situation === 'already_exist') continue; for (const term of element.terms) { let searchFor: RegExp; if (term.type === 'word') searchFor = new RegExp('\\b' + term.term + '\\b', 'i'); // \b is for word boundary else if (term.type === 'regex') searchFor = new RegExp(term.term, 'i'); else if (term.type === 'words') { // make the regex for the words const parts = term.term.split('/'); const regex = parts[0] + '(?:' + parts.slice(1).join('|') + '?)'; searchFor = new RegExp('\\b' + regex + '\\b', 'i'); } else searchFor = new RegExp('\\b' + term.term + '\\b', 'i'); const resultIncludes = searchFor.test(result.title) || searchFor.test(result.abstractNote) || (result.tags && result.tags.some((tag) => searchFor.test(tag.tag))); if (resultIncludes) { element.situation = 'to_add'; break; } } } } catch (error) { console.log(`error happend when retreving ${itemId}`); process.exit(0); } // get the sub collections that will have the item const targetCollections = listCollections.filter((item: { situation: string }) => item.situation === 'to_add'); const targetCollectionsFiltered = targetCollections.map((item) => getCollectionLetters(item.collection)); FinalOutput += 'Collections where item ' + itemId + ' will be added: ' + JSON.stringify(targetCollectionsFiltered) + '\n'; console.log('Collections where item ' + itemId + ' will be added: ' + JSON.stringify(targetCollectionsFiltered)); if (testmode) { return FinalOutput; } // add the item to the sub collections if (targetCollectionsFiltered.length) { try { await zotero.item({ key: itemId, addtocollection: targetCollectionsFiltered, verbose: false, }); } catch (error) { console.log(`error happend when retreving ${itemId}`); process.exit(0); } } return FinalOutput; } export { addItemToCollection };