const Handler = require("./documentHandler.js").DocumentHandler, assert = require("assert"), AdmZip = require("adm-zip"), Xml2js = require("xml2js"), Canvas = require("canvas"), fs = require("fs"); function EpubHandler(doc) { Handler.call(this, doc); this.data = null; this.loading = null; } EpubHandler.prototype = Object.create(Handler.prototype); EpubHandler.prototype.parseFile = function() { return new Promise(async (res, rej) => { const zip = new AdmZip(this.doc.path), entries = zip.getEntries(), entriesByPath = {}; entries.forEach(i => { entriesByPath[i.entryName] = i; }); if (!entriesByPath["content.opf"]) rej(); Xml2js.parseString(entriesByPath["content.opf"].getData().toString("utf8"), ((err, result) => { if (err) { console.error("Malformed XML data in epub file", err); rej(); } if (!result || !result.package || !result.package.manifest || !result.package.manifest[0] || !result.package.manifest[0].item || !Array.isArray(result.package.manifest[0].item)) { console.error("Cannot read metadata epub file"); rej(); } this.data = {}; for (var i =0, len = result.package.manifest[0].item.length; i < len; ++i) { var item = result.package.manifest[0].item[i]["$"]; if (item && item.id === "cover") { if (!entriesByPath[item.href]) { console.error("Referenced file " +item.href +" not found"); continue; } this.data.cover = entriesByPath[item.href].getData(); break; } } if (!this.data.cover) { console.error("Cannot find cover"); this.data = null; rej(); } res(this.data); }).bind(this)); }); } EpubHandler.prototype.loadDocument = function() { return new Promise(((res, rej) => { if (this.data) { res(this.data); } else { if (this.loading) this.loading = this.loading.then((() => res(this.data)).bind(this)); else this.loading = this.parseFile().then(doc => res(this.data)); } }).bind(this)); } EpubHandler.prototype.getPageCount = function() { return new Promise((res, rej) => res(null)); }; EpubHandler.prototype.getThumbmailViewport = function(fullWidth, fullHeight) { const maxSize = require("../config").thumbmailMaxSize; var ratio = Math.min(maxSize /fullHeight, maxSize /fullWidth); return { height: ratio *fullHeight, width: ratio *fullWidth }; }; EpubHandler.prototype.getCover = function() { return new Promise(async (res, rej) => { const data = await this.loadDocument(), image = new Canvas.Image(); image.src = data.cover; const size = this.getThumbmailViewport(image.width, image.height), canvas = Canvas.createCanvas(size.width, size.height), ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0, size.width, size.height); canvas.toBuffer((err, buf) => res(buf), "image/png"); }); }; EpubHandler.prototype.getPngPage = function(page, isThumbmail) { return new Promise((res, rej) => res(null)); }; module.exports.EpubHandler = EpubHandler;