Переименования
This commit is contained in:
@@ -15,7 +15,7 @@ const ayncExit = new (require('./AsyncExit'))();
|
|||||||
const log = new (require('./AppLogger'))().log;//singleton
|
const log = new (require('./AppLogger'))().log;//singleton
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
const genreTree = require('./genres');
|
const genreTree = require('./genres');
|
||||||
const Fb2Parser = require('./fb2/Fb2Parser');
|
const Fb2Helper = require('./fb2/Fb2Helper');
|
||||||
|
|
||||||
//server states
|
//server states
|
||||||
const ssNormal = 'normal';
|
const ssNormal = 'normal';
|
||||||
@@ -45,7 +45,7 @@ class WebWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.inpxHashCreator = new InpxHashCreator(config);
|
this.inpxHashCreator = new InpxHashCreator(config);
|
||||||
this.fb2Parser = new Fb2Parser();
|
this.fb2Helper = new Fb2Helper();
|
||||||
this.inpxFileHash = '';
|
this.inpxFileHash = '';
|
||||||
|
|
||||||
this.wState = this.workerState.getControl('server_state');
|
this.wState = this.workerState.getControl('server_state');
|
||||||
@@ -480,7 +480,7 @@ class WebWorker {
|
|||||||
result.fb2 = false;
|
result.fb2 = false;
|
||||||
|
|
||||||
if (book.ext == 'fb2') {
|
if (book.ext == 'fb2') {
|
||||||
const {desc, cover, coverExt} = await this.fb2Parser.getDescAndCover(bookFile);
|
const {desc, cover, coverExt} = await this.fb2Helper.getDescAndCover(bookFile);
|
||||||
result.fb2 = desc;
|
result.fb2 = desc;
|
||||||
|
|
||||||
if (cover) {
|
if (cover) {
|
||||||
|
|||||||
@@ -1,101 +1,37 @@
|
|||||||
const fs = require('fs-extra');
|
|
||||||
const iconv = require('iconv-lite');
|
|
||||||
const textUtils = require('./textUtils');
|
|
||||||
|
|
||||||
const XmlParser = require('../xml/XmlParser');
|
const XmlParser = require('../xml/XmlParser');
|
||||||
const utils = require('../utils');
|
|
||||||
|
|
||||||
class Fb2Parser {
|
class Fb2Parser {
|
||||||
checkEncoding(data) {
|
constructor() {
|
||||||
//Корректируем кодировку UTF-16
|
this.xml = new XmlParser();
|
||||||
let encoding = textUtils.getEncoding(data);
|
|
||||||
if (encoding.indexOf('UTF-16') == 0) {
|
|
||||||
data = Buffer.from(iconv.decode(data, encoding));
|
|
||||||
encoding = 'utf-8';
|
|
||||||
}
|
|
||||||
|
|
||||||
//Корректируем пробелы, всякие файлы попадаются :(
|
|
||||||
if (data[0] == 32) {
|
|
||||||
data = Buffer.from(data.toString().trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Окончательно корректируем кодировку
|
|
||||||
let result = data;
|
|
||||||
|
|
||||||
let left = data.indexOf('<?xml version="1.0"');
|
|
||||||
if (left < 0) {
|
|
||||||
left = data.indexOf('<?xml version=\'1.0\'');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left >= 0) {
|
|
||||||
const right = data.indexOf('?>', left);
|
|
||||||
if (right >= 0) {
|
|
||||||
const head = data.slice(left, right + 2).toString();
|
|
||||||
const m = head.match(/encoding=['"](.*?)['"]/);
|
|
||||||
if (m) {
|
|
||||||
let enc = m[1].toLowerCase();
|
|
||||||
if (enc != 'utf-8') {
|
|
||||||
//enc может не соответсвовать реальной кодировке файла, поэтому:
|
|
||||||
if (encoding.indexOf('ISO-8859') >= 0) {
|
|
||||||
encoding = enc;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = iconv.decode(data, encoding);
|
|
||||||
result = Buffer.from(result.toString().replace(m[0], `encoding="utf-8"`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDescAndCover(bookFile) {
|
toString(options) {
|
||||||
let data = await fs.readFile(bookFile);
|
return this.xml.toString(options);
|
||||||
data = await utils.gunzipBuffer(data);
|
}
|
||||||
|
|
||||||
data = this.checkEncoding(data);
|
fromString(fb2String) {
|
||||||
|
this.xml.fromString(fb2String);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
const xml = new XmlParser();
|
toObject(options) {
|
||||||
|
return this.xml.toObject(options);
|
||||||
|
}
|
||||||
|
|
||||||
xml.fromString(data.toString(), {
|
fromObject(fb2Object) {
|
||||||
lowerCase: true,
|
this.xml.fromObject(fb2Object);
|
||||||
pickNode: route => route.indexOf('fictionbook/body') !== 0,
|
return this;
|
||||||
});
|
}
|
||||||
|
|
||||||
const desc = xml.$$('description').toObject();
|
bookInfo(fb2Object) {
|
||||||
const coverImage = xml.navigator(desc).$('description/title-info/coverpage/image');
|
if (!fb2Object)
|
||||||
|
fb2Object = this.toObject();
|
||||||
|
|
||||||
let cover = null;
|
//const result = {};
|
||||||
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
|
bookInfoList(fb2Object) {
|
||||||
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};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
class ObjectNavigator {
|
class ObjectInspector {
|
||||||
constructor(raw = null) {
|
constructor(raw = null) {
|
||||||
this.raw = raw;
|
this.raw = raw;
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ class ObjectNavigator {
|
|||||||
|
|
||||||
const result = [];
|
const result = [];
|
||||||
for (const r of raw)
|
for (const r of raw)
|
||||||
result.push(new ObjectNavigator(r));
|
result.push(new ObjectInspector(r));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -106,4 +106,4 @@ class ObjectNavigator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ObjectNavigator;
|
module.exports = ObjectInspector;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
const sax = require('./sax');
|
const sax = require('./sax');
|
||||||
const ObjectNavigator = require('./ObjectNavigator');
|
const ObjectInspector = require('./ObjectInspector');
|
||||||
|
|
||||||
//node types
|
//node types
|
||||||
const NODE = 1;
|
const NODE = 1;
|
||||||
@@ -760,11 +760,11 @@ class XmlParser extends NodeBase {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
navigator(obj) {
|
inspector(obj) {
|
||||||
if (!obj)
|
if (!obj)
|
||||||
obj = this.toObject();
|
obj = this.toObject();
|
||||||
|
|
||||||
return new ObjectNavigator(obj);
|
return new ObjectInspector(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user