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