UNPKG

anki-apkg-export

Version:

Generate decks for Anki (spaced repetition software)

269 lines (235 loc) 8.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLastItem = exports["default"] = void 0; var _sha = _interopRequireDefault(require("sha1")); var _jszip = _interopRequireDefault(require("jszip")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var _default = /*#__PURE__*/ function () { function _default(deckName, _ref) { var template = _ref.template, sql = _ref.sql; _classCallCheck(this, _default); this.db = new sql.Database(); this.db.run(template); var now = Date.now(); var topDeckId = this._getId('cards', 'did', now); var topModelId = this._getId('notes', 'mid', now); this.deckName = deckName; this.zip = new _jszip["default"](); this.media = []; this.topDeckId = topDeckId; this.topModelId = topModelId; this.separator = "\x1F"; var decks = this._getInitialRowValue('col', 'decks'); var deck = getLastItem(decks); deck.name = this.deckName; deck.id = topDeckId; decks[topDeckId + ''] = deck; this._update('update col set decks=:decks where id=1', { ':decks': JSON.stringify(decks) }); var models = this._getInitialRowValue('col', 'models'); var model = getLastItem(models); model.name = this.deckName; model.did = this.topDeckId; model.id = topModelId; models["".concat(topModelId)] = model; this._update('update col set models=:models where id=1', { ':models': JSON.stringify(models) }); } _createClass(_default, [{ key: "save", value: function save(options) { var zip = this.zip, db = this.db, media = this.media; var binaryArray = db["export"](); var mediaObj = media.reduce(function (prev, curr, idx) { prev[idx] = curr.filename; return prev; }, {}); zip.file('collection.anki2', new Buffer(binaryArray)); zip.file('media', JSON.stringify(mediaObj)); media.forEach(function (item, i) { return zip.file(i, item.data); }); if (process.env.APP_ENV === 'browser' || typeof window !== 'undefined') { return zip.generateAsync(Object.assign({}, { type: 'blob' }, options)); } else { return zip.generateAsync(Object.assign({}, { type: 'nodebuffer', base64: false, compression: 'DEFLATE' }, options)); } } }, { key: "addMedia", value: function addMedia(filename, data) { this.media.push({ filename: filename, data: data }); } }, { key: "addCard", value: function addCard(front, back) { var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, tags = _ref2.tags; var topDeckId = this.topDeckId, topModelId = this.topModelId, separator = this.separator; var now = Date.now(); var note_guid = this._getNoteGuid(topDeckId, front, back); var note_id = this._getNoteId(note_guid, now); var strTags = ''; if (typeof tags === 'string') { strTags = tags; } else if (Array.isArray(tags)) { strTags = this._tagsToStr(tags); } this._update('insert or replace into notes values(:id,:guid,:mid,:mod,:usn,:tags,:flds,:sfld,:csum,:flags,:data)', { ':id': note_id, // integer primary key, ':guid': note_guid, // text not null, ':mid': topModelId, // integer not null, ':mod': this._getId('notes', 'mod', now), // integer not null, ':usn': -1, // integer not null, ':tags': strTags, // text not null, ':flds': front + separator + back, // text not null, ':sfld': front, // integer not null, ':csum': this._checksum(front + separator + back), //integer not null, ':flags': 0, // integer not null, ':data': '' // text not null, }); return this._update('insert or replace into cards values(:id,:nid,:did,:ord,:mod,:usn,:type,:queue,:due,:ivl,:factor,:reps,:lapses,:left,:odue,:odid,:flags,:data)', { ':id': this._getCardId(note_id, now), // integer primary key, ':nid': note_id, // integer not null, ':did': topDeckId, // integer not null, ':ord': 0, // integer not null, ':mod': this._getId('cards', 'mod', now), // integer not null, ':usn': -1, // integer not null, ':type': 0, // integer not null, ':queue': 0, // integer not null, ':due': 179, // integer not null, ':ivl': 0, // integer not null, ':factor': 0, // integer not null, ':reps': 0, // integer not null, ':lapses': 0, // integer not null, ':left': 0, // integer not null, ':odue': 0, // integer not null, ':odid': 0, // integer not null, ':flags': 0, // integer not null, ':data': '' // text not null }); } }, { key: "_update", value: function _update(query, obj) { this.db.prepare(query).getAsObject(obj); } }, { key: "_getInitialRowValue", value: function _getInitialRowValue(table) { var column = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'id'; var query = "select ".concat(column, " from ").concat(table); return this._getFirstVal(query); } }, { key: "_checksum", value: function _checksum(str) { return parseInt((0, _sha["default"])(str).substr(0, 8), 16); } }, { key: "_getFirstVal", value: function _getFirstVal(query) { return JSON.parse(this.db.exec(query)[0].values[0]); } }, { key: "_tagsToStr", value: function _tagsToStr() { var tags = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return ' ' + tags.map(function (tag) { return tag.replace(/ /g, '_'); }).join(' ') + ' '; } }, { key: "_getId", value: function _getId(table, col, ts) { var query = "SELECT ".concat(col, " from ").concat(table, " WHERE ").concat(col, " >= :ts ORDER BY ").concat(col, " DESC LIMIT 1"); var rowObj = this.db.prepare(query).getAsObject({ ':ts': ts }); return rowObj[col] ? +rowObj[col] + 1 : ts; } }, { key: "_getNoteId", value: function _getNoteId(guid, ts) { var query = "SELECT id from notes WHERE guid = :guid ORDER BY id DESC LIMIT 1"; var rowObj = this.db.prepare(query).getAsObject({ ':guid': guid }); return rowObj.id || this._getId('notes', 'id', ts); } }, { key: "_getNoteGuid", value: function _getNoteGuid(topDeckId, front, back) { return (0, _sha["default"])("".concat(topDeckId).concat(front).concat(back)); } }, { key: "_getCardId", value: function _getCardId(note_id, ts) { var query = "SELECT id from cards WHERE nid = :note_id ORDER BY id DESC LIMIT 1"; var rowObj = this.db.prepare(query).getAsObject({ ':note_id': note_id }); return rowObj.id || this._getId('cards', 'id', ts); } }]); return _default; }(); exports["default"] = _default; var getLastItem = function getLastItem(obj) { var keys = Object.keys(obj); var lastKey = keys[keys.length - 1]; var item = obj[lastKey]; delete obj[lastKey]; return item; }; exports.getLastItem = getLastItem;