Compare commits

...

17 Commits

Author SHA1 Message Date
Book Pauk
7b59f911ef Merge branch 'release/0.11.8' 2022-07-15 02:10:58 +07:00
Book Pauk
d3444da647 Поправки разметки 2022-07-15 01:58:42 +07:00
Book Pauk
66738d0c9c К предыдущему 2022-07-15 01:51:28 +07:00
Book Pauk
7e187acd68 Версия 0.11.8 2022-07-15 01:50:17 +07:00
Book Pauk
c751372a54 Добавлен resizeImage 2022-07-15 01:38:25 +07:00
Book Pauk
7fc98fc7da Добавление отображения обложки (coverpage) в окне загруженных файлов 2022-07-15 00:47:24 +07:00
Book Pauk
b56f45694e Добавлен coversStorage для хранения coverpage 2022-07-15 00:45:56 +07:00
Book Pauk
091ca521ef Новые upload-методы 2022-07-15 00:45:09 +07:00
Book Pauk
c7a17b0a76 Добавлена синхронизация файлов обоев 2022-07-14 20:14:40 +07:00
Book Pauk
26468b996a Мелкая поправка 2022-07-14 20:12:37 +07:00
Book Pauk
c4e240d87c Увеличил maxPayloadSize 2022-07-14 20:11:17 +07:00
Book Pauk
04713f47c8 Небольшие поправки 2022-07-14 16:14:25 +07:00
Book Pauk
37ab3493db Merge tag '0.11.7-6' into develop
0.11.7-6
2022-07-14 03:52:50 +07:00
Book Pauk
a4cb3c628e Merge branch 'release/0.11.7-6' 2022-07-14 03:52:44 +07:00
Book Pauk
8492da8a13 Небольшое улучшение 2022-07-14 03:51:59 +07:00
Book Pauk
98d7c64a56 Исправление багов 2022-07-14 03:34:55 +07:00
Book Pauk
25f121e5ed Merge tag '0.11.7-5' into develop
0.11.7-5
2022-07-14 01:57:36 +07:00
18 changed files with 370 additions and 27 deletions

View File

@@ -1,5 +1,6 @@
import axios from 'axios'; import axios from 'axios';
import * as utils from '../share/utils'; import * as utils from '../share/utils';
import * as cryptoUtils from '../share/cryptoUtils';
import wsc from './webSocketConnection'; import wsc from './webSocketConnection';
const api = axios.create({ const api = axios.create({
@@ -174,11 +175,10 @@ class Reader {
return await axios.get(url, options); return await axios.get(url, options);
} }
async uploadFile(file, maxUploadFileSize, callback) { async uploadFile(file, maxUploadFileSize = 10*1024*1024, callback) {
if (!maxUploadFileSize)
maxUploadFileSize = 10*1024*1024;
if (file.size > maxUploadFileSize) if (file.size > maxUploadFileSize)
throw new Error(`Размер файла превышает ${maxUploadFileSize} байт`); throw new Error(`Размер файла превышает ${maxUploadFileSize} байт`);
let formData = new FormData(); let formData = new FormData();
formData.append('file', file, file.name); formData.append('file', file, file.name);
@@ -225,6 +225,33 @@ class Reader {
return response; return response;
} }
async uploadFileBuf(buf, urlCallback) {
const key = utils.toHex(cryptoUtils.sha256(buf));
const url = `disk://${key}`;
if (urlCallback)
urlCallback(url);
let response;
try {
await axios.head(`/upload/${key}`, {headers: {'Cache-Control': 'no-cache'}});
response = await wsc.message(await wsc.send({action: 'upload-file-touch', url}));
} catch (e) {
response = await wsc.message(await wsc.send({action: 'upload-file-buf', buf}));
}
if (response.error)
throw new Error(response.error);
return response;
}
async getUploadedFileBuf(url) {
url = url.replace('disk://', '/upload/');
return (await axios.get(url)).data;
}
} }
export default new Reader(); export default new Reader();

View File

@@ -194,6 +194,7 @@ import ReaderDialogs from './ReaderDialogs/ReaderDialogs.vue';
import bookManager from './share/bookManager'; import bookManager from './share/bookManager';
import wallpaperStorage from './share/wallpaperStorage'; import wallpaperStorage from './share/wallpaperStorage';
import coversStorage from './share/coversStorage';
import dynamicCss from '../../share/dynamicCss'; import dynamicCss from '../../share/dynamicCss';
import rstore from '../../store/modules/reader'; import rstore from '../../store/modules/reader';
@@ -366,6 +367,8 @@ class Reader {
mounted() { mounted() {
(async() => { (async() => {
await wallpaperStorage.init(); await wallpaperStorage.init();
await coversStorage.init();
await bookManager.init(this.settings); await bookManager.init(this.settings);
bookManager.addEventListener(this.bookManagerEvent); bookManager.addEventListener(this.bookManagerEvent);
@@ -450,22 +453,47 @@ class Reader {
//wallpaper css //wallpaper css
async loadWallpapers() { async loadWallpapers() {
const wallpaperDataLength = await wallpaperStorage.getLength(); if (!_.isEqual(this.userWallpapers, this.prevUserWallpapers)) {//оптимизация
if (wallpaperDataLength !== this.wallpaperDataLength) {//оптимизация this.prevUserWallpapers = _.cloneDeep(this.userWallpapers);
this.wallpaperDataLength = wallpaperDataLength;
let newCss = ''; let newCss = '';
let updated = false;
const wallpaperExists = new Set();
for (const wp of this.userWallpapers) { for (const wp of this.userWallpapers) {
const data = await wallpaperStorage.getData(wp.cssClass); wallpaperExists.add(wp.cssClass);
let data = await wallpaperStorage.getData(wp.cssClass);
if (!data) { if (!data) {
//здесь будем восстанавливать данные с сервера //здесь будем восстанавливать данные с сервера
const url = `disk://${wp.cssClass.replace('user-paper', '')}`;
try {
data = await readerApi.getUploadedFileBuf(url);
await wallpaperStorage.setData(wp.cssClass, data);
updated = true;
} catch (e) {
console.error(e);
}
} }
if (data) { if (data) {
newCss += `.${wp.cssClass} {background: url(${data}) center; background-size: 100% 100%;}`; newCss += `.${wp.cssClass} {background: url(${data}) center; background-size: 100% 100%;}`;
} }
} }
//почистим wallpaperStorage
for (const key of await wallpaperStorage.getKeys()) {
if (!wallpaperExists.has(key)) {
await wallpaperStorage.removeData(key);
}
}
//обновим settings, если загружали обои из /upload/
if (updated) {
const newSettings = _.cloneDeep(this.settings);
newSettings.needUpdateSettingsView = (newSettings.needUpdateSettingsView < 10 ? newSettings.needUpdateSettingsView + 1 : 0);
this.commit('reader/setSettings', newSettings);
}
dynamicCss.replace('wallpapers', newCss); dynamicCss.replace('wallpapers', newCss);
} }
} }
@@ -1107,6 +1135,7 @@ class Reader {
wasOpened = (wasOpened ? _.cloneDeep(wasOpened) : {}); wasOpened = (wasOpened ? _.cloneDeep(wasOpened) : {});
wasOpened = Object.assign(wasOpened, { wasOpened = Object.assign(wasOpened, {
url: (opts.url !== undefined ? opts.url : wasOpened.url),
path: (opts.path !== undefined ? opts.path : wasOpened.path), path: (opts.path !== undefined ? opts.path : wasOpened.path),
bookPos: (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPos), bookPos: (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPos),
bookPosSeen: (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPosSeen), bookPosSeen: (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPosSeen),

View File

@@ -105,8 +105,9 @@
</div> </div>
<div class="row-part column justify-center items-stretch" style="width: 80px"> <div class="row-part column justify-center items-stretch" style="width: 80px">
<div class="col row justify-center items-center clickable" @click="loadBook(item)"> <div class="col row justify-center items-center clickable" style="padding: 4px" @click="loadBook(item)">
<q-icon name="la la-book" size="40px" style="color: #dddddd" /> <div v-show="isLoadedCover(item.coverPageUrl)" style="height: 80px" v-html="getCoverHtml(item.coverPageUrl)" />
<q-icon v-show="!isLoadedCover(item.coverPageUrl)" name="la la-book" size="40px" style="color: #dddddd" />
</div> </div>
<div v-show="!showSameBook && item.group && item.group.length > 0" class="row justify-center" style="font-size: 70%"> <div v-show="!showSameBook && item.group && item.group.length > 0" class="row justify-center" style="font-size: 70%">
@@ -213,6 +214,7 @@ import LockQueue from '../../../share/LockQueue';
import Window from '../../share/Window.vue'; import Window from '../../share/Window.vue';
import bookManager from '../share/bookManager'; import bookManager from '../share/bookManager';
import readerApi from '../../../api/reader'; import readerApi from '../../../api/reader';
import coversStorage from '../share/coversStorage';
const componentOptions = { const componentOptions = {
components: { components: {
@@ -240,6 +242,8 @@ class RecentBooksPage {
showSameBook = false; showSameBook = false;
archive = false; archive = false;
covers = {};
created() { created() {
this.commit = this.$store.commit; this.commit = this.$store.commit;
@@ -264,6 +268,7 @@ class RecentBooksPage {
this.showBar(); this.showBar();
await this.updateTableData(); await this.updateTableData();
await this.scrollToActiveBook(); await this.scrollToActiveBook();
//await this.scrollRefresh();
})(); })();
} }
@@ -317,6 +322,11 @@ class RecentBooksPage {
const author = (bt.author ? bt.author : (bt.bookTitle ? bt.bookTitle : (book.uploadFileName ? book.uploadFileName : book.url))); const author = (bt.author ? bt.author : (bt.bookTitle ? bt.bookTitle : (book.uploadFileName ? book.uploadFileName : book.url)));
result.push({ result.push({
key: book.key,
url: book.url,
path: book.path,
deleted: book.deleted,
touchTime, touchTime,
loadTime, loadTime,
desc: { desc: {
@@ -326,14 +336,12 @@ class RecentBooksPage {
textLen, textLen,
}, },
readPart, readPart,
url: book.url,
path: book.path,
fullTitle: bt.fullTitle, fullTitle: bt.fullTitle,
key: book.key,
sameBookKey: book.sameBookKey, sameBookKey: book.sameBookKey,
active: (activeBook.key == book.key), active: (activeBook.key == book.key),
activeParent: false, activeParent: false,
inGroup: false, inGroup: false,
coverPageUrl: book.coverPageUrl,
//для сортировки //для сортировки
loadTimeRaw, loadTimeRaw,
@@ -501,8 +509,14 @@ class RecentBooksPage {
this.$root.notify.info('Восстановлено из архива'); this.$root.notify.info('Восстановлено из архива');
} }
loadBook(row) { async loadBook(item) {
this.$emit('load-book', {url: row.url, path: row.path}); //чтобы не обновлять лишний раз updateTableData
this.inited = false;
if (item.deleted)
await this.handleRestore(item.key);
this.$emit('load-book', {url: item.url, path: item.path});
this.close(); this.close();
} }
@@ -559,6 +573,8 @@ class RecentBooksPage {
} }
async scrollToActiveBook() { async scrollToActiveBook() {
await this.$nextTick();
this.lockScroll = true; this.lockScroll = true;
try { try {
let activeIndex = -1; let activeIndex = -1;
@@ -604,6 +620,16 @@ class RecentBooksPage {
} }
} }
async scrollRefresh() {
this.lockScroll = true;
await utils.sleep(100);
try {
this.$refs.virtualScroll.refresh();
} finally {
await utils.sleep(100);
this.lockScroll = false;
}
}
get sortMethodOptions() { get sortMethodOptions() {
return [ return [
@@ -633,6 +659,43 @@ class RecentBooksPage {
} }
return true; return true;
} }
makeCoverHtml(data) {
return `<img src="${data}" style="height: 100%; width: 100%; object-fit: contain" />`;
}
isLoadedCover(coverPageUrl) {
if (!coverPageUrl)
return false;
let loadedCover = this.covers[coverPageUrl];
if (!loadedCover) {
(async() => {
//сначала заглянем в storage
let data = await coversStorage.getData(coverPageUrl);
if (data) {
this.covers[coverPageUrl] = this.makeCoverHtml(data);
} else {//иначе идем на сервер
try {
data = await readerApi.getUploadedFileBuf(coverPageUrl);
await coversStorage.setData(coverPageUrl, data);
this.covers[coverPageUrl] = this.makeCoverHtml(data);
} catch (e) {
console.error(e);
}
}
})();
}
return (loadedCover != undefined);
}
getCoverHtml(coverPageUrl) {
if (coverPageUrl && this.covers[coverPageUrl])
return this.covers[coverPageUrl];
else
return '';
}
} }
export default vueComponent(RecentBooksPage); export default vueComponent(RecentBooksPage);
@@ -706,14 +769,14 @@ export default vueComponent(RecentBooksPage);
line-height: 110%; line-height: 110%;
border-left: 1px solid #cccccc; border-left: 1px solid #cccccc;
border-bottom: 1px solid #cccccc; border-bottom: 1px solid #cccccc;
height: 12px; height: 14px;
} }
.row-info-top { .row-info-top {
line-height: 110%; line-height: 110%;
border: 1px solid #cccccc; border: 1px solid #cccccc;
border-right: 0; border-right: 0;
height: 12px; height: 14px;
} }
.time-info, .row-info-top { .time-info, .row-info-top {
@@ -721,8 +784,8 @@ export default vueComponent(RecentBooksPage);
} }
.read-bar { .read-bar {
height: 4px; height: 6px;
background-color: #bbbbbb; background-color: #b8b8b8;
} }
.del-button { .del-button {

View File

@@ -124,6 +124,7 @@ import NumInput from '../../share/NumInput.vue';
import UserHotKeys from './UserHotKeys/UserHotKeys.vue'; import UserHotKeys from './UserHotKeys/UserHotKeys.vue';
import wallpaperStorage from '../share/wallpaperStorage'; import wallpaperStorage from '../share/wallpaperStorage';
import readerApi from '../../../api/reader';
import rstore from '../../../store/modules/reader'; import rstore from '../../../store/modules/reader';
import defPalette from './defPalette'; import defPalette from './defPalette';
@@ -636,8 +637,17 @@ class SettingsPage {
if (index < 0) if (index < 0)
newUserWallpapers.push({label, cssClass}); newUserWallpapers.push({label, cssClass});
if (!wallpaperStorage.keyExists(cssClass)) if (!wallpaperStorage.keyExists(cssClass)) {
await wallpaperStorage.setData(cssClass, data); await wallpaperStorage.setData(cssClass, data);
//отправим data на сервер в файл `/upload/${key}`
try {
//const res =
await readerApi.uploadFileBuf(data);
//console.log(res);
} catch (e) {
console.error(e);
}
}
this.userWallpapers = newUserWallpapers; this.userWallpapers = newUserWallpapers;
this.wallpaper = cssClass; this.wallpaper = cssClass;

View File

@@ -85,6 +85,7 @@ export default class BookParser {
let binaryId = ''; let binaryId = '';
let binaryType = ''; let binaryType = '';
let dimPromises = []; let dimPromises = [];
this.coverPageId = '';
//оглавление //оглавление
this.contents = []; this.contents = [];
@@ -289,7 +290,7 @@ export default class BookParser {
const href = attrs.href.value; const href = attrs.href.value;
const alt = (attrs.alt && attrs.alt.value ? attrs.alt.value : ''); const alt = (attrs.alt && attrs.alt.value ? attrs.alt.value : '');
const {id, local} = this.imageHrefToId(href); const {id, local} = this.imageHrefToId(href);
if (href[0] == '#') {//local if (local) {//local
imageNum++; imageNum++;
if (inPara && !this.sets.showInlineImagesInCenter && !center) if (inPara && !this.sets.showInlineImagesInCenter && !center)
@@ -301,6 +302,11 @@ export default class BookParser {
if (inPara && this.sets.showInlineImagesInCenter) if (inPara && this.sets.showInlineImagesInCenter)
newParagraph(); newParagraph();
//coverpage
if (path == '/fictionbook/description/title-info/coverpage/image') {
this.coverPageId = id;
}
} else {//external } else {//external
imageNum++; imageNum++;

View File

@@ -2,8 +2,10 @@ import localForage from 'localforage';
import path from 'path-browserify'; import path from 'path-browserify';
import _ from 'lodash'; import _ from 'lodash';
import * as utils from '../../../share/utils';
import BookParser from './BookParser'; import BookParser from './BookParser';
import readerApi from '../../../api/reader';
import coversStorage from './coversStorage';
import * as utils from '../../../share/utils';
const maxDataSize = 500*1024*1024;//compressed bytes const maxDataSize = 500*1024*1024;//compressed bytes
const maxRecentLength = 5000; const maxRecentLength = 5000;
@@ -345,9 +347,36 @@ class BookManager {
const parsed = new BookParser(this.settings); const parsed = new BookParser(this.settings);
const parsedMeta = await parsed.parse(data, callback); const parsedMeta = await parsed.parse(data, callback);
//cover page
let coverPageUrl = '';
if (parsed.coverPageId && parsed.binary[parsed.coverPageId]) {
const bin = parsed.binary[parsed.coverPageId];
let dataUrl = `data:${bin.type};base64,${bin.data}`;
try {
dataUrl = await utils.resizeImage(dataUrl, 160, 160, 0.94);
} catch (e) {
console.error(e);
}
//отправим dataUrl на сервер в /upload
try {
await readerApi.uploadFileBuf(dataUrl, (url) => {
coverPageUrl = url;
});
} catch (e) {
console.error(e);
}
//сохраним в storage
if (coverPageUrl)
await coversStorage.setData(coverPageUrl, dataUrl);
}
const result = Object.assign({}, meta, parsedMeta, { const result = Object.assign({}, meta, parsedMeta, {
length: data.length, length: data.length,
textLength: parsed.textLength, textLength: parsed.textLength,
coverPageUrl,
parsed parsed
}); });

View File

@@ -0,0 +1,61 @@
import localForage from 'localforage';
//import _ from 'lodash';
import * as utils from '../../../share/utils';
const maxDataSize = 100*1024*1024;
const coversStore = localForage.createInstance({
name: 'coversStorage'
});
class CoversStorage {
constructor() {
}
async init() {
this.cleanCovers(); //no await
}
async setData(key, data) {
await coversStore.setItem(key, {addTime: Date.now(), data});
}
async getData(key) {
const item = await coversStore.getItem(key);
return (item ? item.data : undefined);
}
async removeData(key) {
await coversStore.removeItem(key);
}
async cleanCovers() {
await utils.sleep(10000);
while (1) {// eslint-disable-line no-constant-condition
let size = 0;
let min = Date.now();
let toDel = null;
for (const key of (await coversStore.keys())) {
const item = await coversStore.getItem(key);
size += item.data.length;
if (item.addTime < min) {
toDel = key;
min = item.addTime;
}
}
if (size > maxDataSize && toDel) {
await this.removeData(toDel);
} else {
break;
}
}
}
}
export default new CoversStorage();

View File

@@ -32,6 +32,10 @@ class WallpaperStorage {
this.cachedKeys = await wpStore.keys(); this.cachedKeys = await wpStore.keys();
} }
async getKeys() {
return await wpStore.keys();
}
keyExists(key) {//не асинхронная keyExists(key) {//не асинхронная
return this.cachedKeys.includes(key); return this.cachedKeys.includes(key);
} }

View File

@@ -1,4 +1,18 @@
export const versionHistory = [ export const versionHistory = [
{
version: '0.11.8',
releaseDate: '2022-07-14',
showUntil: '2022-07-13',
content:
`
<ul>
<li>добавлено отображение и синхронизация обложек в окне загруженных книг</li>
<li>добавлена синхронизация обоев</li>
</ul>
`
},
{ {
version: '0.11.7', version: '0.11.7',
releaseDate: '2022-07-12', releaseDate: '2022-07-12',

View File

@@ -363,4 +363,50 @@ export function getBookTitle(fb2) {
]).join(' - '); ]).join(' - ');
return result; return result;
}
export function resizeImage(dataUrl, toWidth, toHeight, quality = 0.9) {
return new Promise ((resolve, reject) => { (async() => {
const img = new Image();
let resolved = false;
img.onload = () => {
try {
let width = img.width;
let height = img.height;
if (width > height) {
if (width > toWidth) {
height = height * (toWidth / width);
width = toWidth;
}
} else {
if (height > toHeight) {
width = width * (toHeight / height);
height = toHeight;
}
}
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
const result = canvas.toDataURL('image/jpeg', quality);
resolved = true;
resolve(result);
} catch (e) {
reject(e);
return;
}
};
img.onerror = reject;
img.src = dataUrl;
await sleep(1000);
if (!resolved)
reject('Не удалось изменить размер');
})().catch(reject); });
} }

View File

@@ -191,6 +191,8 @@ const settingDefaults = {
recentShowSameBook: false, recentShowSameBook: false,
recentSortMethod: '', recentSortMethod: '',
needUpdateSettingsView: 0,
}; };
for (const font of fonts) for (const font of fonts)

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.11.7", "version": "0.11.8",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "Liberama", "name": "Liberama",
"version": "0.11.7", "version": "0.11.8",
"hasInstallScript": true, "hasInstallScript": true,
"license": "CC0-1.0", "license": "CC0-1.0",
"dependencies": { "dependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.11.7", "version": "0.11.8",
"author": "Book Pauk <bookpauk@gmail.com>", "author": "Book Pauk <bookpauk@gmail.com>",
"license": "CC0-1.0", "license": "CC0-1.0",
"repository": "bookpauk/liberama", "repository": "bookpauk/liberama",

View File

@@ -25,6 +25,10 @@ class WebSocketController {
ws.on('message', (message) => { ws.on('message', (message) => {
this.onMessage(ws, message.toString()); this.onMessage(ws, message.toString());
}); });
ws.on('error', (err) => {
log(LM_ERR, err);
});
}); });
setTimeout(() => { this.periodicClean(); }, cleanPeriod); setTimeout(() => { this.periodicClean(); }, cleanPeriod);
@@ -70,6 +74,10 @@ class WebSocketController {
await this.readerRestoreCachedFile(req, ws); break; await this.readerRestoreCachedFile(req, ws); break;
case 'reader-storage': case 'reader-storage':
await this.readerStorageDo(req, ws); break; await this.readerStorageDo(req, ws); break;
case 'upload-file-buf':
await this.uploadFileBuf(req, ws); break;
case 'upload-file-touch':
await this.uploadFileTouch(req, ws); break;
default: default:
throw new Error(`Action not found: ${req.action}`); throw new Error(`Action not found: ${req.action}`);
@@ -168,6 +176,20 @@ class WebSocketController {
this.send(await this.readerStorage.doAction(req.body), req, ws); this.send(await this.readerStorage.doAction(req.body), req, ws);
} }
async uploadFileBuf(req, ws) {
if (!req.buf)
throw new Error(`key 'buf' is empty`);
this.send({url: await this.readerWorker.saveFileBuf(req.buf)}, req, ws);
}
async uploadFileTouch(req, ws) {
if (!req.url)
throw new Error(`key 'url' is empty`);
this.send({url: await this.readerWorker.uploadFileTouch(req.url)}, req, ws);
}
} }
module.exports = WebSocketController; module.exports = WebSocketController;

View File

@@ -219,6 +219,27 @@ class ReaderWorker {
return `disk://${hash}`; return `disk://${hash}`;
} }
async saveFileBuf(buf) {
const hash = await utils.getBufHash(buf, 'sha256', 'hex');
const outFilename = `${this.config.uploadDir}/${hash}`;
if (!await fs.pathExists(outFilename)) {
await fs.writeFile(outFilename, buf);
} else {
await utils.touchFile(outFilename);
}
return `disk://${hash}`;
}
async uploadFileTouch(url) {
const outFilename = `${this.config.uploadDir}/${url.replace('disk://', '')}`;
await utils.touchFile(outFilename);
return url;
}
async restoreRemoteFile(filename) { async restoreRemoteFile(filename) {
const basename = path.basename(filename); const basename = path.basename(filename);
const targetName = `${this.config.tempPublicDir}/${basename}`; const targetName = `${this.config.tempPublicDir}/${basename}`;

View File

@@ -94,7 +94,7 @@ class WebSocketConnection {
this.ws = new this.WebSocket(this.url); this.ws = new this.WebSocket(this.url);
} }
const onopen = (e) => { const onopen = () => {
this.connecting = false; this.connecting = false;
resolve(this.ws); resolve(this.ws);
}; };

View File

@@ -34,6 +34,12 @@ function getFileHash(filename, hashName, enc) {
}); });
} }
function getBufHash(buf, hashName, enc) {
const hash = crypto.createHash(hashName);
hash.update(buf);
return hash.digest(enc);
}
function sleep(ms) { function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
@@ -129,6 +135,7 @@ module.exports = {
fromBase36, fromBase36,
bufferRemoveZeroes, bufferRemoveZeroes,
getFileHash, getFileHash,
getBufHash,
sleep, sleep,
toUnixTime, toUnixTime,
randomHexString, randomHexString,

View File

@@ -11,6 +11,8 @@ const ayncExit = new (require('./core/AsyncExit'))();
let log = null; let log = null;
const maxPayloadSize = 50;//in MB
async function init() { async function init() {
//config //config
const configManager = new (require('./config'))();//singleton const configManager = new (require('./config'))();//singleton
@@ -63,7 +65,7 @@ async function main() {
if (serverCfg.mode !== 'none') { if (serverCfg.mode !== 'none') {
const app = express(); const app = express();
const server = http.createServer(app); const server = http.createServer(app);
const wss = new WebSocket.Server({ server, maxPayload: 10*1024*1024 }); const wss = new WebSocket.Server({ server, maxPayload: maxPayloadSize*1024*1024 });
const serverConfig = Object.assign({}, config, serverCfg); const serverConfig = Object.assign({}, config, serverCfg);
@@ -75,7 +77,7 @@ async function main() {
} }
app.use(compression({ level: 1 })); app.use(compression({ level: 1 }));
app.use(express.json({limit: '10mb'})); app.use(express.json({limit: `${maxPayloadSize}mb`}));
if (devModule) if (devModule)
devModule.logQueries(app); devModule.logQueries(app);