diff --git a/client/components/Reader/HistoryPage/HistoryPage.vue b/client/components/Reader/HistoryPage/HistoryPage.vue index 630654a1..a9884b13 100644 --- a/client/components/Reader/HistoryPage/HistoryPage.vue +++ b/client/components/Reader/HistoryPage/HistoryPage.vue @@ -141,17 +141,27 @@ class HistoryPage extends Vue { } const fb2 = (book.fb2 ? book.fb2 : {}); + + let title = fb2.bookTitle; + if (title) + title = `"${title}"`; + else + title = ''; + + let author = _.compact([ + fb2.lastName, + fb2.firstName, + fb2.middleName + ]).join(' '); + author = (author ? author : (fb2.bookTitle ? fb2.bookTitle : book.url)); + result.push({ touchDateTime: book.touchTime, touchDate: t[0], touchTime: t[1], desc: { - title: `"${fb2.bookTitle}"${perc}${textLen}`, - author: _.compact([ - fb2.lastName, - fb2.firstName, - fb2.middleName - ]).join(' '), + title: `${title}${perc}${textLen}`, + author, }, url: book.url, path: book.path, diff --git a/client/components/Reader/Reader.vue b/client/components/Reader/Reader.vue index 80b2a5b0..97b62e5e 100644 --- a/client/components/Reader/Reader.vue +++ b/client/components/Reader/Reader.vue @@ -440,51 +440,55 @@ class Reader extends Vue { buttonClick(button) { const activeClass = this.buttonActiveClass(button); - if (!activeClass['tool-button-disabled']) - switch (button) { - case 'loader': - this.loaderToggle(); - break; - case 'undoAction': - if (this.actionCur > 0) { - this.actionCur--; - this.bookPosChanged({bookPos: this.actionList[this.actionCur]}); - } - break; - case 'redoAction': - if (this.actionCur < this.actionList.length - 1) { - this.actionCur++; - this.bookPosChanged({bookPos: this.actionList[this.actionCur]}); - } - break; - case 'fullScreen': - this.fullScreenToggle(); - break; - case 'setPosition': - this.setPositionToggle(); - break; - case 'scrolling': - this.scrollingToggle(); - break; - case 'search': - this.searchToggle(); - break; - case 'copyText': - this.copyTextToggle(); - break; - case 'history': - this.historyToggle(); - break; - case 'refresh': - if (this.mostRecentBook()) { - this.loadBook({url: this.mostRecentBook().url, force: true}); - } - break; - case 'settings': - this.settingsToggle(); - break; - } + this.$refs[button].$el.blur(); + + if (activeClass['tool-button-disabled']) + return; + + switch (button) { + case 'loader': + this.loaderToggle(); + break; + case 'undoAction': + if (this.actionCur > 0) { + this.actionCur--; + this.bookPosChanged({bookPos: this.actionList[this.actionCur]}); + } + break; + case 'redoAction': + if (this.actionCur < this.actionList.length - 1) { + this.actionCur++; + this.bookPosChanged({bookPos: this.actionList[this.actionCur]}); + } + break; + case 'fullScreen': + this.fullScreenToggle(); + break; + case 'setPosition': + this.setPositionToggle(); + break; + case 'scrolling': + this.scrollingToggle(); + break; + case 'search': + this.searchToggle(); + break; + case 'copyText': + this.copyTextToggle(); + break; + case 'history': + this.historyToggle(); + break; + case 'refresh': + if (this.mostRecentBook()) { + this.loadBook({url: this.mostRecentBook().url, force: true}); + } + break; + case 'settings': + this.settingsToggle(); + break; + } } buttonActiveClass(button) { @@ -591,14 +595,19 @@ class Reader extends Vue { } loadBook(opts) { - if (!opts) { + if (!opts || !opts.url) { this.mostRecentBook(); return; } + let url = opts.url; + if ((url.indexOf('http://') != 0) && (url.indexOf('https://') != 0) && + (url.indexOf('file://') != 0)) + url = 'http://' + url; + // уже просматривается сейчас const lastBook = (this.$refs.page ? this.$refs.page.lastBook : null); - if (!opts.force && lastBook && lastBook.url == opts.url && bookManager.hasBookParsed(lastBook)) { + if (!opts.force && lastBook && lastBook.url == url && bookManager.hasBookParsed(lastBook)) { this.loaderActive = false; return; } @@ -615,7 +624,7 @@ class Reader extends Vue { progress.setState({state: 'parse'}); // есть ли среди недавних - const key = bookManager.keyFromUrl(opts.url); + const key = bookManager.keyFromUrl(url); let wasOpened = await bookManager.getRecentBook({key}); wasOpened = (wasOpened ? wasOpened : {}); const bookPos = (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPos); @@ -626,7 +635,7 @@ class Reader extends Vue { if (!opts.force) { // пытаемся загрузить и распарсить книгу в менеджере из локального кэша - const bookParsed = await bookManager.getBook({url: opts.url}, (prog) => { + const bookParsed = await bookManager.getBook({url}, (prog) => { progress.setState({progress: prog}); }); @@ -662,7 +671,7 @@ class Reader extends Vue { // не удалось, скачиваем книгу полностью с конвертацией let loadCached = true; if (!book) { - book = await readerApi.loadBook(opts.url, (state) => { + book = await readerApi.loadBook(url, (state) => { progress.setState(state); }); loadCached = false; diff --git a/package.json b/package.json index 7bddb107..c57049b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Liberama", - "version": "0.1.2", + "version": "0.1.3", "engines": { "node": ">=10.0.0" }, diff --git a/server/core/BookConverter/index.js b/server/core/BookConverter/index.js index 1a6adaf9..9160629c 100644 --- a/server/core/BookConverter/index.js +++ b/server/core/BookConverter/index.js @@ -22,8 +22,8 @@ class BookConverter { callback(100); if (fileType && (fileType.ext == 'html' || fileType.ext == 'xml')) { - if (data.toString().indexOf('= 0) { - await fs.writeFile(outputFile, data); + if (data.toString().indexOf('= 0) { + await fs.writeFile(outputFile, this.checkEncoding(data)); return; } @@ -69,6 +69,28 @@ class BookConverter { return iconv.decode(data, selected); } + checkEncoding(data) { + let result = data; + + const left = data.indexOf('= 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 encoding = m[1].toLowerCase(); + if (encoding != 'utf-8') { + result = iconv.decode(data, encoding); + result = Buffer.from(result.toString().replace(m[0], 'encoding="utf-8"')); + } + } + } + } + + return result; + } + convertHtml(data, isText) { let titleInfo = {}; let desc = {_n: 'description', 'title-info': titleInfo}; diff --git a/server/core/BookConverter/textUtils.js b/server/core/BookConverter/textUtils.js index 2471c1ec..316f0ec7 100644 --- a/server/core/BookConverter/textUtils.js +++ b/server/core/BookConverter/textUtils.js @@ -62,7 +62,10 @@ function getEncoding(buf) { sorted.sort((a, b) => b.c - a.c); - return sorted[0].codePage; + if (sorted[0].c > 0) + return sorted[0].codePage; + else + return 'ISO-8859-5'; } function checkIfText(buf) {