import { soundTag } from '@/anki'; import { AnkiConnect } from '@/ankiconnect'; export async function listTags( query = 'deck:Takoboto -Takoboto: tag:common -tag:reading-challenge -tag:favorites -tag:death-note -tag:ハピネス -tag:https://www.bunka.go.jp/seisaku/bunkashingikai/kokugo/hokoku/pdf/ijidokun_140221.pdf', ) { const anki = new AnkiConnect(); return anki .api('findNotes', { query, }) .then((notes) => anki.api('notesInfo', { notes })) .then((notes) => { return new Set(notes.flatMap((n) => n.tags)); }); } export async function addSoundTag(query: string, fieldNames: string[]) { query += ' (' + fieldNames.map((f) => `(-${f}: -${f}:[sound:*)`).join(' OR ') + ')'; const anki = new AnkiConnect(); anki .api('findNotes', { query, }) .then((notes) => anki.api('notesInfo', { notes })) .then((notes) => { const notesToUpdate: { id: number; fields: Record; }[] = []; for (const n of notes) { let toUpdate: typeof notesToUpdate[0] | undefined; fieldNames.map((fieldName: string) => { const field = n.fields[fieldName]; if (field) { const { value } = field; if (!soundTag.is(value)) { toUpdate = toUpdate || { id: n.noteId, fields: {} }; toUpdate.fields[fieldName] = soundTag.make(value); } } }); if (toUpdate) { notesToUpdate.push(toUpdate); } } if (!notesToUpdate.length) return; return anki.multi<'updateNoteFields'[]>({ actions: notesToUpdate.map((note) => ({ action: 'updateNoteFields', params: { note, }, })), }); }); } if (require.main === module) { addSoundTag('note:jp.takoboto', ['SentenceAudio', 'JapaneseAudio']); }