init
This commit is contained in:
89
backend/lib/anki.js
Normal file
89
backend/lib/anki.js
Normal file
@@ -0,0 +1,89 @@
|
||||
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
|
||||
Reference in New Issue
Block a user