import { soundTag } from '@/anki';
|
|
import { AnkiConnect, IAnkiConnectActions } from '@/ankiconnect';
|
|
import { ISubject, IVocabulary, WaniKani } from '@/wanikani';
|
|
|
|
export async function populateSounds(
|
|
query: string,
|
|
jaField: string,
|
|
audioField: string,
|
|
subjects: ISubject[],
|
|
) {
|
|
const vocabularies = subjects.filter(
|
|
(s) => s.object === 'vocabulary',
|
|
) as IVocabulary[];
|
|
const audioMap = new Map<
|
|
string,
|
|
{
|
|
url: string;
|
|
filename: string;
|
|
}
|
|
>();
|
|
vocabularies.map((v) => {
|
|
if (audioMap.has(v.data.characters)) return;
|
|
const audio = v.data.pronunciation_audios[0];
|
|
if (!audio) return;
|
|
audioMap.set(v.data.characters, {
|
|
url: audio.url,
|
|
filename: `wanikani_${v.data.characters}_${audio.metadata.source_id}${
|
|
audio.content_type === 'audio/ogg' ? '.ogg' : '.mp3'
|
|
}`,
|
|
});
|
|
});
|
|
if (!audioMap.size) return;
|
|
|
|
query += ` -${jaField}: ${audioField}:`;
|
|
|
|
const anki = new AnkiConnect();
|
|
anki
|
|
.api('findNotes', {
|
|
query,
|
|
})
|
|
.then((notes) => anki.api('notesInfo', { notes }))
|
|
.then(async (notes) => {
|
|
const notesToUpdate: IAnkiConnectActions['updateNoteFields']['params']['note'][] =
|
|
[];
|
|
|
|
for (const n of notes) {
|
|
const { value: ja } = n.fields[jaField] || {};
|
|
if (ja) {
|
|
const audio = audioMap.get(
|
|
ja.replace(/\[.+?\]/g, '').replace(/ /g, ''),
|
|
);
|
|
if (audio) {
|
|
notesToUpdate.push({
|
|
id: n.noteId,
|
|
fields: {
|
|
[audioField]: soundTag.add(audio.filename),
|
|
},
|
|
audio: [
|
|
{
|
|
url: audio.url,
|
|
filename: audio.filename,
|
|
fields: [audioField],
|
|
},
|
|
],
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!notesToUpdate.length) return;
|
|
|
|
while (notesToUpdate.length) {
|
|
await anki.multi<'updateNoteFields'[]>({
|
|
actions: notesToUpdate.splice(0, 100).map((note) => ({
|
|
action: 'updateNoteFields',
|
|
params: {
|
|
note,
|
|
},
|
|
})),
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
if (require.main === module) {
|
|
new WaniKani().subjects().then((subjects) => {
|
|
populateSounds('note:jp.takoboto', 'Japanese', 'JapaneseAudio', subjects);
|
|
});
|
|
}
|