Работа над BookInfoDialog
This commit is contained in:
@@ -239,7 +239,6 @@ class BookInfoDialog {
|
||||
|
||||
parseBookInfo() {
|
||||
const bookInfo = this.bookInfo;
|
||||
const parser = new Fb2Parser();
|
||||
|
||||
//cover
|
||||
if (bookInfo.cover)
|
||||
@@ -247,16 +246,10 @@ class BookInfoDialog {
|
||||
|
||||
//fb2
|
||||
if (bookInfo.fb2) {
|
||||
this.fb2 = parser.bookInfoList(bookInfo.fb2, {
|
||||
valueToString(value, nodePath, origVTS) {//eslint-disable-line no-unused-vars
|
||||
if (nodePath == 'documentInfo/historyHtml' && value)
|
||||
return value.replace(/<p>/g, `<p class="p-history">`);
|
||||
const parser = new Fb2Parser(bookInfo.fb2);
|
||||
|
||||
return origVTS(value, nodePath);
|
||||
},
|
||||
});
|
||||
|
||||
const infoObj = parser.bookInfo(bookInfo.fb2);
|
||||
const infoObj = parser.bookInfo();
|
||||
console.log(JSON.stringify(infoObj, null, 2));
|
||||
if (infoObj.titleInfo) {
|
||||
let ann = infoObj.titleInfo.annotationHtml;
|
||||
if (ann) {
|
||||
@@ -264,6 +257,15 @@ class BookInfoDialog {
|
||||
this.annotation = ann;
|
||||
}
|
||||
}
|
||||
|
||||
this.fb2 = parser.bookInfoList(infoObj, {
|
||||
valueToString(value, nodePath, origVTS) {//eslint-disable-line no-unused-vars
|
||||
if (nodePath == 'documentInfo/historyHtml' && value)
|
||||
return value.replace(/<p>/g, `<p class="p-history">`);
|
||||
|
||||
return origVTS(value, nodePath);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//book
|
||||
|
||||
@@ -369,7 +369,7 @@ class WebWorker {
|
||||
|
||||
const link = `${this.config.filesPathStatic}/${hash}`;
|
||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
||||
const bookFileDesc = `${bookFile}.json`;
|
||||
const bookFileDesc = `${bookFile}.d.json`;
|
||||
|
||||
if (!await fs.pathExists(bookFile) || !await fs.pathExists(bookFileDesc)) {
|
||||
if (!await fs.pathExists(bookFile) && extractedFile) {
|
||||
@@ -435,7 +435,7 @@ class WebWorker {
|
||||
if (rows.length) {//хеш найден по bookPath
|
||||
const hash = rows[0].hash;
|
||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
||||
const bookFileDesc = `${bookFile}.json`;
|
||||
const bookFileDesc = `${bookFile}.d.json`;
|
||||
|
||||
if (await fs.pathExists(bookFile) && await fs.pathExists(bookFileDesc)) {
|
||||
link = `${this.config.filesPathStatic}/${hash}`;
|
||||
@@ -467,9 +467,9 @@ class WebWorker {
|
||||
let bookInfo = await this.getBookLink(bookId);
|
||||
const hash = path.basename(bookInfo.link);
|
||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
||||
const bookFileInfo = `${bookFile}.info`;
|
||||
const bookFileInfo = `${bookFile}.i.json`;
|
||||
|
||||
const restoreBookInfo = async() => {
|
||||
const restoreBookInfo = async(info) => {
|
||||
const result = {};
|
||||
|
||||
const rows = await db.select({table: 'book', where: `@@id(${db.esc(bookId)})`});
|
||||
@@ -478,10 +478,12 @@ class WebWorker {
|
||||
result.book = book;
|
||||
result.cover = '';
|
||||
result.fb2 = false;
|
||||
let parser = null;
|
||||
|
||||
if (book.ext == 'fb2') {
|
||||
const {fb2, cover, coverExt} = await this.fb2Helper.getDescAndCover(bookFile);
|
||||
result.fb2 = fb2;
|
||||
parser = fb2;
|
||||
result.fb2 = fb2.rawNodes;
|
||||
|
||||
if (cover) {
|
||||
result.cover = `${this.config.filesPathStatic}/${hash}${coverExt}`;
|
||||
@@ -489,12 +491,16 @@ class WebWorker {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
Object.assign(info ,result);
|
||||
await fs.writeFile(bookFileInfo, JSON.stringify(info));
|
||||
|
||||
if (this.config.branch === 'development') {
|
||||
await fs.writeFile(`${bookFile}.dev`, `${JSON.stringify(info, null, 2)}\n\n${parser ? parser.toString({format: true}) : ''}`);
|
||||
}
|
||||
};
|
||||
|
||||
if (!await fs.pathExists(bookFileInfo)) {
|
||||
Object.assign(bookInfo, await restoreBookInfo());
|
||||
await fs.writeFile(bookFileInfo, JSON.stringify(bookInfo, null, 2));
|
||||
await restoreBookInfo(bookInfo);
|
||||
} else {
|
||||
await utils.touchFile(bookFileInfo);
|
||||
const info = await fs.readFile(bookFileInfo, 'utf-8');
|
||||
@@ -506,8 +512,7 @@ class WebWorker {
|
||||
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));
|
||||
await restoreBookInfo(bookInfo);
|
||||
} else {
|
||||
bookInfo = tmpInfo;
|
||||
}
|
||||
|
||||
@@ -63,12 +63,11 @@ class Fb2Helper {
|
||||
pickNode: route => route.indexOf('fictionbook/body') !== 0,
|
||||
});
|
||||
|
||||
const desc = parser.$$('description').toObject();
|
||||
const coverImage = parser.inspector(desc).$('description/title-info/coverpage/image');
|
||||
const coverImage = parser.$$('/description/title-info/coverpage/image');
|
||||
|
||||
let cover = null;
|
||||
let coverExt = '';
|
||||
if (coverImage) {
|
||||
if (coverImage.count) {
|
||||
const coverAttrs = coverImage.attrs();
|
||||
const href = coverAttrs[`${parser.xlinkNS}:href`];
|
||||
let coverType = coverAttrs['content-type'];
|
||||
@@ -79,24 +78,21 @@ class Fb2Helper {
|
||||
const binaryId = (href[0] == '#' ? href.substring(1) : href);
|
||||
|
||||
//найдем нужный image
|
||||
parser.$$('binary').eachSelf(node => {
|
||||
for (const node of parser.$$array('/binary')) {
|
||||
let attrs = node.attrs();
|
||||
if (!attrs)
|
||||
return;
|
||||
attrs = Object.fromEntries(attrs);
|
||||
|
||||
if (attrs.id === binaryId) {
|
||||
const textNode = new Fb2Parser(node.value);
|
||||
const base64 = textNode.$self('*TEXT').value;
|
||||
|
||||
const base64 = node.text();
|
||||
cover = (base64 ? Buffer.from(base64, 'base64') : null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parser.remove('binary');
|
||||
return {fb2: parser.toObject(), cover, coverExt};
|
||||
return {fb2: parser, cover, coverExt};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ const XmlParser = require('../xml/XmlParser');
|
||||
class Fb2Parser extends XmlParser {
|
||||
get xlinkNS() {
|
||||
if (!this._xlinkNS) {
|
||||
const rootAttrs = this.$self().attrs();
|
||||
const rootAttrs = this.selectFirstSelf().attrs();
|
||||
let ns = 'l';
|
||||
for (const [key, value] of rootAttrs) {
|
||||
if (value == 'http://www.w3.org/1999/xlink') {
|
||||
@@ -18,27 +18,24 @@ class Fb2Parser extends XmlParser {
|
||||
return this._xlinkNS;
|
||||
}
|
||||
|
||||
bookInfo(fb2Object) {
|
||||
bookInfo() {
|
||||
const result = {};
|
||||
|
||||
if (!fb2Object)
|
||||
fb2Object = this.toObject();
|
||||
|
||||
const desc = this.inspector(fb2Object).$('fictionbook/description');
|
||||
const desc = this.$$('/description/');
|
||||
|
||||
if (!desc)
|
||||
return result;
|
||||
|
||||
const parseAuthors = (node, tagName) => {
|
||||
const authors = [];
|
||||
for (const a of node.$$(tagName)) {
|
||||
for (const a of node.$$array(tagName)) {
|
||||
let names = [];
|
||||
names.push(a.text('last-name'));
|
||||
names.push(a.text('first-name'));
|
||||
names.push(a.text('middle-name'));
|
||||
names.push(a.text('/last-name'));
|
||||
names.push(a.text('/first-name'));
|
||||
names.push(a.text('/middle-name'));
|
||||
names = names.filter(n => n);
|
||||
if (!names.length)
|
||||
names.push(a.text('nickname'));
|
||||
names.push(a.text('/nickname'));
|
||||
|
||||
authors.push(names.join(' '));
|
||||
}
|
||||
@@ -48,7 +45,7 @@ class Fb2Parser extends XmlParser {
|
||||
|
||||
const parseSequence = (node, tagName) => {
|
||||
const sequence = [];
|
||||
for (const s of node.$$(tagName)) {
|
||||
for (const s of node.$$array(tagName)) {
|
||||
const seqAttrs = s.attrs() || {};
|
||||
const name = seqAttrs['name'] || null;
|
||||
const num = seqAttrs['number'] || null;
|
||||
@@ -64,7 +61,7 @@ class Fb2Parser extends XmlParser {
|
||||
const info = {};
|
||||
|
||||
info.genre = [];
|
||||
for (const g of titleInfo.$$('genre'))
|
||||
for (const g of titleInfo.$$array('genre'))
|
||||
info.genre.push(g.text());
|
||||
|
||||
info.author = parseAuthors(titleInfo, 'author');
|
||||
@@ -77,7 +74,7 @@ class Fb2Parser extends XmlParser {
|
||||
info.annotationHtml = null;
|
||||
if (info.annotation) {
|
||||
//annotation как кусок xml
|
||||
info.annotationXml = (new XmlParser()).fromObject(info.annotation).toString({noHeader: true});
|
||||
info.annotationXml = titleInfo.$$('annotation/').toString({noHeader: true});
|
||||
|
||||
//annotation как html
|
||||
info.annotationHtml = this.toHtml(info.annotationXml);
|
||||
@@ -97,19 +94,19 @@ class Fb2Parser extends XmlParser {
|
||||
}
|
||||
|
||||
//title-info
|
||||
const titleInfo = desc.$('title-info');
|
||||
const titleInfo = desc.$$('title-info/');
|
||||
if (titleInfo) {
|
||||
result.titleInfo = parseTitleInfo(titleInfo);
|
||||
}
|
||||
|
||||
//src-title-info
|
||||
const srcTitleInfo = desc.$('src-title-info');
|
||||
const srcTitleInfo = desc.$$('src-title-info/');
|
||||
if (srcTitleInfo) {
|
||||
result.srcTitleInfo = parseTitleInfo(srcTitleInfo);
|
||||
}
|
||||
|
||||
//document-info
|
||||
const documentInfo = desc.$('document-info');
|
||||
const documentInfo = desc.$$('document-info/');
|
||||
if (documentInfo) {
|
||||
const info = {};
|
||||
|
||||
@@ -118,7 +115,7 @@ class Fb2Parser extends XmlParser {
|
||||
info.date = documentInfo.text('date');
|
||||
|
||||
info.srcUrl = [];
|
||||
for (const url of documentInfo.$$('src-url'))
|
||||
for (const url of documentInfo.$$array('src-url'))
|
||||
info.srcUrl.push(url.text());
|
||||
|
||||
info.srcOcr = documentInfo.text('src-ocr');
|
||||
@@ -131,7 +128,7 @@ class Fb2Parser extends XmlParser {
|
||||
info.historyHtml = null;
|
||||
if (info.history) {
|
||||
//history как кусок xml
|
||||
info.historyXml = (new XmlParser()).fromObject(info.history).toString({noHeader: true});
|
||||
info.historyXml = documentInfo.$$('history/').toString({noHeader: true});
|
||||
|
||||
//history как html
|
||||
info.historyHtml = this.toHtml(info.historyXml);
|
||||
@@ -143,7 +140,7 @@ class Fb2Parser extends XmlParser {
|
||||
}
|
||||
|
||||
//publish-info
|
||||
const publishInfo = desc.$('publish-info');
|
||||
const publishInfo = desc.$$('publish-info/');
|
||||
if (publishInfo) {
|
||||
const info = {};
|
||||
|
||||
@@ -160,7 +157,7 @@ class Fb2Parser extends XmlParser {
|
||||
return result;
|
||||
}
|
||||
|
||||
bookInfoList(fb2Object, options = {}) {
|
||||
bookInfoList(bookInfo, options = {}) {
|
||||
let {
|
||||
correctMapping = false,
|
||||
valueToString = false,
|
||||
@@ -236,7 +233,7 @@ class Fb2Parser extends XmlParser {
|
||||
];
|
||||
|
||||
mapping = correctMapping(mapping);
|
||||
const bookInfo = this.bookInfo(fb2Object);
|
||||
bookInfo = (bookInfo ? bookInfo : this.bookInfo());
|
||||
|
||||
//заполняем mapping
|
||||
let result = [];
|
||||
|
||||
@@ -817,7 +817,7 @@ class XmlParser extends NodeBase {
|
||||
if (raw.length && !s.last) {
|
||||
if (s.index < raw.length) {
|
||||
raw = raw[s.index];
|
||||
if (raw[0] === NODE)
|
||||
if (raw[0] === NODE && raw[3])
|
||||
raw = raw[3];
|
||||
else {
|
||||
raw = [];
|
||||
|
||||
@@ -191,7 +191,7 @@ function initStatic(app, config) {
|
||||
|
||||
if (path.extname(req.path) == '') {
|
||||
const bookFile = `${config.publicFilesDir}${req.path}`;
|
||||
const bookFileDesc = `${bookFile}.json`;
|
||||
const bookFileDesc = `${bookFile}.d.json`;
|
||||
|
||||
let downFileName = '';
|
||||
//восстановим из json-файла описания
|
||||
|
||||
Reference in New Issue
Block a user