prototype subdeck from Kanji
This commit is contained in:
1 parent
f427a8e148
commit
13f2bb421c
4 files changed
+80
-16
No files matched your search
+52
-15
@@ -1,4 +1,4 @@
|
|||||||
import { AnkiConnect } from '@/ankiconnect';
|
import { AnkiConnect, IAnkiConnectActions } from '@/ankiconnect';
|
||||||
|
|
||||||
import { makeKanjiLevels } from './get-kanji-level';
|
import { makeKanjiLevels } from './get-kanji-level';
|
||||||
|
|
||||||
@@ -8,7 +8,10 @@ const KANJI_FIELD = 'Japanese';
|
|||||||
async function main() {
|
async function main() {
|
||||||
const anki = new AnkiConnect();
|
const anki = new AnkiConnect();
|
||||||
|
|
||||||
console.log(
|
const deckConfig = await anki.api('getDeckConfig', {
|
||||||
|
deck: DECK,
|
||||||
|
});
|
||||||
|
|
||||||
await anki
|
await anki
|
||||||
.api('findCards', {
|
.api('findCards', {
|
||||||
query: `deck:${DECK}`,
|
query: `deck:${DECK}`,
|
||||||
@@ -62,7 +65,11 @@ async function main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.then((rs) => {
|
.then(async (rs) => {
|
||||||
|
const remaining: {
|
||||||
|
[templateName: string]: Set<number>;
|
||||||
|
} = {};
|
||||||
|
|
||||||
const cardsByTemplateName = {
|
const cardsByTemplateName = {
|
||||||
data: new Map<string, number[]>(),
|
data: new Map<string, number[]>(),
|
||||||
async get(templateName: string) {
|
async get(templateName: string) {
|
||||||
@@ -71,34 +78,64 @@ async function main() {
|
|||||||
v = await anki.api('findCards', {
|
v = await anki.api('findCards', {
|
||||||
query: `deck:${DECK} card:${templateName}`,
|
query: `deck:${DECK} card:${templateName}`,
|
||||||
});
|
});
|
||||||
|
remaining[templateName] = new Set(v);
|
||||||
}
|
}
|
||||||
this.data.set(templateName, v);
|
this.data.set(templateName, v);
|
||||||
return v;
|
return v;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return Promise.all(
|
const toChangeDeck: IAnkiConnectActions['changeDeck']['params'][] = [];
|
||||||
rs
|
|
||||||
|
for (const { templateName, subdeck, cardIdsSet } of rs
|
||||||
.flat()
|
.flat()
|
||||||
.flatMap((r) =>
|
.flatMap((r) =>
|
||||||
r.templateNames.map((templateName) => ({
|
r.templateNames.map((templateName) => ({
|
||||||
...r,
|
...r,
|
||||||
templateName,
|
templateName,
|
||||||
})),
|
})),
|
||||||
)
|
)) {
|
||||||
.map(({ templateName, subdeck, cardIdsSet }) =>
|
const cards = await cardsByTemplateName.get(templateName);
|
||||||
cardsByTemplateName.get(templateName).then((cards) =>
|
|
||||||
anki.api('changeDeck', {
|
toChangeDeck.push({
|
||||||
cards: cards.filter((c) => cardIdsSet.has(c)),
|
cards: cards.filter((c) => {
|
||||||
|
const r = remaining[templateName];
|
||||||
|
if (r) {
|
||||||
|
r.delete(c);
|
||||||
|
}
|
||||||
|
return cardIdsSet.has(c);
|
||||||
|
}),
|
||||||
deck: `${DECK}::${subdeck}::${templateName}`,
|
deck: `${DECK}::${subdeck}::${templateName}`,
|
||||||
}),
|
});
|
||||||
),
|
}
|
||||||
),
|
|
||||||
);
|
Object.entries(remaining).map(([templateName, cards]) => {
|
||||||
}),
|
if (cards.size) {
|
||||||
|
toChangeDeck.push({
|
||||||
|
cards: [...cards],
|
||||||
|
deck: `${DECK}::独習::${templateName}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (toChangeDeck.length) {
|
||||||
|
const batchSize = 20;
|
||||||
|
for (let i = 0; i < toChangeDeck.length; i += batchSize) {
|
||||||
|
await Promise.all(
|
||||||
|
toChangeDeck
|
||||||
|
.slice(i, i + batchSize)
|
||||||
|
.map((params) => anki.api('changeDeck', params)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await anki.api('setDeckConfigId', {
|
||||||
|
decks: toChangeDeck.map((r) => r.deck),
|
||||||
|
configId: deckConfig.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
@@ -42,3 +42,7 @@ export interface IAnkiTemplate {
|
|||||||
bqfmt: string;
|
bqfmt: string;
|
||||||
bamt: string;
|
bamt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IAnkiDeckConfig {
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
+19
-1
@@ -1,6 +1,7 @@
|
|||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
|
||||||
import { IAnkiCard, IAnkiQuery } from './anki';
|
import { IAnkiCard, IAnkiDeckConfig, IAnkiQuery } from './anki';
|
||||||
|
import { logger } from './logger';
|
||||||
|
|
||||||
export interface IAnkiConnectActions
|
export interface IAnkiConnectActions
|
||||||
extends Record<
|
extends Record<
|
||||||
@@ -67,6 +68,19 @@ export interface IAnkiConnectActions
|
|||||||
};
|
};
|
||||||
result: null;
|
result: null;
|
||||||
};
|
};
|
||||||
|
getDeckConfig: {
|
||||||
|
params: {
|
||||||
|
deck: string;
|
||||||
|
};
|
||||||
|
result: IAnkiDeckConfig;
|
||||||
|
};
|
||||||
|
setDeckConfigId: {
|
||||||
|
params: {
|
||||||
|
decks: string[];
|
||||||
|
configId: number;
|
||||||
|
};
|
||||||
|
result: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
// Media Actions
|
// Media Actions
|
||||||
storeMediaFile: {
|
storeMediaFile: {
|
||||||
@@ -443,6 +457,8 @@ export class AnkiConnect {
|
|||||||
params: IAnkiConnectActions[A]['params'],
|
params: IAnkiConnectActions[A]['params'],
|
||||||
version = this.version,
|
version = this.version,
|
||||||
): Promise<IAnkiConnectActions[A]['result']> {
|
): Promise<IAnkiConnectActions[A]['result']> {
|
||||||
|
logger(`AnkiConnect: calling ${action}`, params);
|
||||||
|
|
||||||
const { data: response } = await this.$axios.post<{
|
const { data: response } = await this.$axios.post<{
|
||||||
result: any;
|
result: any;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
@@ -461,6 +477,8 @@ export class AnkiConnect {
|
|||||||
throw response.error;
|
throw response.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger(`AnkiConnect: finished ${action}`, params);
|
||||||
|
|
||||||
return response.result;
|
return response.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export function logger(...args: any[]) {
|
||||||
|
if (process.env['DEBUG']) {
|
||||||
|
console.debug(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user