Extra contents beyond WaniKani
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

82 lines
2.3 KiB

import { AnkiConnect } from '@/ankiconnect';
const DECK = 'Takoboto';
async function main() {
const anki = new AnkiConnect();
console.log(
await anki
.api('findCards', {
query: `deck:${DECK}`,
})
.then((cards) => anki.api('cardsInfo', { cards }))
.then((rs) => {
const modelToSubdecks = new Map<
string,
{
[subdeck: string]: number[];
}
>();
rs.map((r) => {
const vs = modelToSubdecks.get(r.modelName) || {};
// Get the subdeck names from Kanji
const subdeck = '???';
vs[subdeck] = vs[subdeck] || [];
vs[subdeck]!.push(r.cardId);
modelToSubdecks.set(r.modelName, vs);
});
return Promise.all(
Array.from(modelToSubdecks).map(([modelName, subdecks]) =>
anki.api('modelTemplates', { modelName }).then((templates) =>
Object.entries(subdecks).map(([subdeck, cardIds]) => ({
modelName,
templateNames: Object.keys(templates),
subdeck,
cardIdsSet: new Set(cardIds),
})),
),
),
);
})
.then((rs) => {
const cardsByTemplateName = {
data: new Map<string, number[]>(),
async get(templateName: string) {
let v = this.data.get(templateName);
if (!v) {
v = await anki.api('findCards', {
query: `deck:${DECK} card:${templateName}`,
});
}
this.data.set(templateName, v);
return v;
},
};
return Promise.all(
rs
.flat()
.flatMap((r) =>
r.templateNames.map((templateName) => ({
...r,
templateName,
})),
)
.map(({ templateName, subdeck, cardIdsSet }) =>
cardsByTemplateName.get(templateName).then((cards) =>
anki.api('changeDeck', {
cards: cards.filter((c) => cardIdsSet.has(c)),
deck: `${DECK}::${subdeck}::${templateName}`,
}),
),
),
);
}),
);
}
if (require.main === module) {
main();
}