9 Commits
1.0.1 ... 1.0.2

Author SHA1 Message Date
Book Pauk
420c0f2464 Merge branch 'release/1.0.2' 2022-10-16 00:16:14 +07:00
Book Pauk
7e86621fcd Мелкая поправка 2022-10-15 22:02:36 +07:00
Book Pauk
4ddabd1ca9 1.0.2 2022-10-15 22:02:22 +07:00
Book Pauk
061f50b714 Исправлена отдача статики под Windows 2022-10-15 21:51:45 +07:00
Book Pauk
8aab918ac5 Поправил баг 2022-10-15 21:04:56 +07:00
Book Pauk
9aa9261b6a Улучшение работы RemoteLib.downloadInpxFile 2022-10-15 20:59:42 +07:00
Book Pauk
0894a38978 Рефакторинг 2022-10-15 18:59:13 +07:00
Book Pauk
f519bf3f67 Добавлено пояснение в случае неуспешного копирования ссылки 2022-10-15 18:43:14 +07:00
Book Pauk
ecf0aada37 Merge tag '1.0.1' into develop
1.0.1
2022-10-14 21:18:04 +07:00
10 changed files with 67 additions and 38 deletions

View File

@@ -845,7 +845,13 @@ class Search {
if (await utils.copyTextToClipboard(href)) if (await utils.copyTextToClipboard(href))
this.$root.notify.success('Ссылка успешно скопирована'); this.$root.notify.success('Ссылка успешно скопирована');
else else
this.$root.notify.error('Копирование ссылки не удалось'); this.$root.stdDialog.alert(
`Копирование ссылки не удалось. Пожалуйста, попробуйте еще раз.
<br><br>
<b>Пояснение</b>: вероятно, браузер запретил копирование, т.к. прошло<br>
слишком много времени с момента нажатия на кнопку (инициация<br>
пользовательского события). Сейчас ссылка уже закеширована,<br>
поэтому повторная попытка должна быть успешной.`, 'Ошибка');
} else if (action == 'readBook') { } else if (action == 'readBook') {
//читать //читать
if (this.liberamaReady) { if (this.liberamaReady) {

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "inpx-web", "name": "inpx-web",
"version": "1.0.0", "version": "1.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "inpx-web", "name": "inpx-web",
"version": "1.0.0", "version": "1.0.2",
"hasInstallScript": true, "hasInstallScript": true,
"license": "CC0-1.0", "license": "CC0-1.0",
"dependencies": { "dependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "inpx-web", "name": "inpx-web",
"version": "1.0.1", "version": "1.0.2",
"author": "Book Pauk <bookpauk@gmail.com>", "author": "Book Pauk <bookpauk@gmail.com>",
"license": "CC0-1.0", "license": "CC0-1.0",
"repository": "bookpauk/inpx-web", "repository": "bookpauk/inpx-web",

View File

@@ -1,4 +1,3 @@
const fs = require('fs-extra');
const _ = require('lodash'); const _ = require('lodash');
const WebSocket = require ('ws'); const WebSocket = require ('ws');
@@ -182,9 +181,9 @@ class WebSocketController {
if (!this.config.allowRemoteLib) if (!this.config.allowRemoteLib)
throw new Error('Remote lib access disabled'); throw new Error('Remote lib access disabled');
const data = await fs.readFile(this.config.inpxFile, 'base64'); const result = await this.webWorker.getInpxFile(req);
this.send({data}, req, ws); this.send(result, req, ws);
} }
} }

View File

@@ -9,10 +9,10 @@ class FileDownloader {
this.limitDownloadSize = limitDownloadSize; this.limitDownloadSize = limitDownloadSize;
} }
async load(url, callback, abort) { async load(url, opts, callback, abort) {
let errMes = ''; let errMes = '';
const options = { let options = {
headers: { headers: {
'user-agent': userAgent, 'user-agent': userAgent,
timeout: 300*1000, timeout: 300*1000,
@@ -22,6 +22,8 @@ class FileDownloader {
}), }),
responseType: 'stream', responseType: 'stream',
}; };
if (opts)
options = Object.assign({}, opts, options);
try { try {
const res = await axios.get(url, options); const res = await axios.get(url, options);

View File

@@ -23,6 +23,14 @@ class InpxHashCreator {
return utils.getBufHash(joinedHash, 'sha256', 'hex'); return utils.getBufHash(joinedHash, 'sha256', 'hex');
} }
async getInpxFileHash() {
return (
await fs.pathExists(this.config.inpxFile) ?
await utils.getFileHash(this.config.inpxFile, 'sha256', 'hex') :
''
);
}
} }
module.exports = InpxHashCreator; module.exports = InpxHashCreator;

View File

@@ -4,6 +4,7 @@ const utils = require('./utils');
const FileDownloader = require('./FileDownloader'); const FileDownloader = require('./FileDownloader');
const WebSocketConnection = require('./WebSocketConnection'); const WebSocketConnection = require('./WebSocketConnection');
const InpxHashCreator = require('./InpxHashCreator');
const log = new (require('./AppLogger'))().log;//singleton const log = new (require('./AppLogger'))().log;//singleton
//singleton //singleton
@@ -20,10 +21,9 @@ class RemoteLib {
this.remoteHost = config.remoteLib.url.replace(/^ws:\/\//, 'http://').replace(/^wss:\/\//, 'https://'); this.remoteHost = config.remoteLib.url.replace(/^ws:\/\//, 'http://').replace(/^wss:\/\//, 'https://');
this.inpxFile = `${config.tempDir}/${utils.randomHexString(20)}`;
this.lastUpdateTime = 0;
this.down = new FileDownloader(config.maxPayloadSize*1024*1024); this.down = new FileDownloader(config.maxPayloadSize*1024*1024);
this.inpxHashCreator = new InpxHashCreator(config);
this.inpxFileHash = '';
instance = this; instance = this;
} }
@@ -46,17 +46,16 @@ class RemoteLib {
return response; return response;
} }
async downloadInpxFile(getPeriod = 0) { async downloadInpxFile() {
if (getPeriod && Date.now() - this.lastUpdateTime < getPeriod) if (!this.inpxFileHash)
return this.inpxFile; this.inpxFileHash = await this.inpxHashCreator.getInpxFileHash();
const response = await this.wsRequest({action: 'get-inpx-file'}); const response = await this.wsRequest({action: 'get-inpx-file', inpxFileHash: this.inpxFileHash});
await fs.writeFile(this.inpxFile, response.data, 'base64'); if (response.data) {
await fs.writeFile(this.config.inpxFile, response.data, 'base64');
this.lastUpdateTime = Date.now(); this.inpxFileHash = '';
}
return this.inpxFile;
} }
async downloadBook(bookPath, downFileName) { async downloadBook(bookPath, downFileName) {
@@ -64,17 +63,11 @@ class RemoteLib {
const response = await await this.wsRequest({action: 'get-book-link', bookPath, downFileName}); const response = await await this.wsRequest({action: 'get-book-link', bookPath, downFileName});
const link = response.link; const link = response.link;
const buf = await this.down.load(`${this.remoteHost}${link}`); const buf = await this.down.load(`${this.remoteHost}${link}`, {decompress: false});
const tmpFile = `${this.config.tempDir}/${utils.randomHexString(30)}`;
const tmpFile2 = `${this.config.tempDir}/${utils.randomHexString(30)}`;
const publicPath = `${this.config.publicDir}${link}`; const publicPath = `${this.config.publicDir}${link}`;
await fs.writeFile(tmpFile, buf); await fs.writeFile(publicPath, buf);
await utils.gzipFile(tmpFile, tmpFile2, 4);
await fs.remove(tmpFile);
await fs.move(tmpFile2, publicPath, {overwrite: true});
return path.basename(link); return path.basename(link);
} catch (e) { } catch (e) {

View File

@@ -43,6 +43,9 @@ class WebWorker {
this.remoteLib = new RemoteLib(config); this.remoteLib = new RemoteLib(config);
} }
this.inpxHashCreator = new InpxHashCreator(config);
this.inpxFileHash = '';
this.wState = this.workerState.getControl('server_state'); this.wState = this.workerState.getControl('server_state');
this.myState = ''; this.myState = '';
this.db = null; this.db = null;
@@ -136,6 +139,8 @@ class WebWorker {
const config = this.config; const config = this.config;
const dbPath = `${config.dataDir}/db`; const dbPath = `${config.dataDir}/db`;
this.inpxFileHash = await this.inpxHashCreator.getInpxFileHash();
//пересоздаем БД из INPX если нужно //пересоздаем БД из INPX если нужно
if (config.recreateDb || recreate) if (config.recreateDb || recreate)
await fs.remove(dbPath); await fs.remove(dbPath);
@@ -427,6 +432,18 @@ class WebWorker {
} }
} }
async getInpxFile(params) {
let data = null;
if (params.inpxFileHash && this.inpxFileHash && params.inpxFileHash === this.inpxFileHash) {
data = false;
}
if (data === null)
data = await fs.readFile(this.config.inpxFile, 'base64');
return {data};
}
logServerStats() { logServerStats() {
try { try {
const memUsage = process.memoryUsage().rss/(1024*1024);//Mb const memUsage = process.memoryUsage().rss/(1024*1024);//Mb
@@ -436,7 +453,7 @@ class WebWorker {
log(`Server info [ memUsage: ${memUsage.toFixed(2)}MB, loadAvg: (${loadAvg.join(', ')}) ]`); log(`Server info [ memUsage: ${memUsage.toFixed(2)}MB, loadAvg: (${loadAvg.join(', ')}) ]`);
if (this.config.server.ready) if (this.config.server.ready)
log(`Server accessible on http://127.0.0.1:${this.config.server.port} (listening on ${this.config.server.host}:${this.config.server.port})`); log(`Server accessible at http://127.0.0.1:${this.config.server.port} (listening on ${this.config.server.host}:${this.config.server.port})`);
} catch (e) { } catch (e) {
log(LM_ERR, e.message); log(LM_ERR, e.message);
} }
@@ -516,18 +533,16 @@ class WebWorker {
if (!inpxCheckInterval) if (!inpxCheckInterval)
return; return;
const inpxHashCreator = new InpxHashCreator(this.config);
while (1) {// eslint-disable-line no-constant-condition while (1) {// eslint-disable-line no-constant-condition
try { try {
while (this.myState != ssNormal) while (this.myState != ssNormal)
await utils.sleep(1000); await utils.sleep(1000);
if (this.remoteLib) { if (this.remoteLib) {
await this.remoteLib.downloadInpxFile(60*1000); await this.remoteLib.downloadInpxFile();
} }
const newInpxHash = await inpxHashCreator.getHash(); const newInpxHash = await this.inpxHashCreator.getHash();
const dbConfig = await this.dbConfig(); const dbConfig = await this.dbConfig();
const currentInpxHash = (dbConfig.inpxHash ? dbConfig.inpxHash : ''); const currentInpxHash = (dbConfig.inpxHash ? dbConfig.inpxHash : '');

View File

@@ -108,6 +108,10 @@ function gzipFile(inputFile, outputFile, level = 1) {
}); });
} }
function toUnixPath(dir) {
return dir.replace(/\\/g, '/');
}
module.exports = { module.exports = {
sleep, sleep,
versionText, versionText,
@@ -120,4 +124,5 @@ module.exports = {
intersectSet, intersectSet,
randomHexString, randomHexString,
gzipFile, gzipFile,
toUnixPath,
}; };

View File

@@ -114,9 +114,10 @@ async function init() {
} }
} }
} else { } else {
config.inpxFile = `${config.tempDir}/${utils.randomHexString(20)}`;
const RemoteLib = require('./core/RemoteLib');//singleton const RemoteLib = require('./core/RemoteLib');//singleton
const remoteLib = new RemoteLib(config); const remoteLib = new RemoteLib(config);
config.inpxFile = await remoteLib.downloadInpxFile(); await remoteLib.downloadInpxFile();
} }
config.recreateDb = argv.recreate || false; config.recreateDb = argv.recreate || false;
@@ -207,10 +208,10 @@ function initStatic(app, config) {
const filesDir = `${config.publicDir}/files`; const filesDir = `${config.publicDir}/files`;
app.use(express.static(config.publicDir, { app.use(express.static(config.publicDir, {
setHeaders: (res, filePath) => { setHeaders: (res, filePath) => {
res.set('Cache-Control', 'no-cache'); //res.set('Cache-Control', 'no-cache');
res.set('Expires', '-1'); //res.set('Expires', '-1');
if (path.dirname(filePath) == filesDir) { if (utils.toUnixPath(path.dirname(filePath)) == utils.toUnixPath(filesDir)) {
res.set('Content-Encoding', 'gzip'); res.set('Content-Encoding', 'gzip');
if (res.downFileName) if (res.downFileName)