Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4da07e924 | ||
|
|
110d145b91 | ||
|
|
fc3d391aa0 | ||
|
|
4d01901463 | ||
|
|
2d380bd98f | ||
|
|
2dd67487dc | ||
|
|
a3190e4af3 | ||
|
|
3d28beddac |
@@ -1,4 +1,4 @@
|
|||||||
import moment from 'moment';
|
import dayjs from 'dayjs';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import authorBooksStorage from './authorBooksStorage';
|
import authorBooksStorage from './authorBooksStorage';
|
||||||
@@ -467,13 +467,13 @@ export default class BaseList {
|
|||||||
*/
|
*/
|
||||||
const sqlFormat = 'YYYY-MM-DD';
|
const sqlFormat = 'YYYY-MM-DD';
|
||||||
switch (date) {
|
switch (date) {
|
||||||
case 'today': date = utils.dateFormat(moment(), sqlFormat); break;
|
case 'today': date = utils.dateFormat(dayjs(), sqlFormat); break;
|
||||||
case '3days': date = utils.dateFormat(moment().subtract(3, 'days'), sqlFormat); break;
|
case '3days': date = utils.dateFormat(dayjs().subtract(3, 'days'), sqlFormat); break;
|
||||||
case 'week': date = utils.dateFormat(moment().subtract(1, 'weeks'), sqlFormat); break;
|
case 'week': date = utils.dateFormat(dayjs().subtract(1, 'weeks'), sqlFormat); break;
|
||||||
case '2weeks': date = utils.dateFormat(moment().subtract(2, 'weeks'), sqlFormat); break;
|
case '2weeks': date = utils.dateFormat(dayjs().subtract(2, 'weeks'), sqlFormat); break;
|
||||||
case 'month': date = utils.dateFormat(moment().subtract(1, 'months'), sqlFormat); break;
|
case 'month': date = utils.dateFormat(dayjs().subtract(1, 'months'), sqlFormat); break;
|
||||||
case '2months': date = utils.dateFormat(moment().subtract(2, 'months'), sqlFormat); break;
|
case '2months': date = utils.dateFormat(dayjs().subtract(2, 'months'), sqlFormat); break;
|
||||||
case '3months': date = utils.dateFormat(moment().subtract(3, 'months'), sqlFormat); break;
|
case '3months': date = utils.dateFormat(dayjs().subtract(3, 'months'), sqlFormat); break;
|
||||||
default:
|
default:
|
||||||
date = '';
|
date = '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ class BookInfoDialog {
|
|||||||
return utils.sqlDateFormat(value);
|
return utils.sqlDateFormat(value);
|
||||||
|
|
||||||
if (nodePath == 'fileInfo/del')
|
if (nodePath == 'fileInfo/del')
|
||||||
return (value ? 'Да' : 'Нет');
|
return (value ? 'Да' : '');
|
||||||
|
|
||||||
if (nodePath == 'titleInfo/author')
|
if (nodePath == 'titleInfo/author')
|
||||||
return value.split(',').join(', ');
|
return value.split(',').join(', ');
|
||||||
@@ -239,7 +239,6 @@ class BookInfoDialog {
|
|||||||
|
|
||||||
parseBookInfo() {
|
parseBookInfo() {
|
||||||
const bookInfo = this.bookInfo;
|
const bookInfo = this.bookInfo;
|
||||||
const parser = new Fb2Parser();
|
|
||||||
|
|
||||||
//cover
|
//cover
|
||||||
if (bookInfo.cover)
|
if (bookInfo.cover)
|
||||||
@@ -247,16 +246,10 @@ class BookInfoDialog {
|
|||||||
|
|
||||||
//fb2
|
//fb2
|
||||||
if (bookInfo.fb2) {
|
if (bookInfo.fb2) {
|
||||||
this.fb2 = parser.bookInfoList(bookInfo.fb2, {
|
const parser = new Fb2Parser(bookInfo.fb2);
|
||||||
valueToString(value, nodePath, origVTS) {//eslint-disable-line no-unused-vars
|
|
||||||
if (nodePath == 'documentInfo/historyHtml' && value)
|
const infoObj = parser.bookInfo();
|
||||||
return value.replace(/<p>/g, `<p class="p-history">`);
|
|
||||||
|
|
||||||
return origVTS(value, nodePath);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const infoObj = parser.bookInfo(bookInfo.fb2);
|
|
||||||
if (infoObj.titleInfo) {
|
if (infoObj.titleInfo) {
|
||||||
let ann = infoObj.titleInfo.annotationHtml;
|
let ann = infoObj.titleInfo.annotationHtml;
|
||||||
if (ann) {
|
if (ann) {
|
||||||
@@ -264,6 +257,15 @@ class BookInfoDialog {
|
|||||||
this.annotation = ann;
|
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
|
//book
|
||||||
|
|||||||
@@ -55,8 +55,8 @@
|
|||||||
{{ bookSize }}, {{ book.ext }}
|
{{ bookSize }}, {{ book.ext }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="showInfo" class="row items-center q-ml-sm clickable" @click="emit('bookInfo')">
|
<div v-if="showInfo" class="q-ml-sm clickable" @click="emit('bookInfo')">
|
||||||
[ . . . ]
|
(инфо)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="q-ml-sm clickable" @click="emit('download')">
|
<div class="q-ml-sm clickable" @click="emit('download')">
|
||||||
|
|||||||
@@ -204,7 +204,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row justify-center">
|
<div class="row justify-center">
|
||||||
<div class="q-mb-sm q-px-sm q-py-xs bg-cyan-2 clickable2" style="border: 1px solid #aaaaaa; border-radius: 6px; white-space: nowrap;" @click="openReleasePage">
|
<div class="q-mb-xl q-px-sm q-py-xs bg-cyan-2 clickable2" style="border: 1px solid #aaaaaa; border-radius: 6px; white-space: nowrap;" @click="openReleasePage">
|
||||||
{{ projectName }}
|
{{ projectName }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -232,7 +232,7 @@
|
|||||||
|
|
||||||
<q-checkbox v-model="showCounts" size="36px" label="Показывать количество" />
|
<q-checkbox v-model="showCounts" size="36px" label="Показывать количество" />
|
||||||
<q-checkbox v-model="showRates" size="36px" label="Показывать оценки" />
|
<q-checkbox v-model="showRates" size="36px" label="Показывать оценки" />
|
||||||
<q-checkbox v-model="showInfo" size="36px" label="Показывать кнопку 'инфо'" />
|
<q-checkbox v-model="showInfo" size="36px" label="Показывать кнопку (инфо)" />
|
||||||
<q-checkbox v-model="showGenres" size="36px" label="Показывать жанры" />
|
<q-checkbox v-model="showGenres" size="36px" label="Показывать жанры" />
|
||||||
<q-checkbox v-model="showDates" size="36px" label="Показывать даты поступления" />
|
<q-checkbox v-model="showDates" size="36px" label="Показывать даты поступления" />
|
||||||
<q-checkbox v-model="showDeleted" size="36px" label="Показывать удаленные" />
|
<q-checkbox v-model="showDeleted" size="36px" label="Показывать удаленные" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import moment from 'moment';
|
import dayjs from 'dayjs';
|
||||||
import {Buffer} from 'safe-buffer';
|
import {Buffer} from 'safe-buffer';
|
||||||
//import _ from 'lodash';
|
//import _ from 'lodash';
|
||||||
|
|
||||||
@@ -121,11 +121,11 @@ export function isDigit(c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function dateFormat(date, format = 'DD.MM.YYYY') {
|
export function dateFormat(date, format = 'DD.MM.YYYY') {
|
||||||
return moment(date).format(format);
|
return dayjs(date).format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sqlDateFormat(date, format = 'DD.MM.YYYY') {
|
export function sqlDateFormat(date, format = 'DD.MM.YYYY') {
|
||||||
return moment(date, 'YYYY-MM-DD').format(format);
|
return dayjs(date, 'YYYY-MM-DD').format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isManualDate(date) {
|
export function isManualDate(date) {
|
||||||
|
|||||||
29
package-lock.json
generated
29
package-lock.json
generated
@@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "inpx-web",
|
"name": "inpx-web",
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "inpx-web",
|
"name": "inpx-web",
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "CC0-1.0",
|
"license": "CC0-1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/extras": "^1.15.0",
|
"@quasar/extras": "^1.15.0",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"chardet": "^1.5.0",
|
"chardet": "^1.5.0",
|
||||||
|
"dayjs": "^1.11.6",
|
||||||
"express": "^4.18.1",
|
"express": "^4.18.1",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
@@ -20,7 +21,6 @@
|
|||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"minimist": "^1.2.6",
|
"minimist": "^1.2.6",
|
||||||
"moment": "^2.29.4",
|
|
||||||
"node-stream-zip": "^1.15.0",
|
"node-stream-zip": "^1.15.0",
|
||||||
"quasar": "^2.7.5",
|
"quasar": "^2.7.5",
|
||||||
"safe-buffer": "^5.2.1",
|
"safe-buffer": "^5.2.1",
|
||||||
@@ -3433,6 +3433,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz",
|
||||||
|
"integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ=="
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
@@ -5519,14 +5524,6 @@
|
|||||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/moment": {
|
|
||||||
"version": "2.29.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
|
||||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@@ -11324,6 +11321,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.20.tgz",
|
||||||
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
"integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA=="
|
||||||
},
|
},
|
||||||
|
"dayjs": {
|
||||||
|
"version": "1.11.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz",
|
||||||
|
"integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ=="
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
@@ -12879,11 +12881,6 @@
|
|||||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"moment": {
|
|
||||||
"version": "2.29.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
|
||||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
|
||||||
},
|
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "inpx-web",
|
"name": "inpx-web",
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"author": "Book Pauk <bookpauk@gmail.com>",
|
"author": "Book Pauk <bookpauk@gmail.com>",
|
||||||
"license": "CC0-1.0",
|
"license": "CC0-1.0",
|
||||||
"repository": "bookpauk/inpx-web",
|
"repository": "bookpauk/inpx-web",
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
"@quasar/extras": "^1.15.0",
|
"@quasar/extras": "^1.15.0",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"chardet": "^1.5.0",
|
"chardet": "^1.5.0",
|
||||||
|
"dayjs": "^1.11.6",
|
||||||
"express": "^4.18.1",
|
"express": "^4.18.1",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
@@ -59,7 +60,6 @@
|
|||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"minimist": "^1.2.6",
|
"minimist": "^1.2.6",
|
||||||
"moment": "^2.29.4",
|
|
||||||
"node-stream-zip": "^1.15.0",
|
"node-stream-zip": "^1.15.0",
|
||||||
"quasar": "^2.7.5",
|
"quasar": "^2.7.5",
|
||||||
"safe-buffer": "^5.2.1",
|
"safe-buffer": "^5.2.1",
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ class WebWorker {
|
|||||||
|
|
||||||
const link = `${this.config.filesPathStatic}/${hash}`;
|
const link = `${this.config.filesPathStatic}/${hash}`;
|
||||||
const bookFile = `${this.config.filesDir}/${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) || !await fs.pathExists(bookFileDesc)) {
|
||||||
if (!await fs.pathExists(bookFile) && extractedFile) {
|
if (!await fs.pathExists(bookFile) && extractedFile) {
|
||||||
@@ -435,7 +435,7 @@ class WebWorker {
|
|||||||
if (rows.length) {//хеш найден по bookPath
|
if (rows.length) {//хеш найден по bookPath
|
||||||
const hash = rows[0].hash;
|
const hash = rows[0].hash;
|
||||||
const bookFile = `${this.config.filesDir}/${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) && await fs.pathExists(bookFileDesc)) {
|
||||||
link = `${this.config.filesPathStatic}/${hash}`;
|
link = `${this.config.filesPathStatic}/${hash}`;
|
||||||
@@ -467,9 +467,9 @@ class WebWorker {
|
|||||||
let bookInfo = await this.getBookLink(bookId);
|
let bookInfo = await this.getBookLink(bookId);
|
||||||
const hash = path.basename(bookInfo.link);
|
const hash = path.basename(bookInfo.link);
|
||||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
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 result = {};
|
||||||
|
|
||||||
const rows = await db.select({table: 'book', where: `@@id(${db.esc(bookId)})`});
|
const rows = await db.select({table: 'book', where: `@@id(${db.esc(bookId)})`});
|
||||||
@@ -478,10 +478,12 @@ class WebWorker {
|
|||||||
result.book = book;
|
result.book = book;
|
||||||
result.cover = '';
|
result.cover = '';
|
||||||
result.fb2 = false;
|
result.fb2 = false;
|
||||||
|
let parser = null;
|
||||||
|
|
||||||
if (book.ext == 'fb2') {
|
if (book.ext == 'fb2') {
|
||||||
const {fb2, cover, coverExt} = await this.fb2Helper.getDescAndCover(bookFile);
|
const {fb2, cover, coverExt} = await this.fb2Helper.getDescAndCover(bookFile);
|
||||||
result.fb2 = fb2;
|
parser = fb2;
|
||||||
|
result.fb2 = fb2.rawNodes;
|
||||||
|
|
||||||
if (cover) {
|
if (cover) {
|
||||||
result.cover = `${this.config.filesPathStatic}/${hash}${coverExt}`;
|
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)) {
|
if (!await fs.pathExists(bookFileInfo)) {
|
||||||
Object.assign(bookInfo, await restoreBookInfo());
|
await restoreBookInfo(bookInfo);
|
||||||
await fs.writeFile(bookFileInfo, JSON.stringify(bookInfo, null, 2));
|
|
||||||
} else {
|
} else {
|
||||||
await utils.touchFile(bookFileInfo);
|
await utils.touchFile(bookFileInfo);
|
||||||
const info = await fs.readFile(bookFileInfo, 'utf-8');
|
const info = await fs.readFile(bookFileInfo, 'utf-8');
|
||||||
@@ -506,8 +512,7 @@ class WebWorker {
|
|||||||
coverFile = `${this.config.publicFilesDir}${tmpInfo.cover}`;
|
coverFile = `${this.config.publicFilesDir}${tmpInfo.cover}`;
|
||||||
|
|
||||||
if (coverFile && !await fs.pathExists(coverFile)) {
|
if (coverFile && !await fs.pathExists(coverFile)) {
|
||||||
Object.assign(bookInfo, await restoreBookInfo());
|
await restoreBookInfo(bookInfo);
|
||||||
await fs.writeFile(bookFileInfo, JSON.stringify(bookInfo, null, 2));
|
|
||||||
} else {
|
} else {
|
||||||
bookInfo = tmpInfo;
|
bookInfo = tmpInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,12 +63,11 @@ class Fb2Helper {
|
|||||||
pickNode: route => route.indexOf('fictionbook/body') !== 0,
|
pickNode: route => route.indexOf('fictionbook/body') !== 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const desc = parser.$$('description').toObject();
|
const coverImage = parser.$$('/description/title-info/coverpage/image');
|
||||||
const coverImage = parser.inspector(desc).$('description/title-info/coverpage/image');
|
|
||||||
|
|
||||||
let cover = null;
|
let cover = null;
|
||||||
let coverExt = '';
|
let coverExt = '';
|
||||||
if (coverImage) {
|
if (coverImage.count) {
|
||||||
const coverAttrs = coverImage.attrs();
|
const coverAttrs = coverImage.attrs();
|
||||||
const href = coverAttrs[`${parser.xlinkNS}:href`];
|
const href = coverAttrs[`${parser.xlinkNS}:href`];
|
||||||
let coverType = coverAttrs['content-type'];
|
let coverType = coverAttrs['content-type'];
|
||||||
@@ -79,24 +78,21 @@ class Fb2Helper {
|
|||||||
const binaryId = (href[0] == '#' ? href.substring(1) : href);
|
const binaryId = (href[0] == '#' ? href.substring(1) : href);
|
||||||
|
|
||||||
//найдем нужный image
|
//найдем нужный image
|
||||||
parser.$$('binary').eachSelf(node => {
|
for (const node of parser.$$array('/binary')) {
|
||||||
let attrs = node.attrs();
|
let attrs = node.attrs();
|
||||||
if (!attrs)
|
if (!attrs)
|
||||||
return;
|
return;
|
||||||
attrs = Object.fromEntries(attrs);
|
|
||||||
|
|
||||||
if (attrs.id === binaryId) {
|
if (attrs.id === binaryId) {
|
||||||
const textNode = new Fb2Parser(node.value);
|
const base64 = node.text();
|
||||||
const base64 = textNode.$self('*TEXT').value;
|
|
||||||
|
|
||||||
cover = (base64 ? Buffer.from(base64, 'base64') : null);
|
cover = (base64 ? Buffer.from(base64, 'base64') : null);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.remove('binary');
|
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 {
|
class Fb2Parser extends XmlParser {
|
||||||
get xlinkNS() {
|
get xlinkNS() {
|
||||||
if (!this._xlinkNS) {
|
if (!this._xlinkNS) {
|
||||||
const rootAttrs = this.$self().attrs();
|
const rootAttrs = this.selectFirstSelf().attrs();
|
||||||
let ns = 'l';
|
let ns = 'l';
|
||||||
for (const [key, value] of rootAttrs) {
|
for (const [key, value] of rootAttrs) {
|
||||||
if (value == 'http://www.w3.org/1999/xlink') {
|
if (value == 'http://www.w3.org/1999/xlink') {
|
||||||
@@ -18,27 +18,24 @@ class Fb2Parser extends XmlParser {
|
|||||||
return this._xlinkNS;
|
return this._xlinkNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bookInfo(fb2Object) {
|
bookInfo() {
|
||||||
const result = {};
|
const result = {};
|
||||||
|
|
||||||
if (!fb2Object)
|
const desc = this.$$('/description/');
|
||||||
fb2Object = this.toObject();
|
|
||||||
|
|
||||||
const desc = this.inspector(fb2Object).$('fictionbook/description');
|
|
||||||
|
|
||||||
if (!desc)
|
if (!desc)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
const parseAuthors = (node, tagName) => {
|
const parseAuthors = (node, tagName) => {
|
||||||
const authors = [];
|
const authors = [];
|
||||||
for (const a of node.$$(tagName)) {
|
for (const a of node.$$array(tagName)) {
|
||||||
let names = [];
|
let names = [];
|
||||||
names.push(a.text('last-name'));
|
names.push(a.text('/last-name'));
|
||||||
names.push(a.text('first-name'));
|
names.push(a.text('/first-name'));
|
||||||
names.push(a.text('middle-name'));
|
names.push(a.text('/middle-name'));
|
||||||
names = names.filter(n => n);
|
names = names.filter(n => n);
|
||||||
if (!names.length)
|
if (!names.length)
|
||||||
names.push(a.text('nickname'));
|
names.push(a.text('/nickname'));
|
||||||
|
|
||||||
authors.push(names.join(' '));
|
authors.push(names.join(' '));
|
||||||
}
|
}
|
||||||
@@ -48,7 +45,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
|
|
||||||
const parseSequence = (node, tagName) => {
|
const parseSequence = (node, tagName) => {
|
||||||
const sequence = [];
|
const sequence = [];
|
||||||
for (const s of node.$$(tagName)) {
|
for (const s of node.$$array(tagName)) {
|
||||||
const seqAttrs = s.attrs() || {};
|
const seqAttrs = s.attrs() || {};
|
||||||
const name = seqAttrs['name'] || null;
|
const name = seqAttrs['name'] || null;
|
||||||
const num = seqAttrs['number'] || null;
|
const num = seqAttrs['number'] || null;
|
||||||
@@ -64,7 +61,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
const info = {};
|
const info = {};
|
||||||
|
|
||||||
info.genre = [];
|
info.genre = [];
|
||||||
for (const g of titleInfo.$$('genre'))
|
for (const g of titleInfo.$$array('genre'))
|
||||||
info.genre.push(g.text());
|
info.genre.push(g.text());
|
||||||
|
|
||||||
info.author = parseAuthors(titleInfo, 'author');
|
info.author = parseAuthors(titleInfo, 'author');
|
||||||
@@ -77,7 +74,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
info.annotationHtml = null;
|
info.annotationHtml = null;
|
||||||
if (info.annotation) {
|
if (info.annotation) {
|
||||||
//annotation как кусок xml
|
//annotation как кусок xml
|
||||||
info.annotationXml = (new XmlParser()).fromObject(info.annotation).toString({noHeader: true});
|
info.annotationXml = titleInfo.$$('annotation/').toString({noHeader: true});
|
||||||
|
|
||||||
//annotation как html
|
//annotation как html
|
||||||
info.annotationHtml = this.toHtml(info.annotationXml);
|
info.annotationHtml = this.toHtml(info.annotationXml);
|
||||||
@@ -97,19 +94,19 @@ class Fb2Parser extends XmlParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//title-info
|
//title-info
|
||||||
const titleInfo = desc.$('title-info');
|
const titleInfo = desc.$$('title-info/');
|
||||||
if (titleInfo) {
|
if (titleInfo) {
|
||||||
result.titleInfo = parseTitleInfo(titleInfo);
|
result.titleInfo = parseTitleInfo(titleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//src-title-info
|
//src-title-info
|
||||||
const srcTitleInfo = desc.$('src-title-info');
|
const srcTitleInfo = desc.$$('src-title-info/');
|
||||||
if (srcTitleInfo) {
|
if (srcTitleInfo) {
|
||||||
result.srcTitleInfo = parseTitleInfo(srcTitleInfo);
|
result.srcTitleInfo = parseTitleInfo(srcTitleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//document-info
|
//document-info
|
||||||
const documentInfo = desc.$('document-info');
|
const documentInfo = desc.$$('document-info/');
|
||||||
if (documentInfo) {
|
if (documentInfo) {
|
||||||
const info = {};
|
const info = {};
|
||||||
|
|
||||||
@@ -118,7 +115,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
info.date = documentInfo.text('date');
|
info.date = documentInfo.text('date');
|
||||||
|
|
||||||
info.srcUrl = [];
|
info.srcUrl = [];
|
||||||
for (const url of documentInfo.$$('src-url'))
|
for (const url of documentInfo.$$array('src-url'))
|
||||||
info.srcUrl.push(url.text());
|
info.srcUrl.push(url.text());
|
||||||
|
|
||||||
info.srcOcr = documentInfo.text('src-ocr');
|
info.srcOcr = documentInfo.text('src-ocr');
|
||||||
@@ -131,7 +128,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
info.historyHtml = null;
|
info.historyHtml = null;
|
||||||
if (info.history) {
|
if (info.history) {
|
||||||
//history как кусок xml
|
//history как кусок xml
|
||||||
info.historyXml = (new XmlParser()).fromObject(info.history).toString({noHeader: true});
|
info.historyXml = documentInfo.$$('history/').toString({noHeader: true});
|
||||||
|
|
||||||
//history как html
|
//history как html
|
||||||
info.historyHtml = this.toHtml(info.historyXml);
|
info.historyHtml = this.toHtml(info.historyXml);
|
||||||
@@ -143,7 +140,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//publish-info
|
//publish-info
|
||||||
const publishInfo = desc.$('publish-info');
|
const publishInfo = desc.$$('publish-info/');
|
||||||
if (publishInfo) {
|
if (publishInfo) {
|
||||||
const info = {};
|
const info = {};
|
||||||
|
|
||||||
@@ -160,7 +157,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bookInfoList(fb2Object, options = {}) {
|
bookInfoList(bookInfo, options = {}) {
|
||||||
let {
|
let {
|
||||||
correctMapping = false,
|
correctMapping = false,
|
||||||
valueToString = false,
|
valueToString = false,
|
||||||
@@ -236,7 +233,7 @@ class Fb2Parser extends XmlParser {
|
|||||||
];
|
];
|
||||||
|
|
||||||
mapping = correctMapping(mapping);
|
mapping = correctMapping(mapping);
|
||||||
const bookInfo = this.bookInfo(fb2Object);
|
bookInfo = (bookInfo ? bookInfo : this.bookInfo());
|
||||||
|
|
||||||
//заполняем mapping
|
//заполняем mapping
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ class ObjectInspector {
|
|||||||
this.raw = raw;
|
this.raw = raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
makeSelector(selector) {
|
narrowSelector(selector) {
|
||||||
const result = [];
|
const result = [];
|
||||||
selector = selector.trim();
|
selector = selector.trim();
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ class ObjectInspector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
select(selector = '') {
|
select(selector = '') {
|
||||||
selector = this.makeSelector(selector);
|
selector = this.narrowSelector(selector);
|
||||||
|
|
||||||
let raw = this.raw;
|
let raw = this.raw;
|
||||||
for (const s of selector) {
|
for (const s of selector) {
|
||||||
@@ -50,14 +50,10 @@ class ObjectInspector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (raw === undefined || raw === null) {
|
if (raw === undefined || raw === null) {
|
||||||
raw = null;
|
return [];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw === null)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
raw = (Array.isArray(raw) ? raw : [raw]);
|
raw = (Array.isArray(raw) ? raw : [raw]);
|
||||||
|
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
const sax = require('./sax');
|
const sax = require('./sax');
|
||||||
const ObjectInspector = require('./ObjectInspector');
|
|
||||||
|
|
||||||
//node types
|
//node types
|
||||||
const NODE = 1;
|
const NODE = 1;
|
||||||
@@ -22,7 +21,7 @@ const type2name = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class NodeBase {
|
class NodeBase {
|
||||||
makeSelectorObj(selectorString) {
|
wideSelector(selectorString) {
|
||||||
const result = {all: false, before: false, type: 0, name: ''};
|
const result = {all: false, before: false, type: 0, name: ''};
|
||||||
|
|
||||||
if (selectorString === '') {
|
if (selectorString === '') {
|
||||||
@@ -153,7 +152,7 @@ class NodeObject extends NodeBase {
|
|||||||
if (this.type !== NODE)
|
if (this.type !== NODE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const selectorObj = this.makeSelectorObj(after);
|
const selectorObj = this.wideSelector(after);
|
||||||
|
|
||||||
if (!Array.isArray(this.raw[3]))
|
if (!Array.isArray(this.raw[3]))
|
||||||
this.raw[3] = [];
|
this.raw[3] = [];
|
||||||
@@ -172,7 +171,7 @@ class NodeObject extends NodeBase {
|
|||||||
if (this.type !== NODE || !this.raw[3])
|
if (this.type !== NODE || !this.raw[3])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const selectorObj = this.makeSelectorObj(selector);
|
const selectorObj = this.wideSelector(selector);
|
||||||
|
|
||||||
this.rawRemove(this.raw[3], selectorObj);
|
this.rawRemove(this.raw[3], selectorObj);
|
||||||
if (!this.raw[3].length)
|
if (!this.raw[3].length)
|
||||||
@@ -233,6 +232,14 @@ class XmlParser extends NodeBase {
|
|||||||
return this.rawNodes.length;
|
return this.rawNodes.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get nodes() {
|
||||||
|
const result = [];
|
||||||
|
for (const n of this.rawNodes)
|
||||||
|
result.push(new NodeObject(n));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
nodeObject(node) {
|
nodeObject(node) {
|
||||||
return new NodeObject(node);
|
return new NodeObject(node);
|
||||||
}
|
}
|
||||||
@@ -279,7 +286,7 @@ class XmlParser extends NodeBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add(node, after = '*') {
|
add(node, after = '*') {
|
||||||
const selectorObj = this.makeSelectorObj(after);
|
const selectorObj = this.wideSelector(after);
|
||||||
|
|
||||||
for (const n of this.rawNodes) {
|
for (const n of this.rawNodes) {
|
||||||
if (n && n[0] === NODE) {
|
if (n && n[0] === NODE) {
|
||||||
@@ -299,7 +306,7 @@ class XmlParser extends NodeBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addRoot(node, after = '*') {
|
addRoot(node, after = '*') {
|
||||||
const selectorObj = this.makeSelectorObj(after);
|
const selectorObj = this.wideSelector(after);
|
||||||
|
|
||||||
if (Array.isArray(node)) {
|
if (Array.isArray(node)) {
|
||||||
for (const node_ of node)
|
for (const node_ of node)
|
||||||
@@ -312,7 +319,7 @@ class XmlParser extends NodeBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remove(selector = '') {
|
remove(selector = '') {
|
||||||
const selectorObj = this.makeSelectorObj(selector);
|
const selectorObj = this.wideSelector(selector);
|
||||||
|
|
||||||
for (const n of this.rawNodes) {
|
for (const n of this.rawNodes) {
|
||||||
if (n && n[0] === NODE && Array.isArray(n[3])) {
|
if (n && n[0] === NODE && Array.isArray(n[3])) {
|
||||||
@@ -326,7 +333,7 @@ class XmlParser extends NodeBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeRoot(selector = '') {
|
removeRoot(selector = '') {
|
||||||
const selectorObj = this.makeSelectorObj(selector);
|
const selectorObj = this.wideSelector(selector);
|
||||||
|
|
||||||
this.rawRemove(this.rawNodes, selectorObj);
|
this.rawRemove(this.rawNodes, selectorObj);
|
||||||
|
|
||||||
@@ -409,7 +416,7 @@ class XmlParser extends NodeBase {
|
|||||||
|
|
||||||
newRawNodes = res.rawNodes;
|
newRawNodes = res.rawNodes;
|
||||||
} else {
|
} else {
|
||||||
const selectorObj = this.makeSelectorObj(selector);
|
const selectorObj = this.wideSelector(selector);
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
this.rawSelect(this.rawNodes, selectorObj, (node) => {
|
this.rawSelect(this.rawNodes, selectorObj, (node) => {
|
||||||
@@ -429,11 +436,7 @@ class XmlParser extends NodeBase {
|
|||||||
return new XmlParser(newRawNodes);
|
return new XmlParser(newRawNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
$$(selector, self) {
|
selectSelf(selector) {
|
||||||
return this.select(selector, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
$$self(selector) {
|
|
||||||
return this.select(selector, true);
|
return this.select(selector, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,11 +446,7 @@ class XmlParser extends NodeBase {
|
|||||||
return new NodeObject(node);
|
return new NodeObject(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
$(selector, self) {
|
selectFirstSelf(selector) {
|
||||||
return this.selectFirst(selector, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
$self(selector) {
|
|
||||||
return this.selectFirst(selector, true);
|
return this.selectFirst(selector, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,12 +759,138 @@ class XmlParser extends NodeBase {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inspector(obj) {
|
// XML Inspector start
|
||||||
if (!obj)
|
narrowSelector(selector) {
|
||||||
obj = this.toObject();
|
const result = [];
|
||||||
|
selector = selector.trim();
|
||||||
|
|
||||||
|
//последний индекс не учитывется, только если не задан явно
|
||||||
|
if (selector && selector[selector.length - 1] == ']')
|
||||||
|
selector += '/';
|
||||||
|
|
||||||
return new ObjectInspector(obj);
|
const levels = selector.split('/');
|
||||||
|
|
||||||
|
for (const level of levels) {
|
||||||
|
const [name, indexPart] = level.split('[');
|
||||||
|
let index = 0;
|
||||||
|
if (indexPart) {
|
||||||
|
const i = indexPart.indexOf(']');
|
||||||
|
index = parseInt(indexPart.substring(0, i), 10) || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let type = NODE;
|
||||||
|
if (name[0] === '*') {
|
||||||
|
const typeName = name.substring(1);
|
||||||
|
type = name2type[typeName];
|
||||||
|
if (!type)
|
||||||
|
throw new Error(`Unknown selector type: ${typeName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push({type, name, index});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.length);
|
||||||
|
result[result.length - 1].last = true;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inspect(selector = '') {
|
||||||
|
selector = this.narrowSelector(selector);
|
||||||
|
|
||||||
|
let raw = this.rawNodes;
|
||||||
|
for (const s of selector) {
|
||||||
|
if (s.name) {
|
||||||
|
let found = [];
|
||||||
|
for (const n of raw) {
|
||||||
|
if (n[0] === s.type && (n[0] !== NODE || s.name === '*NODE' || n[1] === s.name)) {
|
||||||
|
found.push(n);
|
||||||
|
|
||||||
|
if (found.length > s.index && !s.last)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
raw = found;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw.length && !s.last) {
|
||||||
|
if (s.index < raw.length) {
|
||||||
|
raw = raw[s.index];
|
||||||
|
if (raw[0] === NODE && raw[3])
|
||||||
|
raw = raw[3];
|
||||||
|
else {
|
||||||
|
raw = [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
raw = [];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new XmlParser(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
$$(selector) {
|
||||||
|
return this.inspect(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
$$array(selector) {
|
||||||
|
const res = this.inspect(selector);
|
||||||
|
const result = [];
|
||||||
|
for (const n of res.rawNodes)
|
||||||
|
if (n[0] === NODE)
|
||||||
|
result.push(new XmlParser([n]));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(selector) {
|
||||||
|
const res = this.inspect(selector);
|
||||||
|
const node = (res.count ? res.rawNodes[0] : null);
|
||||||
|
return new NodeObject(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
v(selector = '') {
|
||||||
|
const res = this.$(selector);
|
||||||
|
return (res.type ? res.value : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
text(selector = '') {
|
||||||
|
const res = this.$(`${selector}/*TEXT`);
|
||||||
|
return (res.type === TEXT ? res.value : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
comment(selector = '') {
|
||||||
|
const res = this.$(`${selector}/*COMMENT`);
|
||||||
|
return (res.type === COMMENT ? res.value : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
cdata(selector = '') {
|
||||||
|
const res = this.$(`${selector}/*CDATA`);
|
||||||
|
return (res.type === CDATA ? res.value : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
concat(selector = '') {
|
||||||
|
const res = this.$$(selector);
|
||||||
|
const out = [];
|
||||||
|
for (const n of res.rawNodes) {
|
||||||
|
const node = new NodeObject(n);
|
||||||
|
if (node.type && node.type !== NODE)
|
||||||
|
out.push(node.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (out.length ? out.join('') : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs(selector = '') {
|
||||||
|
const res = this.$(selector);
|
||||||
|
const attrs = res.attrs();
|
||||||
|
return (res.type === NODE && attrs ? Object.fromEntries(attrs) : null);
|
||||||
|
}
|
||||||
|
// XML Inspector finish
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = XmlParser;
|
module.exports = XmlParser;
|
||||||
@@ -191,7 +191,7 @@ function initStatic(app, config) {
|
|||||||
|
|
||||||
if (path.extname(req.path) == '') {
|
if (path.extname(req.path) == '') {
|
||||||
const bookFile = `${config.publicFilesDir}${req.path}`;
|
const bookFile = `${config.publicFilesDir}${req.path}`;
|
||||||
const bookFileDesc = `${bookFile}.json`;
|
const bookFileDesc = `${bookFile}.d.json`;
|
||||||
|
|
||||||
let downFileName = '';
|
let downFileName = '';
|
||||||
//восстановим из json-файла описания
|
//восстановим из json-файла описания
|
||||||
|
|||||||
Reference in New Issue
Block a user