zotero-categorise
Version:
A command-line tool to manage Zotero collections by placing items into specific collections based on their title, description, and tags.
119 lines (104 loc) • 3.51 kB
text/typescript
import Zotero from 'zotero-lib';
import fs from 'fs';
type CommanderOptions = {
item: string[];
collection: string[];
group: string;
test: boolean;
name: string;
json?: string;
recursive?: boolean;
};
type Options = {
key: string[];
top?: boolean;
verbose?: boolean;
recursive?: boolean;
};
type Collection = {
collection_name: string;
collection: string;
terms: [{ term: string; description: string; type: string }];
};
type ResCollection = {
collections?: Collection[];
source_collection?: string;
source_collection_name?: string;
};
type ResList = {
library?: string;
source_collections?: ResCollection[];
addtag?: string[];
ignoretag?: string[];
};
async function generate(commanderOptions: CommanderOptions) {
let zotero: Zotero;
const groupid = commanderOptions.group;
if (!groupid) {
zotero = new Zotero({ verbose: false });
} else {
zotero = new Zotero({ verbose: false, 'group-id': groupid });
}
if (!commanderOptions.collection) {
console.log('You must provide at least one collection');
return;
}
const list: ResList = {};
list.library = groupid;
list.source_collections = [];
for (const collectionId of commanderOptions.collection) {
const collectionList: ResCollection = {};
collectionList.source_collection_name = '';
collectionList.source_collection = collectionId;
collectionList.collections = [];
const options: Options = {
top: false,
key: [collectionId],
verbose: false,
recursive: commanderOptions.recursive,
};
// fetch the collection
const result: any = await zotero.collection(options);
// check if the collection exists
if (!result || !result.data) {
console.log(`There is no collection with this key ${collectionId}`);
continue;
}
collectionList.source_collection_name = result.data.name;
if (list.library === undefined) list.library = result.library.id;
// fetch the subcollections
const results: any = await zotero.collections(options);
// fs.writeFileSync('collection.json', JSON.stringify(results));
async function addChildren(collection: Collection[], parent: any) {
for (const child of parent.children) {
// console.log('child name', child.data.name);
collection.push({
collection_name: child.data.name,
collection: `zotero://select/groups/${list.library}/collections/${child.key}`,
terms: [{ term: child.data.name, description: 'main', type: 'word' }],
});
if (child.children.length > 0) {
addChildren(collection, child);
}
}
}
// make a list of the subcollections with the collection name, the collection key and the terms
for (const collectionkey of results) {
collectionList.collections.push({
collection_name: collectionkey.data.name,
collection: `zotero://select/groups/${list.library}/collections/${collectionkey.key}`,
terms: [{ term: collectionkey.data.name, description: 'main', type: 'word' }],
});
if (commanderOptions.recursive && collectionkey.children?.length > 0) {
await addChildren(collectionList.collections, collectionkey);
}
console.log(collectionkey.data);
}
list.source_collections.push(collectionList);
}
list.ignoretag = [];
list.addtag = [];
const filename = commanderOptions.name;
fs.writeFileSync(filename, JSON.stringify(list));
}
export { generate, CommanderOptions };