diff --git a/server/core/WebWorker.js b/server/core/WebWorker.js index f0e321f..f01829d 100644 --- a/server/core/WebWorker.js +++ b/server/core/WebWorker.js @@ -469,24 +469,48 @@ class WebWorker { const bookFile = `${this.config.filesDir}/${hash}`; const bookFileInfo = `${bookFile}.info`; - if (!await fs.pathExists(bookFileInfo)) { + const restoreBookInfo = async() => { + const result = {}; + const rows = await db.select({table: 'book', where: `@@id(${db.esc(bookId)})`}); const book = rows[0]; - bookInfo.book = book; - bookInfo.cover = ''; - bookInfo.fb2 = false; + result.book = book; + result.cover = ''; + result.fb2 = false; if (book.ext == 'fb2') { - const {desc, cover} = await this.fb2Parser.getDescAndCover(bookFile); - bookInfo.fb2 = desc; + const {desc, cover, coverExt} = await this.fb2Parser.getDescAndCover(bookFile); + result.fb2 = desc; + + if (cover) { + result.cover = `${this.config.filesPathStatic}/${hash}${coverExt}`; + await fs.writeFile(`${bookFile}${coverExt}`, cover); + } } + return result; + }; + + if (!await fs.pathExists(bookFileInfo)) { + Object.assign(bookInfo, await restoreBookInfo()); await fs.writeFile(bookFileInfo, JSON.stringify(bookInfo, null, 2)); } else { await utils.touchFile(bookFileInfo); - const info = fs.readFile(bookFileInfo, 'utf-8'); - bookInfo = JSON.parse(info); + const info = await fs.readFile(bookFileInfo, 'utf-8'); + const tmpInfo = JSON.parse(info); + + //проверим существование файла обложки, восстановим если нету + let coverFile = ''; + if (tmpInfo.cover) + coverFile = `${this.config.publicFilesDir}${tmpInfo.cover}`; + + if (coverFile && !await fs.pathExists(coverFile)) { + Object.assign(bookInfo, await restoreBookInfo()); + await fs.writeFile(bookFileInfo, JSON.stringify(bookInfo, null, 2)); + } else { + bookInfo = tmpInfo; + } } return {bookInfo}; diff --git a/server/core/fb2/Fb2Parser.js b/server/core/fb2/Fb2Parser.js index c3e1323..3cf2564 100644 --- a/server/core/fb2/Fb2Parser.js +++ b/server/core/fb2/Fb2Parser.js @@ -63,13 +63,39 @@ class Fb2Parser { pickNode: route => route.indexOf('fictionbook/body') !== 0, }); - let cover = null; - //console.log(xml.toString()); - //xml.each(node => console.log(node.name)); - const desc = xml.$$('description').toObject(); + const coverImage = xml.navigator(desc).$('description/title-info/coverpage/image'); - return {desc, cover}; + let cover = null; + let coverExt = ''; + if (coverImage) { + const coverAttrs = coverImage.attrs(); + const href = coverAttrs['l:href']; + let coverType = coverAttrs['content-type']; + coverType = (coverType == 'image/jpg' || coverType == 'application/octet-stream' ? 'image/jpeg' : coverType); + coverExt = (coverType == 'image/png' ? '.png' : '.jpg'); + + if (href) { + const binaryId = (href[0] == '#' ? href.substring(1) : href); + + //найдем нужный image + xml.$$('binary').eachSelf(node => { + let attrs = node.attrs(); + if (!attrs) + return; + attrs = Object.fromEntries(attrs); + + if (attrs.id === binaryId) { + const textNode = new XmlParser(node.value); + const base64 = textNode.$self('*TEXT').value; + + cover = (base64 ? Buffer.from(base64, 'base64') : null); + } + }); + } + } + + return {desc, cover, coverExt}; } }