Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7eb576d0d | ||
|
|
34f1ad8fae | ||
|
|
c60f0991df | ||
|
|
d505fd0795 | ||
|
|
93cf506535 | ||
|
|
bfb37e55d4 | ||
|
|
92afc5cb33 | ||
|
|
75cb611701 | ||
|
|
2ec1dd58a5 | ||
|
|
7d59af54de | ||
|
|
2b5f47b3de | ||
|
|
16eebfb9a4 | ||
|
|
9025218671 | ||
|
|
6bccb546bb | ||
|
|
29d49046a0 | ||
|
|
717af9ffaf | ||
|
|
00060c9f43 | ||
|
|
759ff46c92 | ||
|
|
41957cdceb | ||
|
|
d418e3a1c9 | ||
|
|
f650124428 | ||
|
|
795d109c76 | ||
|
|
6868b3effc | ||
|
|
26747b7013 | ||
|
|
5198f8aa60 |
@@ -1,6 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import axios from 'axios';
|
||||
import {Buffer} from 'safe-buffer';
|
||||
|
||||
import * as utils from '../share/utils';
|
||||
|
||||
@@ -66,12 +64,13 @@ class Reader {
|
||||
estSize = response.headers['content-length'];
|
||||
}
|
||||
|
||||
callback({state: 'loading', progress: 0});
|
||||
const options = {
|
||||
onDownloadProgress: progress => {
|
||||
while (progress.loaded > estSize) estSize *= 1.5;
|
||||
|
||||
if (callback)
|
||||
callback({state: 'loading', progress: Math.round((progress.loaded*100)/estSize)});
|
||||
callback({progress: Math.round((progress.loaded*100)/estSize)});
|
||||
}
|
||||
}
|
||||
//загрузка
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<h4>Возможности читалки:</h4>
|
||||
<ul>
|
||||
<li>загрузка любой страницы интернета</li>
|
||||
<li>работа в автономном режиме (без связи)</li>
|
||||
<li>изменение цвета фона, текста, размер и тип шрифта и прочее</li>
|
||||
<li>установка и запоминание текущей позиции и настроек в браузере и на сервере</li>
|
||||
<li>синхронизация данных (настроек и читаемых книг) между различными устройствами</li>
|
||||
@@ -13,7 +14,6 @@
|
||||
<li>поиск по тексту и копирование фрагмента</li>
|
||||
<li>запоминание недавних книг, скачивание книги из читалки в формате fb2</li>
|
||||
<li>управление кликом и с клавиатуры</li>
|
||||
<li>подключение к интернету не обязательно для чтения книги после ее загрузки</li>
|
||||
<li>регистрация не требуется</li>
|
||||
<li>поддерживаемые браузеры: Google Chrome, Mozilla Firefox последних версий</li>
|
||||
</ul>
|
||||
@@ -22,18 +22,17 @@
|
||||
на файл из онлайн-библиотеки (например, скопировав адрес ссылки или кнопки "скачать fb2").</p>
|
||||
<p>Поддерживаемые форматы: <b>fb2, fb2.zip, html, txt</b> и другие.</p>
|
||||
|
||||
<p>Для автономной загрузки читалки (без интернета):<br>
|
||||
В Google Chrome можно установить флаг <span class="clickable" @click="copyText('chrome://flags/#show-saved-copy', 'Ссылка на флаг успешно скопирована в буфер обмена. Можно открыть ее в новой вкладке.')">chrome://flags/#show-saved-copy</span>
|
||||
в значение "Primary". В этом случае на стандартной странице "нет соединения" появится кнопка для автономной загрузки сайта из кэша.<br>
|
||||
В Mozilla Firefox в автономном режиме сайт загружается из кэша автоматически. Если этого не происходит, можно установить опцию
|
||||
"Веб-разработка" -> "Работать автономно".</p>
|
||||
|
||||
<div v-show="mode == 'omnireader'">
|
||||
<p>Вы также можете добавить в свой браузер закладку, указав в ее свойствах вместо адреса следующий код:
|
||||
<br><span class="clickable" @click="copyText('javascript:location.href=\'https://omnireader.ru/?url=\'+location.href;', 'Код для адреса закладки успешно скопирован в буфер обмена')">
|
||||
<strong>javascript:location.href='https://omnireader.ru/?url='+location.href;</strong>
|
||||
<p>Вы можете добавить в свой браузер закладку, указав в ее свойствах вместо адреса следующий код:
|
||||
<br><strong>javascript:location.href='https://omnireader.ru/?url='+location.href;</strong>
|
||||
|
||||
<span class="clickable" @click="copyText('javascript:location.href=\'https://omnireader.ru/?url=\'+location.href;', 'Код для адреса закладки успешно скопирован в буфер обмена')">
|
||||
(скопировать)
|
||||
</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 можно вызывать такую закладку по имени прямо в адресной строке браузера (имя стоит сделать попроще).
|
||||
</p>
|
||||
</div>
|
||||
<p>Связаться с разработчиком: <a href="mailto:bookpauk@gmail.com">bookpauk@gmail.com</a></p>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<li><b>Ctrl+C</b> - скопировать текст со страницы</li>
|
||||
<li><b>R</b> - принудительно обновить книгу в обход кэша</li>
|
||||
<li><b>X</b> - открыть недавние</li>
|
||||
<li><b>O</b> - автономный режим</li>
|
||||
<li><b>S</b> - открыть окно настроек</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
</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="openOldVersion">Старая версия</span>
|
||||
</div>
|
||||
|
||||
<div class="part bottom">
|
||||
@@ -137,6 +138,10 @@ class LoaderPage extends Vue {
|
||||
window.open('http://samlib.ru/comment/b/bookpauk/bookpauk_reader', '_blank');
|
||||
}
|
||||
|
||||
openOldVersion() {
|
||||
window.open('http://old.omnireader.ru', '_blank');
|
||||
}
|
||||
|
||||
keyHook(event) {
|
||||
if (this.pasteTextActive) {
|
||||
return this.$refs.pasteTextPage.keyHook(event);
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<div class="space"></div>
|
||||
<el-tooltip v-show="showToolButton['offlineMode']" content="Автономный режим (без интернета)" :open-delay="1000" effect="light">
|
||||
<el-button ref="offlineMode" class="tool-button" :class="buttonActiveClass('offlineMode')" @click="buttonClick('offlineMode')"><i class="el-icon-connection"></i></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-show="showToolButton['recentBooks']" content="Открыть недавние" :open-delay="1000" effect="light">
|
||||
<el-button ref="recentBooks" class="tool-button" :class="buttonActiveClass('recentBooks')" @click="buttonClick('recentBooks')"><i class="el-icon-document"></i></el-button>
|
||||
</el-tooltip>
|
||||
@@ -257,6 +260,7 @@ class Reader extends Vue {
|
||||
searchActive = false;
|
||||
copyTextActive = false;
|
||||
recentBooksActive = false;
|
||||
offlineModeActive = false;
|
||||
settingsActive = false;
|
||||
helpActive = false;
|
||||
clickMapActive = false;
|
||||
@@ -506,29 +510,35 @@ class Reader extends Vue {
|
||||
}
|
||||
|
||||
async bookManagerEvent(eventName) {
|
||||
if (eventName == 'recent-changed') {
|
||||
if (this.recentBooksActive) {
|
||||
await this.$refs.recentBooksPage.updateTableData();
|
||||
}
|
||||
}
|
||||
|
||||
if (eventName == 'set-recent' || eventName == 'recent-deleted') {
|
||||
const oldBook = this.mostRecentBookReactive;
|
||||
const oldBook = (this.textPage ? this.textPage.lastBook : null);
|
||||
const oldPos = (this.textPage ? this.textPage.bookPos : null);
|
||||
const newBook = bookManager.mostRecentBook();
|
||||
|
||||
if (!(oldBook && newBook && oldBook.key == newBook.key)) {
|
||||
this.mostRecentBook();
|
||||
}
|
||||
|
||||
if (oldBook && newBook) {
|
||||
if (oldBook.key != newBook.key) {
|
||||
if (oldBook.key != newBook.key || oldBook.path != newBook.path) {
|
||||
this.loadingBook = true;
|
||||
try {
|
||||
await this.loadBook(newBook);
|
||||
} finally {
|
||||
this.loadingBook = false;
|
||||
}
|
||||
} else if (oldBook.bookPos != newBook.bookPos) {
|
||||
} else if (oldPos != newBook.bookPos) {
|
||||
while (this.loadingBook) await utils.sleep(100);
|
||||
this.bookPosChanged({bookPos: newBook.bookPos});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eventName == 'recent-changed') {
|
||||
if (this.recentBooksActive) {
|
||||
await this.$refs.recentBooksPage.updateTableData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get toolBarActive() {
|
||||
@@ -696,6 +706,11 @@ class Reader extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
offlineModeToggle() {
|
||||
this.offlineModeActive = !this.offlineModeActive;
|
||||
this.$refs.serverStorage.offlineModeActive = this.offlineModeActive;
|
||||
}
|
||||
|
||||
settingsToggle() {
|
||||
this.settingsActive = !this.settingsActive;
|
||||
if (this.settingsActive) {
|
||||
@@ -781,11 +796,14 @@ class Reader extends Vue {
|
||||
case 'copyText':
|
||||
this.copyTextToggle();
|
||||
break;
|
||||
case 'refresh':
|
||||
this.refreshBook();
|
||||
break;
|
||||
case 'recentBooks':
|
||||
this.recentBooksToggle();
|
||||
break;
|
||||
case 'refresh':
|
||||
this.refreshBook();
|
||||
case 'offlineMode':
|
||||
this.offlineModeToggle();
|
||||
break;
|
||||
case 'settings':
|
||||
this.settingsToggle();
|
||||
@@ -806,6 +824,7 @@ class Reader extends Vue {
|
||||
case 'search':
|
||||
case 'copyText':
|
||||
case 'recentBooks':
|
||||
case 'offlineMode':
|
||||
case 'settings':
|
||||
if (this[`${button}Active`])
|
||||
classResult = classActive;
|
||||
@@ -890,6 +909,7 @@ class Reader extends Vue {
|
||||
this.updateRoute();
|
||||
const textPage = this.$refs.page;
|
||||
if (textPage.showBook) {
|
||||
this.textPage = textPage;
|
||||
textPage.lastBook = last;
|
||||
textPage.bookPos = (last.bookPos !== undefined ? last.bookPos : 0);
|
||||
|
||||
@@ -914,8 +934,10 @@ class Reader extends Vue {
|
||||
url = 'http://' + url;
|
||||
|
||||
// уже просматривается сейчас
|
||||
const lastBook = (this.$refs.page ? this.$refs.page.lastBook : null);
|
||||
if (!opts.force && lastBook && lastBook.url == url && await bookManager.hasBookParsed(lastBook)) {
|
||||
const lastBook = (this.textPage ? this.textPage.lastBook : null);
|
||||
if (!opts.force && lastBook && lastBook.url == url &&
|
||||
(!opts.path || opts.path == lastBook.path) &&
|
||||
await bookManager.hasBookParsed(lastBook)) {
|
||||
this.loaderActive = false;
|
||||
return;
|
||||
}
|
||||
@@ -944,7 +966,7 @@ class Reader extends Vue {
|
||||
|
||||
if (!opts.force) {
|
||||
// пытаемся загрузить и распарсить книгу в менеджере из локального кэша
|
||||
const bookParsed = await bookManager.getBook({url}, (prog) => {
|
||||
const bookParsed = await bookManager.getBook({url, path: opts.path}, (prog) => {
|
||||
progress.setState({progress: prog});
|
||||
});
|
||||
|
||||
@@ -965,6 +987,7 @@ class Reader extends Vue {
|
||||
// иначе идем на сервер
|
||||
// пытаемся загрузить готовый файл с сервера
|
||||
if (wasOpened.path) {
|
||||
progress.setState({totalSteps: 5});
|
||||
try {
|
||||
const resp = await readerApi.loadCachedBook(wasOpened.path, (state) => {
|
||||
progress.setState(state);
|
||||
@@ -1050,7 +1073,7 @@ class Reader extends Vue {
|
||||
let page = this.$refs.page;
|
||||
while (this.blinkCount) {
|
||||
this.showRefreshIcon = !this.showRefreshIcon;
|
||||
if (page.blinkCachedLoadMessage)
|
||||
if (page && page.blinkCachedLoadMessage)
|
||||
page.blinkCachedLoadMessage(this.showRefreshIcon);
|
||||
await utils.sleep(500);
|
||||
if (this.stopBlink)
|
||||
@@ -1060,7 +1083,7 @@ class Reader extends Vue {
|
||||
}
|
||||
this.showRefreshIcon = true;
|
||||
this.inBlink = false;
|
||||
if (page.blinkCachedLoadMessage)
|
||||
if (page && page.blinkCachedLoadMessage)
|
||||
page.blinkCachedLoadMessage('finish');
|
||||
});
|
||||
}
|
||||
@@ -1130,6 +1153,9 @@ class Reader extends Vue {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case 'KeyO':
|
||||
this.offlineModeToggle();
|
||||
break;
|
||||
case 'KeyS':
|
||||
this.settingsToggle();
|
||||
break;
|
||||
|
||||
@@ -251,6 +251,7 @@ class RecentBooksPage extends Vue {
|
||||
}
|
||||
if (this.tableData.length > result.length)
|
||||
this.tableData.splice(result.length);*/
|
||||
|
||||
this.tableData = result;
|
||||
this.updating = false;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ class ServerStorage extends Vue {
|
||||
if (eventName == 'recent-changed') {
|
||||
if (itemKey) {
|
||||
if (!this.recentDeltaInited) {
|
||||
await this.loadRecent();
|
||||
this.warning('Функции сохранения на сервер пока недоступны');
|
||||
return;
|
||||
}
|
||||
@@ -175,12 +176,12 @@ class ServerStorage extends Vue {
|
||||
}
|
||||
|
||||
warning(message) {
|
||||
if (this.showServerStorageMessages)
|
||||
if (this.showServerStorageMessages && !this.offlineModeActive)
|
||||
this.$notify.warning({message});
|
||||
}
|
||||
|
||||
error(message) {
|
||||
if (this.showServerStorageMessages)
|
||||
if (this.showServerStorageMessages && !this.offlineModeActive)
|
||||
this.$notify.error({message});
|
||||
}
|
||||
|
||||
@@ -362,74 +363,79 @@ class ServerStorage extends Vue {
|
||||
}
|
||||
|
||||
async loadRecent(skipRevCheck = false, doNotifySuccess = true) {
|
||||
if (!this.keyInited || !this.serverSyncEnabled)
|
||||
if (!this.keyInited || !this.serverSyncEnabled || this.loadingRecent)
|
||||
return;
|
||||
|
||||
const oldRecentRev = bookManager.recentRev;
|
||||
const oldRecentDeltaRev = bookManager.recentDeltaRev;
|
||||
//проверим ревизию на сервере
|
||||
let revs = null;
|
||||
if (!skipRevCheck) {
|
||||
try {
|
||||
revs = await this.storageCheck({recent: {}, recentDelta: {}});
|
||||
if (revs.state == 'success' && revs.items.recent.rev == oldRecentRev &&
|
||||
revs.items.recentDelta.rev == oldRecentDeltaRev) {
|
||||
if (!this.recentDeltaInited)
|
||||
await this.initRecentDelta();
|
||||
this.loadingRecent = true;
|
||||
try {
|
||||
const oldRecentRev = bookManager.recentRev;
|
||||
const oldRecentDeltaRev = bookManager.recentDeltaRev;
|
||||
//проверим ревизию на сервере
|
||||
let revs = null;
|
||||
if (!skipRevCheck) {
|
||||
try {
|
||||
revs = await this.storageCheck({recent: {}, recentDelta: {}});
|
||||
if (revs.state == 'success' && revs.items.recent.rev == oldRecentRev &&
|
||||
revs.items.recentDelta.rev == oldRecentDeltaRev) {
|
||||
if (!this.recentDeltaInited)
|
||||
await this.initRecentDelta();
|
||||
return;
|
||||
}
|
||||
} catch(e) {
|
||||
this.error(`Ошибка соединения с сервером: ${e.message}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let recent = null;
|
||||
try {
|
||||
recent = await this.storageGet({recent: {}, recentDelta: {}});
|
||||
} catch(e) {
|
||||
this.error(`Ошибка соединения с сервером: ${e.message}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let recent = null;
|
||||
try {
|
||||
recent = await this.storageGet({recent: {}, recentDelta: {}});
|
||||
} catch(e) {
|
||||
this.error(`Ошибка соединения с сервером: ${e.message}`);
|
||||
return;
|
||||
}
|
||||
if (recent.state == 'success') {
|
||||
let recentDelta = recent.items.recentDelta;
|
||||
recent = recent.items.recent;
|
||||
|
||||
if (recent.state == 'success') {
|
||||
let recentDelta = recent.items.recentDelta;
|
||||
recent = recent.items.recent;
|
||||
if (recent.rev == 0)
|
||||
recent.data = {};
|
||||
|
||||
if (recent.rev == 0)
|
||||
recent.data = {};
|
||||
|
||||
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);
|
||||
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;
|
||||
} else {
|
||||
newRecent = Object.assign(recent.data, recentDelta.data);
|
||||
newRecent = recent.data;
|
||||
this.recentDelta = {};
|
||||
}
|
||||
this.recentDelta = recentDelta.data;
|
||||
|
||||
this.recentDeltaInited = true;
|
||||
|
||||
if (!bookManager.loaded) {
|
||||
this.warning('Ожидание загрузки списка книг перед синхронизацией');
|
||||
while (!bookManager.loaded) await utils.sleep(100);
|
||||
}
|
||||
await bookManager.setRecent(newRecent);
|
||||
await bookManager.setRecentRev(recent.rev);
|
||||
await bookManager.setRecentDeltaRev(recentDelta.rev);
|
||||
} else {
|
||||
newRecent = recent.data;
|
||||
this.recentDelta = {};
|
||||
this.warning(`Неверный ответ сервера: ${recent.state}`);
|
||||
}
|
||||
|
||||
this.recentDeltaInited = true;
|
||||
|
||||
if (!bookManager.loaded) {
|
||||
this.warning('Ожидание загрузки списка книг перед синхронизацией');
|
||||
while (!bookManager.loaded) await utils.sleep(100);
|
||||
}
|
||||
await bookManager.setRecent(newRecent);
|
||||
await bookManager.setRecentRev(recent.rev);
|
||||
await bookManager.setRecentDeltaRev(recentDelta.rev);
|
||||
} else {
|
||||
this.warning(`Неверный ответ сервера: ${recent.state}`);
|
||||
if (doNotifySuccess)
|
||||
this.debouncedNotifySuccess();
|
||||
} finally {
|
||||
this.loadingRecent = false;
|
||||
}
|
||||
|
||||
if (doNotifySuccess)
|
||||
this.debouncedNotifySuccess();
|
||||
}
|
||||
|
||||
async saveRecent(itemKey, recurse) {
|
||||
@@ -449,7 +455,7 @@ class ServerStorage extends Vue {
|
||||
|
||||
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);
|
||||
const forceSaveRecent = l > 20 || (this.sameKeyCount > 5 && (l > 1)) || (l == 1 && this.sameKeyCount > 10 && !this.makeDeltaDiff);
|
||||
|
||||
this.sameKeyCount = (!forceSaveRecent ? this.sameKeyCount : 0);
|
||||
this.prevItemKey = itemKey;
|
||||
|
||||
@@ -262,6 +262,11 @@ class BookManager {
|
||||
this.books[meta.key] = result;
|
||||
}
|
||||
|
||||
//Если файл на сервере изменился, считаем, что в кеше его нету
|
||||
if (meta.path && result && meta.path != result.path) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result && !result.parsed) {
|
||||
let data = await bmDataStore.getItem(`bmData-${meta.key}`);
|
||||
callback(5);
|
||||
@@ -434,6 +439,12 @@ class BookManager {
|
||||
const mergedRecent = _.cloneDeep(this.recent);
|
||||
|
||||
Object.assign(mergedRecent, value);
|
||||
|
||||
//подстраховка
|
||||
for (let i of Object.keys(mergedRecent)) {
|
||||
if (!mergedRecent[i].key || mergedRecent[i].key !== i)
|
||||
delete mergedRecent[i];
|
||||
}
|
||||
|
||||
//"ленивое" обновление хранилища
|
||||
(async() => {
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
export const versionHistory = [
|
||||
{
|
||||
showUntil: '2019-10-17',
|
||||
header: '0.7.2 (2019-10-18)',
|
||||
content:
|
||||
`
|
||||
<ul>
|
||||
<li>исправления багов</li>
|
||||
</ul>
|
||||
`
|
||||
},
|
||||
|
||||
{
|
||||
showUntil: '2019-09-19',
|
||||
header: '0.7.1 (2019-09-20)',
|
||||
@@ -6,6 +17,8 @@ export const versionHistory = [
|
||||
`
|
||||
<ul>
|
||||
<li>исправления багов</li>
|
||||
<li>на панель управления добавлена кнопка "Автономный режим"</li>
|
||||
<li>актуализирована справка</li>
|
||||
</ul>
|
||||
`
|
||||
},
|
||||
|
||||
@@ -8,6 +8,7 @@ const toolButtons = [
|
||||
{name: 'search', show: true, text: 'Найти в тексте'},
|
||||
{name: 'copyText', show: false, text: 'Скопировать текст со страницы'},
|
||||
{name: 'refresh', show: true, text: 'Принудительно обновить книгу'},
|
||||
{name: 'offlineMode', show: false, text: 'Автономный режим (без интернета)'},
|
||||
{name: 'recentBooks', show: true, text: 'Открыть недавние'},
|
||||
];
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
82
package-lock.json
generated
82
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Liberama",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -541,6 +541,11 @@
|
||||
"integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==",
|
||||
"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": {
|
||||
"version": "6.10.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
|
||||
@@ -1645,15 +1650,6 @@
|
||||
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
|
||||
"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": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
|
||||
@@ -1883,11 +1879,6 @@
|
||||
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
|
||||
"dev": true
|
||||
},
|
||||
"buffers": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
|
||||
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
|
||||
},
|
||||
"builtin-status-codes": {
|
||||
"version": "3.0.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
@@ -3196,20 +3179,6 @@
|
||||
"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": {
|
||||
"version": "0.6.0",
|
||||
"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": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
@@ -7047,14 +7011,6 @@
|
||||
"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": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
@@ -9953,7 +9909,8 @@
|
||||
"q": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
|
||||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
|
||||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
@@ -11785,24 +11742,6 @@
|
||||
"integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
|
||||
"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": {
|
||||
"version": "2.4.3",
|
||||
"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": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Liberama",
|
||||
"version": "0.7.1",
|
||||
"version": "0.7.2",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
@@ -55,12 +55,12 @@
|
||||
"webpack-merge": "^4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"adm-zip": "^0.4.13",
|
||||
"appcache-webpack-plugin": "^1.4.0",
|
||||
"axios": "^0.18.1",
|
||||
"base-x": "^3.0.6",
|
||||
"chardet": "^0.7.0",
|
||||
"compression": "^1.7.4",
|
||||
"decompress-zip": "^0.2.2",
|
||||
"element-ui": "^2.12.0",
|
||||
"express": "^4.17.1",
|
||||
"fg-loadcss": "^2.1.0",
|
||||
|
||||
@@ -74,7 +74,7 @@ function getEncoding(buf, returnAll) {
|
||||
|
||||
if (returnAll)
|
||||
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;
|
||||
else
|
||||
return 'ISO-8859-5';
|
||||
|
||||
@@ -4,7 +4,7 @@ const crypto = require('crypto');
|
||||
const path = require('path');
|
||||
const unbzip2Stream = require('unbzip2-stream');
|
||||
const tar = require('tar-fs');
|
||||
const DecompressZip = require('decompress-zip');
|
||||
const AdmZip = require('adm-zip');
|
||||
|
||||
const utils = require('./utils');
|
||||
const FileDetector = require('./FileDetector');
|
||||
@@ -112,26 +112,17 @@ class FileDecompressor {
|
||||
}
|
||||
|
||||
async unZip(filename, outputDir) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
const files = [];
|
||||
const unzipper = new DecompressZip(filename);
|
||||
const zip = new AdmZip(filename);
|
||||
|
||||
unzipper.on('error', function(err) {
|
||||
reject(err);
|
||||
zip.getEntries().forEach(function(zipEntry) {
|
||||
files.push({path: zipEntry.entryName, size: zipEntry.header.size});
|
||||
});
|
||||
|
||||
unzipper.on('extract', function() {
|
||||
resolve(files);
|
||||
});
|
||||
zip.extractAllTo(outputDir, true);
|
||||
|
||||
unzipper.extract({
|
||||
path: outputDir,
|
||||
filter: function(file) {
|
||||
if (file.type == 'File')
|
||||
files.push({path: file.path, size: file.uncompressedSize});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
resolve(files);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user