add tag adder
This commit is contained in:
1 parent
e178881b37
commit
16d1307744
4 files changed
+148
-26
No files matched your search
@@ -0,0 +1,5 @@
|
||||
export interface ILevelLabel {
|
||||
range: string;
|
||||
ja: string;
|
||||
en: string;
|
||||
}
|
||||
+136
@@ -4,6 +4,7 @@ import axios, { AxiosInstance } from 'axios';
|
||||
|
||||
import { soundTag } from './anki';
|
||||
import { AnkiConnect, IAnkiConnectActions } from './ankiconnect';
|
||||
import { ILevelLabel } from './level';
|
||||
import { logger } from './logger';
|
||||
|
||||
export class WaniKani {
|
||||
@@ -18,6 +19,48 @@ export class WaniKani {
|
||||
});
|
||||
}
|
||||
|
||||
static getLevelLabel(level: number): ILevelLabel {
|
||||
if (level < 11) {
|
||||
return {
|
||||
range: '01-10',
|
||||
ja: '快',
|
||||
en: 'PLEASANT',
|
||||
};
|
||||
} else if (level < 21) {
|
||||
return {
|
||||
range: '11-20',
|
||||
ja: '苦',
|
||||
en: 'PAINFUL',
|
||||
};
|
||||
} else if (level < 31) {
|
||||
return {
|
||||
range: '21-30',
|
||||
ja: '死',
|
||||
en: 'DEATH',
|
||||
};
|
||||
} else if (level < 41) {
|
||||
return {
|
||||
range: '31-40',
|
||||
ja: '地獄',
|
||||
en: 'HELL',
|
||||
};
|
||||
} else if (level < 51) {
|
||||
return {
|
||||
range: '41-50',
|
||||
ja: '天国',
|
||||
en: 'PARADISE',
|
||||
};
|
||||
} else if (level < 61) {
|
||||
return {
|
||||
range: '51-60',
|
||||
ja: '現実',
|
||||
en: 'REALITY',
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`invalid level: ${level}`);
|
||||
}
|
||||
|
||||
async subjects({
|
||||
force,
|
||||
}: {
|
||||
@@ -239,6 +282,99 @@ export class WaniKani {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async addTags(
|
||||
query: string,
|
||||
fields: {
|
||||
ja: string;
|
||||
},
|
||||
) {
|
||||
const subjects = await this.subjects();
|
||||
|
||||
const vocabularies = subjects.filter(
|
||||
(s) => s.object === 'vocabulary',
|
||||
) as IVocabulary[];
|
||||
const vocabMap = new Map<
|
||||
string,
|
||||
{
|
||||
level: number;
|
||||
label: ILevelLabel;
|
||||
}
|
||||
>();
|
||||
vocabularies.map((v) => {
|
||||
if (vocabMap.has(v.data.characters)) return;
|
||||
vocabMap.set(v.data.characters, {
|
||||
level: v.data.level,
|
||||
label: WaniKani.getLevelLabel(v.data.level),
|
||||
});
|
||||
});
|
||||
if (!vocabMap.size) return;
|
||||
|
||||
query += ` -${fields.ja}:`;
|
||||
|
||||
const anki = new AnkiConnect();
|
||||
anki
|
||||
.api('findNotes', {
|
||||
query,
|
||||
})
|
||||
.then((notes) => anki.api('notesInfo', { notes }))
|
||||
.then(async (notes) => {
|
||||
const notesToUpdate: {
|
||||
id: SubjectID;
|
||||
tags: string[];
|
||||
}[] = [];
|
||||
|
||||
for (const n of notes) {
|
||||
const { value: ja } = n.fields[fields.ja] || {};
|
||||
if (ja) {
|
||||
const vocab = vocabMap.get(
|
||||
ja.replace(/\[.+?\]/g, '').replace(/ /g, ''),
|
||||
);
|
||||
if (vocab) {
|
||||
notesToUpdate.push({
|
||||
id: n.noteId,
|
||||
tags: [
|
||||
'wanikani',
|
||||
`level-${vocab.level}`,
|
||||
`wanikani-level-${vocab.level}`,
|
||||
`wanikani-level-${vocab.label.range}-${vocab.label.ja}`,
|
||||
`wanikani-level-${
|
||||
vocab.label.range
|
||||
}-${vocab.label.en.toLocaleLowerCase()}`,
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!notesToUpdate.length) return;
|
||||
|
||||
const addTagsMap = new Map<
|
||||
string,
|
||||
{
|
||||
notes: SubjectID[];
|
||||
tags: string;
|
||||
}
|
||||
>();
|
||||
|
||||
notesToUpdate.map(({ id, tags }) => {
|
||||
const identifier = JSON.stringify(tags);
|
||||
const v = addTagsMap.get(identifier) || {
|
||||
notes: [],
|
||||
tags: tags.join(' '),
|
||||
};
|
||||
v.notes.push(id);
|
||||
addTagsMap.set(identifier, v);
|
||||
});
|
||||
|
||||
await anki.multi<'addTags'[]>({
|
||||
actions: Array.from(addTagsMap.values()).map((params) => ({
|
||||
action: 'addTags',
|
||||
params,
|
||||
})),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
type WaniKaniDate = string;
|
||||
|
||||
Reference in new issue
Block a user