Compare commits

...

29 Commits

Author SHA1 Message Date
Book Pauk
4ae7338f94 Merge branch 'release/0.7.3b' 2019-10-19 19:28:36 +07:00
Book Pauk
0d1e51cb21 Поправка бага 2019-10-19 19:27:18 +07:00
Book Pauk
475fb833ea Merge tag '0.7.3' into develop
0.7.3
2019-10-18 19:30:51 +07:00
Book Pauk
580b030ee4 Merge branch 'release/0.7.3' 2019-10-18 19:30:42 +07:00
Book Pauk
6a7cbc70d6 0.7.3 2019-10-18 19:30:21 +07:00
Book Pauk
d76f60639c Добавлен параметр "Включить html-фильтр для сайтов" в раздел "Вид"->"Текст" в настройках 2019-10-18 19:13:17 +07:00
Book Pauk
e2bea407ee 0.7.3 2019-10-18 17:12:30 +07:00
Book Pauk
558fed31aa Добавлен фильтр для некоторых сайтов 2019-10-18 17:07:28 +07:00
Book Pauk
f6513d40c8 Небольшая поправка 2019-10-18 15:32:05 +07:00
Book Pauk
259f9baa59 Merge branch 'feature/ss_fix2' into develop 2019-10-18 15:25:57 +07:00
Book Pauk
db5650e276 Мелкая поправка 2019-10-18 15:20:32 +07:00
Book Pauk
51ebbbc569 Закончена очередная переработка loadRecent & saveRecent 2019-10-18 15:19:53 +07:00
Book Pauk
5184661652 Мелкая поправка 2019-10-18 14:00:52 +07:00
Book Pauk
7853a14ce6 Начало очередной переделки ServerStorage 2019-10-18 13:53:44 +07:00
Book Pauk
a01e78ace9 Merge tag '0.7.2' into develop
0.7.2
2019-10-18 09:17:58 +07:00
Book Pauk
f7eb576d0d Merge branch 'release/0.7.2' 2019-10-18 09:17:45 +07:00
Book Pauk
34f1ad8fae Версия 0.7.2 2019-10-18 09:16:52 +07:00
Book Pauk
c60f0991df Правка багов 2019-10-18 09:06:04 +07:00
Book Pauk
d505fd0795 Мелкая поправка 2019-10-17 21:38:13 +07:00
Book Pauk
93cf506535 Поправка бага 2019-10-17 20:38:52 +07:00
Book Pauk
bfb37e55d4 Поправка отображения прогрессбара загрузки книги 2019-10-17 19:18:56 +07:00
Book Pauk
92afc5cb33 Поправки багов 2019-10-17 19:09:05 +07:00
Book Pauk
75cb611701 Поправки багов 2019-10-17 17:20:43 +07:00
Book Pauk
2ec1dd58a5 Добавлена ссылка "Старая версия" 2019-10-17 13:49:24 +07:00
Book Pauk
7d59af54de Улучшил определение кодировки 2019-10-16 21:48:41 +07:00
Book Pauk
2b5f47b3de Замена decompress-zip на adm-zip 2019-10-16 21:08:34 +07:00
Book Pauk
16eebfb9a4 Поправил текст ссылки 2019-10-16 16:41:26 +07:00
Book Pauk
9025218671 Мелкая поправка 2019-10-16 11:19:40 +07:00
Book Pauk
6bccb546bb Merge tag '0.7.1e' into develop
0.7.1e
2019-09-21 11:29:57 +07:00
20 changed files with 343 additions and 282 deletions

View File

@@ -1,6 +1,4 @@
import _ from 'lodash';
import axios from 'axios'; import axios from 'axios';
import {Buffer} from 'safe-buffer';
import * as utils from '../share/utils'; import * as utils from '../share/utils';
@@ -13,11 +11,11 @@ const workerApi = axios.create({
}); });
class Reader { class Reader {
async loadBook(url, callback) { async loadBook(opts, callback) {
const refreshPause = 300; const refreshPause = 300;
if (!callback) callback = () => {}; if (!callback) callback = () => {};
let response = await api.post('/load-book', {type: 'url', url}); let response = await api.post('/load-book', opts);
const workerId = response.data.workerId; const workerId = response.data.workerId;
if (!workerId) if (!workerId)
@@ -66,12 +64,13 @@ class Reader {
estSize = response.headers['content-length']; estSize = response.headers['content-length'];
} }
callback({state: 'loading', progress: 0});
const options = { const options = {
onDownloadProgress: progress => { onDownloadProgress: progress => {
while (progress.loaded > estSize) estSize *= 1.5; while (progress.loaded > estSize) estSize *= 1.5;
if (callback) if (callback)
callback({state: 'loading', progress: Math.round((progress.loaded*100)/estSize)}); callback({progress: Math.round((progress.loaded*100)/estSize)});
} }
} }
//загрузка //загрузка

View File

@@ -24,10 +24,14 @@
<div v-show="mode == 'omnireader'"> <div v-show="mode == 'omnireader'">
<p>Вы можете добавить в свой браузер закладку, указав в ее свойствах вместо адреса следующий код: <p>Вы можете добавить в свой браузер закладку, указав в ее свойствах вместо адреса следующий код:
<br><span class="clickable" @click="copyText('javascript:location.href=\'https://omnireader.ru/?url=\'+location.href;', 'Код для адреса закладки успешно скопирован в буфер обмена')"> <br><strong>javascript:location.href='https://omnireader.ru/?url='+location.href;</strong>
<strong>javascript:location.href='https://omnireader.ru/?url='+location.href;</strong> &nbsp;
<span class="clickable" @click="copyText('javascript:location.href=\'https://omnireader.ru/?url=\'+location.href;', 'Код для адреса закладки успешно скопирован в буфер обмена')">
(скопировать)
</span> </span>
<br>Тогда, активировав получившуюся закладку на любой странице интернета, вы автоматически откроете ее в Omni Reader. <br>или перетащив на панель закладок следующую ссылку:
<br><a style="margin-left: 50px" href="javascript:location.href='https://omnireader.ru/?url='+location.href;">Omni Reader</a>
<br>Тогда, активировав получившуюся закладку на любой странице интернета, вы автоматически загрузите эту страницу в Omni Reader.
<br>В Chrome для Android можно вызывать такую закладку по имени прямо в адресной строке браузера (имя стоит сделать попроще). <br>В Chrome для Android можно вызывать такую закладку по имени прямо в адресной строке браузера (имя стоит сделать попроще).
</p> </p>
</div> </div>

View File

@@ -31,6 +31,7 @@
</div> </div>
<div class="space"></div> <div class="space"></div>
<span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="openComments">Отзывы о читалке</span> <span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="openComments">Отзывы о читалке</span>
<span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="openOldVersion">Старая версия</span>
</div> </div>
<div class="part bottom"> <div class="part bottom">
@@ -137,6 +138,10 @@ class LoaderPage extends Vue {
window.open('http://samlib.ru/comment/b/bookpauk/bookpauk_reader', '_blank'); window.open('http://samlib.ru/comment/b/bookpauk/bookpauk_reader', '_blank');
} }
openOldVersion() {
window.open('http://old.omnireader.ru', '_blank');
}
keyHook(event) { keyHook(event) {
if (this.pasteTextActive) { if (this.pasteTextActive) {
return this.$refs.pasteTextPage.keyHook(event); return this.$refs.pasteTextPage.keyHook(event);

View File

@@ -356,6 +356,7 @@ class Reader extends Vue {
this.showWhatsNewDialog = settings.showWhatsNewDialog; this.showWhatsNewDialog = settings.showWhatsNewDialog;
this.showMigrationDialog = settings.showMigrationDialog; this.showMigrationDialog = settings.showMigrationDialog;
this.showToolButton = settings.showToolButton; this.showToolButton = settings.showToolButton;
this.enableSitesFilter = settings.enableSitesFilter;
this.updateHeaderMinWidth(); this.updateHeaderMinWidth();
} }
@@ -510,29 +511,35 @@ class Reader extends Vue {
} }
async bookManagerEvent(eventName) { async bookManagerEvent(eventName) {
if (eventName == 'recent-changed') { if (eventName == 'set-recent' || eventName == 'recent-deleted') {
if (this.recentBooksActive) { const oldBook = (this.textPage ? this.textPage.lastBook : null);
await this.$refs.recentBooksPage.updateTableData(); const oldPos = (this.textPage ? this.textPage.bookPos : null);
} const newBook = bookManager.mostRecentBook();
if (!(oldBook && newBook && oldBook.key == newBook.key)) {
this.mostRecentBook();
} }
if (eventName == 'set-recent' || eventName == 'recent-deleted') {
const oldBook = this.mostRecentBookReactive;
const newBook = bookManager.mostRecentBook();
if (oldBook && newBook) { if (oldBook && newBook) {
if (oldBook.key != newBook.key) { if (oldBook.key != newBook.key || oldBook.path != newBook.path) {
this.loadingBook = true; this.loadingBook = true;
try { try {
await this.loadBook(newBook); await this.loadBook(newBook);
} finally { } finally {
this.loadingBook = false; this.loadingBook = false;
} }
} else if (oldBook.bookPos != newBook.bookPos) { } else if (oldPos != newBook.bookPos) {
while (this.loadingBook) await utils.sleep(100); while (this.loadingBook) await utils.sleep(100);
this.bookPosChanged({bookPos: newBook.bookPos}); this.bookPosChanged({bookPos: newBook.bookPos});
} }
} }
} }
if (eventName == 'recent-changed') {
if (this.recentBooksActive) {
await this.$refs.recentBooksPage.updateTableData();
}
}
} }
get toolBarActive() { get toolBarActive() {
@@ -903,6 +910,7 @@ class Reader extends Vue {
this.updateRoute(); this.updateRoute();
const textPage = this.$refs.page; const textPage = this.$refs.page;
if (textPage.showBook) { if (textPage.showBook) {
this.textPage = textPage;
textPage.lastBook = last; textPage.lastBook = last;
textPage.bookPos = (last.bookPos !== undefined ? last.bookPos : 0); textPage.bookPos = (last.bookPos !== undefined ? last.bookPos : 0);
@@ -927,8 +935,10 @@ class Reader extends Vue {
url = 'http://' + url; url = 'http://' + url;
// уже просматривается сейчас // уже просматривается сейчас
const lastBook = (this.$refs.page ? this.$refs.page.lastBook : null); const lastBook = (this.textPage ? this.textPage.lastBook : null);
if (!opts.force && lastBook && lastBook.url == url && await bookManager.hasBookParsed(lastBook)) { if (!opts.force && lastBook && lastBook.url == url &&
(!opts.path || opts.path == lastBook.path) &&
await bookManager.hasBookParsed(lastBook)) {
this.loaderActive = false; this.loaderActive = false;
return; return;
} }
@@ -957,7 +967,7 @@ class Reader extends Vue {
if (!opts.force) { if (!opts.force) {
// пытаемся загрузить и распарсить книгу в менеджере из локального кэша // пытаемся загрузить и распарсить книгу в менеджере из локального кэша
const bookParsed = await bookManager.getBook({url}, (prog) => { const bookParsed = await bookManager.getBook({url, path: opts.path}, (prog) => {
progress.setState({progress: prog}); progress.setState({progress: prog});
}); });
@@ -978,6 +988,7 @@ class Reader extends Vue {
// иначе идем на сервер // иначе идем на сервер
// пытаемся загрузить готовый файл с сервера // пытаемся загрузить готовый файл с сервера
if (wasOpened.path) { if (wasOpened.path) {
progress.setState({totalSteps: 5});
try { try {
const resp = await readerApi.loadCachedBook(wasOpened.path, (state) => { const resp = await readerApi.loadCachedBook(wasOpened.path, (state) => {
progress.setState(state); progress.setState(state);
@@ -993,7 +1004,7 @@ class Reader extends Vue {
// не удалось, скачиваем книгу полностью с конвертацией // не удалось, скачиваем книгу полностью с конвертацией
let loadCached = true; let loadCached = true;
if (!book) { if (!book) {
book = await readerApi.loadBook(url, (state) => { book = await readerApi.loadBook({url, enableSitesFilter: this.enableSitesFilter}, (state) => {
progress.setState(state); progress.setState(state);
}); });
loadCached = false; loadCached = false;
@@ -1063,7 +1074,7 @@ class Reader extends Vue {
let page = this.$refs.page; let page = this.$refs.page;
while (this.blinkCount) { while (this.blinkCount) {
this.showRefreshIcon = !this.showRefreshIcon; this.showRefreshIcon = !this.showRefreshIcon;
if (page.blinkCachedLoadMessage) if (page && page.blinkCachedLoadMessage)
page.blinkCachedLoadMessage(this.showRefreshIcon); page.blinkCachedLoadMessage(this.showRefreshIcon);
await utils.sleep(500); await utils.sleep(500);
if (this.stopBlink) if (this.stopBlink)
@@ -1073,7 +1084,7 @@ class Reader extends Vue {
} }
this.showRefreshIcon = true; this.showRefreshIcon = true;
this.inBlink = false; this.inBlink = false;
if (page.blinkCachedLoadMessage) if (page && page.blinkCachedLoadMessage)
page.blinkCachedLoadMessage('finish'); page.blinkCachedLoadMessage('finish');
}); });
} }

View File

@@ -251,6 +251,7 @@ class RecentBooksPage extends Vue {
} }
if (this.tableData.length > result.length) if (this.tableData.length > result.length)
this.tableData.splice(result.length);*/ this.tableData.splice(result.length);*/
this.tableData = result; this.tableData = result;
this.updating = false; this.updating = false;
} }

View File

@@ -13,6 +13,11 @@ import readerApi from '../../../api/reader';
import * as utils from '../../../share/utils'; import * as utils from '../../../share/utils';
import * as cryptoUtils from '../../../share/cryptoUtils'; import * as cryptoUtils from '../../../share/cryptoUtils';
import localForage from 'localforage';
const ssCacheStore = localForage.createInstance({
name: 'ssCacheStore'
});
export default @Component({ export default @Component({
watch: { watch: {
serverSyncEnabled: function() { serverSyncEnabled: function() {
@@ -58,35 +63,52 @@ class ServerStorage extends Vue {
async init() { async init() {
try { try {
this.cachedRecent = await ssCacheStore.getItem('recent');
if (!this.cachedRecent)
await this.setCachedRecent({rev: 0, data: {}});
this.cachedRecentPatch = await ssCacheStore.getItem('recent-patch');
if (!this.cachedRecentPatch)
await this.setCachedRecentPatch({rev: 0, data: {}});
this.cachedRecentMod = await ssCacheStore.getItem('recent-mod');
if (!this.cachedRecentMod)
await this.setCachedRecentMod({rev: 0, data: {}});
if (!this.serverStorageKey) { if (!this.serverStorageKey) {
//генерируем новый ключ //генерируем новый ключ
await this.generateNewServerStorageKey(); await this.generateNewServerStorageKey();
} else { } else {
await this.serverStorageKeyChanged(); await this.serverStorageKeyChanged();
} }
bookManager.addEventListener(this.bookManagerEvent); bookManager.addEventListener(this.bookManagerEvent);
} finally { } finally {
this.inited = true; this.inited = true;
} }
} }
async setCachedRecent(value) {
await ssCacheStore.setItem('recent', value);
this.cachedRecent = value;
}
async setCachedRecentPatch(value) {
await ssCacheStore.setItem('recent-patch', value);
this.cachedRecentPatch = value;
}
async setCachedRecentMod(value) {
await ssCacheStore.setItem('recent-mod', value);
this.cachedRecentMod = value;
}
async bookManagerEvent(eventName, itemKey) { async bookManagerEvent(eventName, itemKey) {
if (!this.serverSyncEnabled) if (!this.serverSyncEnabled)
return; return;
if (eventName == 'recent-changed') { if (eventName == 'recent-changed') {
if (itemKey) { if (itemKey) {
if (!this.recentDeltaInited) {
await this.loadRecent();
this.warning('Функции сохранения на сервер пока недоступны');
return;
}
if (!this.recentDelta)
this.recentDelta = {};
this.recentDelta[itemKey] = _.cloneDeep(bookManager.recent[itemKey]);
this.debouncedSaveRecent(itemKey); this.debouncedSaveRecent(itemKey);
} }
} }
@@ -119,8 +141,8 @@ class ServerStorage extends Vue {
await this.loadProfiles(force); await this.loadProfiles(force);
this.checkCurrentProfile(); this.checkCurrentProfile();
await this.currentProfileChanged(force); await this.currentProfileChanged(force);
await this.loadRecent(); const loadSuccess = await this.loadRecent();
if (force) if (loadSuccess && force)
await this.saveRecent(); await this.saveRecent();
} }
} }
@@ -340,46 +362,26 @@ class ServerStorage extends Vue {
} }
} }
async initRecentDelta() {
let recentDelta = null;
try {
recentDelta = await this.storageGet({recentDelta: {}});
} catch(e) {
this.error(`Ошибка соединения с сервером: ${e.message}`);
return;
}
if (recentDelta.state == 'success') {
recentDelta = recentDelta.items.recentDelta;
if (recentDelta.rev == 0)
recentDelta.data = {};
this.recentDelta = recentDelta.data;
this.recentDeltaInited = true;
} else {
this.warning(`Неверный ответ сервера: ${recentDelta.state}`);
}
}
async loadRecent(skipRevCheck = false, doNotifySuccess = true) { async loadRecent(skipRevCheck = false, doNotifySuccess = true) {
if (!this.keyInited || !this.serverSyncEnabled || this.loadingRecent) if (!this.keyInited || !this.serverSyncEnabled || this.loadingRecent)
return; return;
this.loadingRecent = true; this.loadingRecent = true;
try { try {
const oldRecentRev = bookManager.recentRev;
const oldRecentDeltaRev = bookManager.recentDeltaRev;
//проверим ревизию на сервере //проверим ревизию на сервере
let query = {recent: {}, recentPatch: {}, recentMod: {}};
let revs = null; let revs = null;
if (!skipRevCheck) { if (!skipRevCheck) {
try { try {
revs = await this.storageCheck({recent: {}, recentDelta: {}}); revs = await this.storageCheck(query);
if (revs.state == 'success' && revs.items.recent.rev == oldRecentRev && if (revs.state == 'success') {
revs.items.recentDelta.rev == oldRecentDeltaRev) { if (revs.items.recent.rev != this.cachedRecent.rev) {
if (!this.recentDeltaInited) //no changes
await this.initRecentDelta(); } else if (revs.items.recentPatch.rev != this.cachedRecentPatch.rev) {
return; query = {recentPatch: {}, recentMod: {}};
} else if (revs.items.recentMod.rev != this.cachedRecentMod.rev) {
query = {recentMod: {}};
} else
return true;
} }
} catch(e) { } catch(e) {
this.error(`Ошибка соединения с сервером: ${e.message}`); this.error(`Ошибка соединения с сервером: ${e.message}`);
@@ -389,46 +391,53 @@ class ServerStorage extends Vue {
let recent = null; let recent = null;
try { try {
recent = await this.storageGet({recent: {}, recentDelta: {}}); recent = await this.storageGet(query);
} catch(e) { } catch(e) {
this.error(`Ошибка соединения с сервером: ${e.message}`); this.error(`Ошибка соединения с сервером: ${e.message}`);
return; return;
} }
if (recent.state == 'success') { if (recent.state == 'success') {
let recentDelta = recent.items.recentDelta; let newRecent = recent.items.recent;
recent = recent.items.recent; let newRecentPatch = recent.items.recentPatch;
let newRecentMod = recent.items.recentMod;
if (recent.rev == 0) if (!newRecent) {
recent.data = {}; newRecent = _.cloneDeep(this.cachedRecent);
let newRecent = {};
if (recentDelta && recentDelta.data) {
if (recentDelta.data.diff) {
newRecent = recent.data;
const key = recentDelta.data.diff.key;
if (newRecent[key])
newRecent[key] = utils.applyObjDiff(newRecent[key], recentDelta.data.diff);
} else {
newRecent = Object.assign(recent.data, recentDelta.data);
} }
this.recentDelta = recentDelta.data; if (!newRecentPatch) {
} else { newRecentPatch = _.cloneDeep(this.cachedRecentPatch);
newRecent = recent.data; }
this.recentDelta = {}; if (!newRecentMod) {
newRecentMod = _.cloneDeep(this.cachedRecentMod);
} }
this.recentDeltaInited = true; if (newRecent.rev == 0) newRecent.data = {};
if (newRecentPatch.rev == 0) newRecentPatch.data = {};
if (newRecentMod.rev == 0) newRecentMod.data = {};
let result = Object.assign({}, newRecent.data, newRecentPatch.data);
const md = newRecentMod.data;
if (md.key && result[md.key])
result[md.key] = utils.applyObjDiff(result[md.key], md.mod);
if (newRecent.rev != this.cachedRecent.rev)
await this.setCachedRecent(newRecent);
if (newRecentPatch.rev != this.cachedRecentPatch.rev)
await this.setCachedRecentPatch(newRecentPatch);
if (newRecentMod.rev != this.cachedRecentMod.rev)
await this.setCachedRecentMod(newRecentMod);
if (!bookManager.loaded) { if (!bookManager.loaded) {
this.warning('Ожидание загрузки списка книг перед синхронизацией'); this.warning('Ожидание загрузки списка книг перед синхронизацией');
while (!bookManager.loaded) await utils.sleep(100); while (!bookManager.loaded) await utils.sleep(100);
} }
await bookManager.setRecent(newRecent);
await bookManager.setRecentRev(recent.rev); await bookManager.setRecent(result);
await bookManager.setRecentDeltaRev(recentDelta.rev);
} else { } else {
this.warning(`Неверный ответ сервера: ${recent.state}`); this.warning(`Неверный ответ сервера: ${recent.state}`);
return;
} }
if (doNotifySuccess) if (doNotifySuccess)
@@ -436,6 +445,7 @@ class ServerStorage extends Vue {
} finally { } finally {
this.loadingRecent = false; this.loadingRecent = false;
} }
return true;
} }
async saveRecent(itemKey, recurse) { async saveRecent(itemKey, recurse) {
@@ -444,91 +454,87 @@ class ServerStorage extends Vue {
const bm = bookManager; const bm = bookManager;
//вычисление критерия сохранения целиком let needSaveRecent = false;
if (!this.sameKeyCount) let needSaveRecentPatch = false;
this.sameKeyCount = 0; let needSaveRecentMod = false;
if (this.prevItemKey == itemKey) {
this.sameKeyCount++; //newRecentMod
} else { let newRecentMod = {};
this.sameKeyCount = 0; if (itemKey && this.cachedRecentPatch.data[itemKey] && this.prevItemKey == itemKey) {
newRecentMod = _.cloneDeep(this.cachedRecentMod);
newRecentMod.rev++;
newRecentMod.data.key = itemKey;
newRecentMod.data.mod = utils.getObjDiff(this.cachedRecentPatch.data[itemKey], bm.recent[itemKey]);
needSaveRecentMod = true;
} }
const l = Object.keys(this.recentDelta).length - (1*(!!this.recentDelta.diff));
this.makeDeltaDiff = (l == 1 && this.prevItemKey == itemKey ? this.makeDeltaDiff : false);
const forceSaveRecent = l > 10 || (this.sameKeyCount > 5 && (l > 1)) || (l == 1 && this.sameKeyCount > 10 && !this.makeDeltaDiff);
this.sameKeyCount = (!forceSaveRecent ? this.sameKeyCount : 0);
this.prevItemKey = itemKey; this.prevItemKey = itemKey;
//дифф от дельты для уменьшения размера передаваемых данных в частном случае //newRecentPatch
if (this.makeDeltaDiff) { let newRecentPatch = {};
this.recentDelta.diff = utils.getObjDiff(this.prevSavedItem, bm.recent[itemKey]); if (itemKey && !needSaveRecentMod) {
this.recentDelta.diff.key = itemKey; newRecentPatch = _.cloneDeep(this.cachedRecentPatch);
delete this.recentDelta[itemKey]; newRecentPatch.rev++;
} else if (this.recentDelta.diff) { newRecentPatch.data[itemKey] = bm.recent[itemKey];
const key = this.recentDelta.diff.key;
if (!this.prevSavedItem && bm.recent[key]) let applyMod = this.cachedRecentMod.data;
this.prevSavedItem = _.cloneDeep(bm.recent[key]); if (applyMod && applyMod.key && newRecentPatch.data[applyMod.key])
if (this.prevSavedItem) { newRecentPatch.data[applyMod.key] = utils.applyObjDiff(newRecentPatch.data[applyMod.key], applyMod.mod);
this.recentDelta[key] = utils.applyObjDiff(this.prevSavedItem, this.recentDelta.diff);
newRecentMod = {rev: this.cachedRecentMod.rev + 1, data: {}};
needSaveRecentPatch = true;
needSaveRecentMod = true;
} }
delete this.recentDelta.diff;
//newRecent
let newRecent = {};
if (!itemKey || (needSaveRecentPatch && Object.keys(newRecentPatch.data).length > 10)) {
newRecent = {rev: this.cachedRecent.rev + 1, data: bm.recent};
newRecentPatch = {rev: this.cachedRecentPatch.rev + 1, data: {}};
newRecentMod = {rev: this.cachedRecentMod.rev + 1, data: {}};
needSaveRecent = true;
needSaveRecentPatch = true;
needSaveRecentMod = true;
}
//query
let query = {};
if (needSaveRecent) {
query = {recent: newRecent, recentPatch: newRecentPatch, recentMod: newRecentMod};
} else if (needSaveRecentPatch) {
query = {recentPatch: newRecentPatch, recentMod: newRecentMod};
} else {
query = {recentMod: newRecentMod};
} }
//сохранение //сохранение
this.savingRecent = true; this.savingRecent = true;
try { try {
if (forceSaveRecent) {//сохраняем recent целиком
let result = {state: ''}; let result = {state: ''};
try { try {
result = await this.storageSet({recent: {rev: bm.recentRev + 1, data: bm.recent}, recentDelta: {rev: bm.recentDeltaRev + 1, data: {}}}); result = await this.storageSet(query);
} catch(e) { } catch(e) {
this.error(`Ошибка соединения с сервером (${e.message}). Данные не сохранены и могут быть перезаписаны.`); this.error(`Ошибка соединения с сервером (${e.message}). Данные не сохранены и могут быть перезаписаны.`);
} }
if (result.state == 'reject') { if (result.state == 'reject') {
await this.loadRecent(true, false); await this.loadRecent(false, false);
this.warning(`Последние изменения отменены. Данные синхронизированы с сервером.`); this.warning(`Последние изменения отменены. Данные синхронизированы с сервером.`);
if (!recurse) { if (!recurse && itemKey) {
this.savingRecent = false; this.savingRecent = false;
this.recentDelta[itemKey] = _.cloneDeep(bm.recent[itemKey]);
this.saveRecent(itemKey, true); this.saveRecent(itemKey, true);
return; return;
} }
} else if (result.state == 'success') { } else if (result.state == 'success') {
this.makeDeltaDiff = true; if (needSaveRecent && newRecent.rev)
this.prevSavedItem = _.cloneDeep(bm.recent[itemKey]); await this.setCachedRecent(newRecent);
if (needSaveRecentPatch && newRecentPatch.rev)
this.recentDelta = {}; await this.setCachedRecentPatch(newRecentPatch);
await bm.setRecentRev(bm.recentRev + 1); if (needSaveRecentMod && newRecentMod.rev)
await bm.setRecentDeltaRev(bm.recentDeltaRev + 1); await this.setCachedRecentMod(newRecentMod);
}
} else {//сохраняем только дифф
let result = {state: ''};
try {
result = await this.storageSet({recentDelta: {rev: bm.recentDeltaRev + 1, data: this.recentDelta}});
} catch(e) {
this.error(`Ошибка соединения с сервером (${e.message}). Данные не сохранены и могут быть перезаписаны.`);
}
if (result.state == 'reject') {
await this.loadRecent(true, false);
this.warning(`Последние изменения отменены. Данные синхронизированы с сервером.`);
if (!recurse) {
this.savingRecent = false;
this.recentDelta[itemKey] = _.cloneDeep(bm.recent[itemKey]);
this.saveRecent(itemKey, true);
return;
}
} else if (result.state == 'success') {
await bm.setRecentDeltaRev(bm.recentDeltaRev + 1);
}
} }
} finally { } finally {
this.savingRecent = false; this.savingRecent = false;

View File

@@ -304,6 +304,19 @@
</el-col> </el-col>
<el-input-number v-model="addEmptyParagraphs" :min="0" :max="2"></el-input-number> <el-input-number v-model="addEmptyParagraphs" :min="0" :max="2"></el-input-number>
</el-form-item> </el-form-item>
<el-form-item label="">
<el-tooltip :open-delay="500" effect="light" placement="top">
<template slot="content">
Html-фильтр вырезает лишние элементы со<br>
страницы для определенных сайтов, таких как:<br>
samlib.ru<br>
www.fanfiction.net<br>
archiveofourown.org<br>
и других
</template>
<el-checkbox v-model="enableSitesFilter" @change="needTextReload">Включить html-фильтр для сайтов</el-checkbox>
</el-tooltip>
</el-form-item>
<el-form-item label="Изображения"> <el-form-item label="Изображения">
<el-col :span="11"> <el-col :span="11">
@@ -688,6 +701,10 @@ class SettingsPage extends Vue {
this.$notify.warning({message: 'Необходимо обновить страницу (F5), чтобы изменения возымели эффект'}); this.$notify.warning({message: 'Необходимо обновить страницу (F5), чтобы изменения возымели эффект'});
} }
needTextReload() {
this.$notify.warning({message: 'Необходимо обновить книгу в обход кэша, чтобы изменения возымели эффект'});
}
close() { close() {
this.$emit('settings-toggle'); this.$emit('settings-toggle');
} }

View File

@@ -36,9 +36,6 @@ class BookManager {
} }
} }
this.recentRev = await bmRecentStore.getItem('recent-rev') || 0;
this.recentDeltaRev = await bmRecentStore.getItem('recent-delta-rev') || 0;
this.recentChanged = true; this.recentChanged = true;
this.loadStored();//no await this.loadStored();//no await
@@ -262,6 +259,11 @@ class BookManager {
this.books[meta.key] = result; this.books[meta.key] = result;
} }
//Если файл на сервере изменился, считаем, что в кеше его нету
if (meta.path && result && meta.path != result.path) {
return;
}
if (result && !result.parsed) { if (result && !result.parsed) {
let data = await bmDataStore.getItem(`bmData-${meta.key}`); let data = await bmDataStore.getItem(`bmData-${meta.key}`);
callback(5); callback(5);
@@ -435,6 +437,12 @@ class BookManager {
Object.assign(mergedRecent, value); Object.assign(mergedRecent, value);
//подстраховка от hotReload
for (let i of Object.keys(mergedRecent)) {
if (!mergedRecent[i].key || mergedRecent[i].key !== i)
delete mergedRecent[i];
}
//"ленивое" обновление хранилища //"ленивое" обновление хранилища
(async() => { (async() => {
for (const rec of Object.values(mergedRecent)) { for (const rec of Object.values(mergedRecent)) {
@@ -455,16 +463,6 @@ class BookManager {
this.emit('recent-changed'); this.emit('recent-changed');
} }
async setRecentRev(value) {
await bmRecentStore.setItem('recent-rev', value);
this.recentRev = value;
}
async setRecentDeltaRev(value) {
await bmRecentStore.setItem('recent-delta-rev', value);
this.recentDeltaRev = value;
}
addEventListener(listener) { addEventListener(listener) {
if (this.eventListeners.indexOf(listener) < 0) if (this.eventListeners.indexOf(listener) < 0)
this.eventListeners.push(listener); this.eventListeners.push(listener);

View File

@@ -1,4 +1,18 @@
export const versionHistory = [ export const versionHistory = [
{
showUntil: '2019-10-17',
header: '0.7.3 (2019-10-18)',
content:
`
<ul>
<li>внутренние переделки механизма синхронизации с сервером</li>
<li>добавлен html-фильтр для сайтов www.fanfiction.net, archiveofourown.org</li>
<li>добавлен параметр "Включить html-фильтр для сайтов" в раздел "Вид"->"Текст" в настройках</li>
<li>исправления багов</li>
</ul>
`
},
{ {
showUntil: '2019-09-19', showUntil: '2019-09-19',
header: '0.7.1 (2019-09-20)', header: '0.7.1 (2019-09-20)',

View File

@@ -183,6 +183,7 @@ const settingDefaults = {
showServerStorageMessages: true, showServerStorageMessages: true,
showWhatsNewDialog: true, showWhatsNewDialog: true,
showMigrationDialog: true, showMigrationDialog: true,
enableSitesFilter: true,
fontShifts: {}, fontShifts: {},
showToolButton: {}, showToolButton: {},

82
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.7.0", "version": "0.7.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -541,6 +541,11 @@
"integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==",
"dev": true "dev": true
}, },
"adm-zip": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz",
"integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw=="
},
"ajv": { "ajv": {
"version": "6.10.2", "version": "6.10.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
@@ -1645,15 +1650,6 @@
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true "dev": true
}, },
"binary": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
"integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
"requires": {
"buffers": "~0.1.1",
"chainsaw": "~0.1.0"
}
},
"binary-extensions": { "binary-extensions": {
"version": "1.13.1", "version": "1.13.1",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
@@ -1883,11 +1879,6 @@
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
"dev": true "dev": true
}, },
"buffers": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
},
"builtin-status-codes": { "builtin-status-codes": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
@@ -2071,14 +2062,6 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
}, },
"chainsaw": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
"integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
"requires": {
"traverse": ">=0.3.0 <0.4"
}
},
"chalk": { "chalk": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
@@ -3196,20 +3179,6 @@
"mimic-response": "^1.0.0" "mimic-response": "^1.0.0"
} }
}, },
"decompress-zip": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.2.2.tgz",
"integrity": "sha512-v+Na3Ck86Px7s2ix+f77pMQC3GlkxHHN+YyvnkEW7+xX5F39pcDpIV/VFvGYk8MznTFcMoPjL3XNWEJLXWoSPw==",
"requires": {
"binary": "^0.3.0",
"graceful-fs": "^4.1.3",
"mkpath": "^0.1.0",
"nopt": "^3.0.1",
"q": "^1.1.2",
"readable-stream": "^1.1.8",
"touch": "0.0.3"
}
},
"deep-extend": { "deep-extend": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -6751,11 +6720,6 @@
} }
} }
}, },
"mkpath": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz",
"integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE="
},
"move-concurrently": { "move-concurrently": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -7047,14 +7011,6 @@
"semver": "^5.3.0" "semver": "^5.3.0"
} }
}, },
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
"requires": {
"abbrev": "1"
}
},
"normalize-path": { "normalize-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -9953,7 +9909,8 @@
"q": { "q": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
}, },
"qs": { "qs": {
"version": "6.7.0", "version": "6.7.0",
@@ -11785,24 +11742,6 @@
"integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
"dev": true "dev": true
}, },
"touch": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz",
"integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=",
"requires": {
"nopt": "~1.0.10"
},
"dependencies": {
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
"requires": {
"abbrev": "1"
}
}
}
},
"tough-cookie": { "tough-cookie": {
"version": "2.4.3", "version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@@ -11819,11 +11758,6 @@
} }
} }
}, },
"traverse": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
"integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk="
},
"trim-right": { "trim-right": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",

View File

@@ -1,6 +1,6 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.7.1", "version": "0.7.3",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },
@@ -55,12 +55,12 @@
"webpack-merge": "^4.2.2" "webpack-merge": "^4.2.2"
}, },
"dependencies": { "dependencies": {
"adm-zip": "^0.4.13",
"appcache-webpack-plugin": "^1.4.0", "appcache-webpack-plugin": "^1.4.0",
"axios": "^0.18.1", "axios": "^0.18.1",
"base-x": "^3.0.6", "base-x": "^3.0.6",
"chardet": "^0.7.0", "chardet": "^0.7.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"decompress-zip": "^0.2.2",
"element-ui": "^2.12.0", "element-ui": "^2.12.0",
"express": "^4.17.1", "express": "^4.17.1",
"fg-loadcss": "^2.1.0", "fg-loadcss": "^2.1.0",

View File

@@ -15,7 +15,10 @@ class ReaderController extends BaseController {
try { try {
if (!request.url) if (!request.url)
throw new Error(`key 'url' is empty`); throw new Error(`key 'url' is empty`);
const workerId = this.readerWorker.loadBookUrl(request.url); const workerId = this.readerWorker.loadBookUrl({
url: request.url,
enableSitesFilter: (request.hasOwnProperty('enableSitesFilter') ? request.enableSitesFilter : true)
});
const state = workerState.getState(workerId); const state = workerState.getState(workerId);
return (state ? state : {}); return (state ? state : {});
} catch (e) { } catch (e) {

View File

@@ -20,6 +20,9 @@ class ConvertSamlib extends ConvertBase {
} }
async run(data, opts) { async run(data, opts) {
if (!opts.enableSitesFilter)
return false;
const checkResult = this.check(data, opts); const checkResult = this.check(data, opts);
if (!checkResult) if (!checkResult)
return false; return false;

View File

@@ -0,0 +1,71 @@
const URL = require('url').URL;
const ConvertHtml = require('./ConvertHtml');
const sitesFilter = {
'www.fanfiction.net': {
converter: 'cutter',
begin: `<div class='storytext xcontrast_txt nocopy' id='storytext'>`,
end: `<div style='height:5px'></div><div style='clear:both;text-align:right;'>`,
},
'archiveofourown.org': {
converter: 'cutter',
begin: `<!-- BEGIN section where work skin applies -->`,
end: `<!-- END work skin -->`,
}
};
class ConvertSites extends ConvertHtml {
check(data, opts) {
const {url, dataType} = opts;
const parsedUrl = new URL(url);
if (dataType && dataType.ext == 'html') {
if (sitesFilter[parsedUrl.hostname])
return {hostname: parsedUrl.hostname};
}
return false;
}
async run(data, opts) {
if (!opts.enableSitesFilter)
return false;
const checkResult = this.check(data, opts);
if (!checkResult)
return false;
const {hostname} = checkResult;
let text = this.decode(data).toString();
text = this[sitesFilter[hostname].converter](text, sitesFilter[hostname]);
if (text === false)
return false;
return await super.run(Buffer.from(text), {skipCheck: true, cutTitle: true});
}
getTitle(text) {
let title = '';
const m = text.match(/<title>([\s\S]*?)<\/title>/);
if (m)
title = m[1];
return `<title>${title.trim()}</title>`;
}
cutter(text, opts) {
const title = this.getTitle(text);
const l = text.indexOf(opts.begin);
const r = text.indexOf(opts.end);
if (l < 0 || r < 0 || r <= l)
return false;
return text.substring(l, r) + title;
}
}
module.exports = ConvertSites;

View File

@@ -11,6 +11,7 @@ const convertClassFactory = [
require('./ConvertMobi'), require('./ConvertMobi'),
require('./ConvertFb2'), require('./ConvertFb2'),
require('./ConvertSamlib'), require('./ConvertSamlib'),
require('./ConvertSites'),
require('./ConvertHtml'), require('./ConvertHtml'),
]; ];
@@ -24,13 +25,14 @@ class BookConverter {
} }
} }
async convertToFb2(inputFiles, outputFile, url, callback) { async convertToFb2(inputFiles, outputFile, opts, callback) {
const selectedFileType = await this.detector.detectFile(inputFiles.selectedFile); const selectedFileType = await this.detector.detectFile(inputFiles.selectedFile);
const data = await fs.readFile(inputFiles.selectedFile); const data = await fs.readFile(inputFiles.selectedFile);
const convertOpts = Object.assign({}, opts, {inputFiles, callback, dataType: selectedFileType});
let result = false; let result = false;
for (const convert of this.convertFactory) { for (const convert of this.convertFactory) {
result = await convert.run(data, {inputFiles, url, callback, dataType: selectedFileType}); result = await convert.run(data, convertOpts);
if (result) { if (result) {
await fs.writeFile(outputFile, result); await fs.writeFile(outputFile, result);
break; break;
@@ -38,14 +40,14 @@ class BookConverter {
} }
if (!result && inputFiles.nesting) { if (!result && inputFiles.nesting) {
result = await this.convertToFb2(inputFiles.nesting, outputFile, url, callback); result = await this.convertToFb2(inputFiles.nesting, outputFile, opts, callback);
} }
if (!result) { if (!result) {
if (selectedFileType) if (selectedFileType)
throw new Error(`Этот формат файла не поддерживается: ${selectedFileType.mime}`); throw new Error(`Этот формат файла не поддерживается: ${selectedFileType.mime}`);
else { else {
throw new Error(`Не удалось определить формат файла: ${url}`); throw new Error(`Не удалось определить формат файла: ${opts.url}`);
} }
} }

View File

@@ -74,7 +74,7 @@ function getEncoding(buf, returnAll) {
if (returnAll) if (returnAll)
return sorted; return sorted;
else if (sorted[0].c > 0) else if (sorted[0].c > 0 && sorted[0].c > sorted[0].totalChecked/2)
return sorted[0].codePage; return sorted[0].codePage;
else else
return 'ISO-8859-5'; return 'ISO-8859-5';

View File

@@ -4,7 +4,7 @@ const crypto = require('crypto');
const path = require('path'); const path = require('path');
const unbzip2Stream = require('unbzip2-stream'); const unbzip2Stream = require('unbzip2-stream');
const tar = require('tar-fs'); const tar = require('tar-fs');
const DecompressZip = require('decompress-zip'); const AdmZip = require('adm-zip');
const utils = require('./utils'); const utils = require('./utils');
const FileDetector = require('./FileDetector'); const FileDetector = require('./FileDetector');
@@ -112,27 +112,18 @@ class FileDecompressor {
} }
async unZip(filename, outputDir) { async unZip(filename, outputDir) {
return new Promise((resolve, reject) => { return new Promise((resolve) => {
const files = []; const files = [];
const unzipper = new DecompressZip(filename); const zip = new AdmZip(filename);
unzipper.on('error', function(err) { zip.getEntries().forEach(function(zipEntry) {
reject(err); files.push({path: zipEntry.entryName, size: zipEntry.header.size});
}); });
unzipper.on('extract', function() { zip.extractAllTo(outputDir, true);
resolve(files); resolve(files);
}); });
unzipper.extract({
path: outputDir,
filter: function(file) {
if (file.type == 'File')
files.push({path: file.path, size: file.uncompressedSize});
return true;
}
});
});
} }
unBz2(filename, outputDir) { unBz2(filename, outputDir) {

View File

@@ -32,7 +32,8 @@ class ReaderWorker {
} }
} }
async loadBook(url, wState) { async loadBook(opts, wState) {
const url = opts.url;
let errMes = ''; let errMes = '';
let decompDir = ''; let decompDir = '';
let downloadedFilename = ''; let downloadedFilename = '';
@@ -77,7 +78,7 @@ class ReaderWorker {
//конвертирование в fb2 //конвертирование в fb2
wState.set({state: 'convert', step: 3, progress: 0}); wState.set({state: 'convert', step: 3, progress: 0});
convertFilename = `${this.config.tempDownloadDir}/${tempFilename2}`; convertFilename = `${this.config.tempDownloadDir}/${tempFilename2}`;
await this.bookConverter.convertToFb2(decompFiles, convertFilename, url, progress => { await this.bookConverter.convertToFb2(decompFiles, convertFilename, opts, progress => {
wState.set({progress}); wState.set({progress});
}); });
@@ -105,12 +106,12 @@ class ReaderWorker {
} }
} }
loadBookUrl(url) { loadBookUrl(opts) {
const workerId = workerState.generateWorkerId(); const workerId = workerState.generateWorkerId();
const wState = workerState.getControl(workerId); const wState = workerState.getControl(workerId);
wState.set({state: 'start'}); wState.set({state: 'start'});
this.loadBook(url, wState); this.loadBook(opts, wState);
return workerId; return workerId;
} }

View File

@@ -20,7 +20,7 @@ function webpackDevMiddleware(app) {
function logQueries(app) { function logQueries(app) {
app.use(function(req, res, next) { app.use(function(req, res, next) {
const start = Date.now(); const start = Date.now();
log(`${req.method} ${req.originalUrl} ${JSON.stringify(req.body).substr(0, 2000)}`); log(`${req.method} ${req.originalUrl} ${JSON.stringify(req.body).substr(0, 4000)}`);
//log(`${JSON.stringify(req.headers, null, 2)}`) //log(`${JSON.stringify(req.headers, null, 2)}`)
res.once('finish', () => { res.once('finish', () => {
log(`${Date.now() - start}ms`); log(`${Date.now() - start}ms`);