zotero-categorise
Version:
A command-line tool to manage Zotero collections by placing items into specific collections based on their title, description, and tags.
156 lines (136 loc) • 4.43 kB
text/typescript
import fs from 'fs';
import { collection } from './collection';
import Zotero from 'zotero-lib';
import { ZoteroItem, addItemToCollection } from './addItemToCollection';
type Subcollections = {
collection_name: string;
collection: string;
terms: { term: string; description: string; type: string }[];
};
type ResCollection = {
collections?: Subcollections[];
source_collection: string;
source_collection_name?: string;
};
type ResList = {
library: string;
source_collections: ResCollection[];
addtag: string[];
ignoretag: string[];
};
type CommanderOptions = {
item: string[];
itemsfromcollection: string;
itemswithtag: string;
itemswithouttag: string;
itemsfromlibrary: boolean;
collection: string[];
group: string;
test: boolean;
name: string;
json?: string;
ignoretag?: string[];
addtag?: string[];
};
type ZoteroCollections = {
terms: { term: string; type: string }[];
collection: string;
collection_name: string;
situation: string;
}[];
// this function is used to categorize items from a JSON file into Zotero collections
async function generateByJSon(commanderOptions: CommanderOptions) {
// check if the user provided a json file
if (!commanderOptions.json) {
console.log('Please provide a json file');
return;
}
const { itemsfromcollection, itemswithtag, itemswithouttag, itemsfromlibrary } = commanderOptions;
const itemOptions = [commanderOptions.item, itemsfromcollection, itemswithtag, itemswithouttag, itemsfromlibrary];
if (itemOptions.filter(Boolean).length > 1) {
console.log('Only one of these options should be used at a time:');
console.log('--item');
console.log('--itemsfromcollection');
console.log('--itemswithtag');
console.log('--itemswithouttag');
console.log('--itemsfromlibrary');
return;
}
const groupid = commanderOptions.group;
let zotero;
if (groupid) {
zotero = new Zotero({ verbose: false, 'group-id': groupid });
} else {
zotero = new Zotero({ verbose: false });
}
let items: (string | ZoteroItem)[] = commanderOptions.item;
let fetched: { data: ZoteroItem }[] = [];
if (itemsfromcollection) {
fetched = await zotero.items({ collection: itemsfromcollection });
} else if (itemswithtag) {
fetched = await zotero.items({ filter: { tag: itemswithtag } });
} else if (itemswithouttag) {
fetched = await zotero.items({ filter: { tag: `-${itemswithouttag}` } });
} else if (itemsfromlibrary) {
fetched = await zotero.items({});
}
if (fetched.length) {
items = fetched.map((item) => item.data);
}
if (!items || !items.length) {
console.log('No items to process');
return;
}
const jsonFile = commanderOptions.json;
const data = fs.readFileSync(jsonFile, 'utf8');
const json: ResList = JSON.parse(data);
if (!json.source_collections) {
console.log('Please provide a json file with collections');
return;
}
if (commanderOptions.ignoretag) {
json.ignoretag = [...(json.ignoretag || []), ...commanderOptions.ignoretag];
}
if (commanderOptions.addtag) {
json.addtag = [...(json.addtag || []), ...commanderOptions.addtag];
}
const testmode = commanderOptions.test;
const resultcollcections: ZoteroCollections = [];
// get the collections from the json file
// make a list of collections with their terms,name and situation
for (const element of json.source_collections) {
if (!element.collections) continue;
for (const collle of element.collections) {
const termsList: { term: string; type: string }[] = [];
for (const term of collle.terms) {
termsList.push({ term: term.term, type: term.type });
}
resultcollcections.push({
terms: termsList,
collection: collle.collection,
collection_name: collle.collection_name,
situation: 'nothing',
});
}
}
let FinalOutput = '';
// add the items to the collections for each item
for (const item of items) {
const id = typeof item === 'string' ? item : item.key;
FinalOutput += '\n\nItem ' + id + ' :\n';
FinalOutput = await addItemToCollection(
item,
zotero,
resultcollcections,
testmode,
FinalOutput,
json.ignoretag,
json.addtag
);
for (const element of resultcollcections) {
element.situation = 'nothing';
}
}
console.log(FinalOutput);
}
export { generateByJSon };