Files
linguamate/backend/lib/anki.js
2026-02-21 08:06:37 -05:00

90 lines
2.3 KiB
JavaScript

import { readFile } from 'fs/promises'
import { open } from 'sqlite'
import sqlite3 from 'sqlite3'
import AdmZip from 'adm-zip'
// database structure: https://github.com/ankidroid/Anki-Android/wiki/Database-Structure
// python example: https://github.com/patarapolw/ankisync2
// old js example: https://github.com/nornagon/mkanki/blob/master/index.js
// to create a zip file
// const zip = new AdmZip()
// zip.addLocalFolder('./folder_to_zip')
// zip.writeZip('./output.zip')
class Deck {
/**
*
* @param info ID of internal deck, or filename or anki export
* @param process whether or not this is an external anki export to process
*/
constructor(info, process) {
// pull out variables
this.notes = null // this is what is edited; may create multiple cards
this.media = null // image and audio files attached to cards/notes
}
/**
* Loads an internal deck
*/
async load(id) {
// open database
// open media files
}
/**
* Processes an anki export for internal use. Currently only supports
* .apkg files. In the future, may support:
* colpkg
* txt (notes)
* txt (cards)
*
* @param filename path of file to process
*/
async process(filename) {
return await this.processApkg(filename)
}
/**
* Processes a .apkg file into a database
*
* @param filename name of file to open and process
*/
async processApkg(filename) {
// error handling
if (!filename) throw new Error('Must specify a .apkg filename')
// setup
let uuid = crypto.randomUUID()
let location = `../data/anki/decks/${uuid}/`
// make the resource folder if it does not exist already
// let resource = ''
// if (!fs.existsSync(resource)) fs.mkdirSync(resource, { recursive: true })
// extract zip
// https://stuk.github.io/jszip/documentation/howto/read_zip.html#in-nodejs
let zip = new AdmZip(filename)
zip.extractAllTo(location, true)
// extract the notes database
let db = await open({
filename: location + 'collection.anki2',
driver: sqlite3.cached.Database
})
let result = await db.get('SELECT sfld FROM notes WHERE id = :n', 1486785585103)
console.log(result);
// extract media files
// ? process/rename media files and update in db?
// load data into this obj
// return { notes, media }
}
}
export default Deck