90 lines
2.3 KiB
JavaScript
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
|