diff --git a/client/components/Search/Search.vue b/client/components/Search/Search.vue
index 0dbe05d..b4225d2 100644
--- a/client/components/Search/Search.vue
+++ b/client/components/Search/Search.vue
@@ -845,7 +845,13 @@ class Search {
if (await utils.copyTextToClipboard(href))
this.$root.notify.success('Ссылка успешно скопирована');
else
- this.$root.notify.error('Копирование ссылки не удалось');
+ this.$root.stdDialog.alert(
+`Копирование ссылки не удалось. Пожалуйста, попробуйте еще раз.
+
+Пояснение: вероятно, браузер запретил копирование, т.к. прошло
+слишком много времени с момента нажатия на кнопку (инициация
+пользовательского события). Сейчас ссылка уже закеширована,
+поэтому повторная попытка должна быть успешной.`, 'Ошибка');
} else if (action == 'readBook') {
//читать
if (this.liberamaReady) {
diff --git a/package-lock.json b/package-lock.json
index 85bbb33..7c68481 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "inpx-web",
- "version": "1.0.0",
+ "version": "1.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "inpx-web",
- "version": "1.0.0",
+ "version": "1.0.2",
"hasInstallScript": true,
"license": "CC0-1.0",
"dependencies": {
diff --git a/package.json b/package.json
index 65b5e30..80543cc 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "inpx-web",
- "version": "1.0.1",
+ "version": "1.0.2",
"author": "Book Pauk ",
"license": "CC0-1.0",
"repository": "bookpauk/inpx-web",
diff --git a/server/controllers/WebSocketController.js b/server/controllers/WebSocketController.js
index 8f0c4e8..6c2d338 100644
--- a/server/controllers/WebSocketController.js
+++ b/server/controllers/WebSocketController.js
@@ -1,4 +1,3 @@
-const fs = require('fs-extra');
const _ = require('lodash');
const WebSocket = require ('ws');
@@ -182,9 +181,9 @@ class WebSocketController {
if (!this.config.allowRemoteLib)
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);
}
}
diff --git a/server/core/FileDownloader.js b/server/core/FileDownloader.js
index 5f86e5a..aab1c21 100644
--- a/server/core/FileDownloader.js
+++ b/server/core/FileDownloader.js
@@ -9,10 +9,10 @@ class FileDownloader {
this.limitDownloadSize = limitDownloadSize;
}
- async load(url, callback, abort) {
+ async load(url, opts, callback, abort) {
let errMes = '';
- const options = {
+ let options = {
headers: {
'user-agent': userAgent,
timeout: 300*1000,
@@ -22,6 +22,8 @@ class FileDownloader {
}),
responseType: 'stream',
};
+ if (opts)
+ options = Object.assign({}, opts, options);
try {
const res = await axios.get(url, options);
diff --git a/server/core/InpxHashCreator.js b/server/core/InpxHashCreator.js
index 8bda1d9..35460da 100644
--- a/server/core/InpxHashCreator.js
+++ b/server/core/InpxHashCreator.js
@@ -23,6 +23,14 @@ class InpxHashCreator {
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;
\ No newline at end of file
diff --git a/server/core/RemoteLib.js b/server/core/RemoteLib.js
index fe0520c..5bd0238 100644
--- a/server/core/RemoteLib.js
+++ b/server/core/RemoteLib.js
@@ -4,6 +4,7 @@ const utils = require('./utils');
const FileDownloader = require('./FileDownloader');
const WebSocketConnection = require('./WebSocketConnection');
+const InpxHashCreator = require('./InpxHashCreator');
const log = new (require('./AppLogger'))().log;//singleton
//singleton
@@ -20,10 +21,9 @@ class RemoteLib {
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.inpxHashCreator = new InpxHashCreator(config);
+ this.inpxFileHash = '';
instance = this;
}
@@ -46,17 +46,16 @@ class RemoteLib {
return response;
}
- async downloadInpxFile(getPeriod = 0) {
- if (getPeriod && Date.now() - this.lastUpdateTime < getPeriod)
- return this.inpxFile;
+ async downloadInpxFile() {
+ if (!this.inpxFileHash)
+ 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');
-
- this.lastUpdateTime = Date.now();
-
- return this.inpxFile;
+ if (response.data) {
+ await fs.writeFile(this.config.inpxFile, response.data, 'base64');
+ this.inpxFileHash = '';
+ }
}
async downloadBook(bookPath, downFileName) {
@@ -64,17 +63,11 @@ class RemoteLib {
const response = await await this.wsRequest({action: 'get-book-link', bookPath, downFileName});
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}`;
- await fs.writeFile(tmpFile, buf);
-
- await utils.gzipFile(tmpFile, tmpFile2, 4);
- await fs.remove(tmpFile);
- await fs.move(tmpFile2, publicPath, {overwrite: true});
+ await fs.writeFile(publicPath, buf);
return path.basename(link);
} catch (e) {
diff --git a/server/core/WebWorker.js b/server/core/WebWorker.js
index 759ae6e..472c38b 100644
--- a/server/core/WebWorker.js
+++ b/server/core/WebWorker.js
@@ -43,6 +43,9 @@ class WebWorker {
this.remoteLib = new RemoteLib(config);
}
+ this.inpxHashCreator = new InpxHashCreator(config);
+ this.inpxFileHash = '';
+
this.wState = this.workerState.getControl('server_state');
this.myState = '';
this.db = null;
@@ -136,6 +139,8 @@ class WebWorker {
const config = this.config;
const dbPath = `${config.dataDir}/db`;
+ this.inpxFileHash = await this.inpxHashCreator.getInpxFileHash();
+
//пересоздаем БД из INPX если нужно
if (config.recreateDb || recreate)
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() {
try {
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(', ')}) ]`);
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) {
log(LM_ERR, e.message);
}
@@ -516,18 +533,16 @@ class WebWorker {
if (!inpxCheckInterval)
return;
- const inpxHashCreator = new InpxHashCreator(this.config);
-
while (1) {// eslint-disable-line no-constant-condition
try {
while (this.myState != ssNormal)
await utils.sleep(1000);
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 currentInpxHash = (dbConfig.inpxHash ? dbConfig.inpxHash : '');
diff --git a/server/core/utils.js b/server/core/utils.js
index 07beff4..18b9535 100644
--- a/server/core/utils.js
+++ b/server/core/utils.js
@@ -108,6 +108,10 @@ function gzipFile(inputFile, outputFile, level = 1) {
});
}
+function toUnixPath(dir) {
+ return dir.replace(/\\/g, '/');
+}
+
module.exports = {
sleep,
versionText,
@@ -120,4 +124,5 @@ module.exports = {
intersectSet,
randomHexString,
gzipFile,
+ toUnixPath,
};
\ No newline at end of file
diff --git a/server/index.js b/server/index.js
index 9f49286..f6305d1 100644
--- a/server/index.js
+++ b/server/index.js
@@ -114,9 +114,10 @@ async function init() {
}
}
} else {
+ config.inpxFile = `${config.tempDir}/${utils.randomHexString(20)}`;
const RemoteLib = require('./core/RemoteLib');//singleton
const remoteLib = new RemoteLib(config);
- config.inpxFile = await remoteLib.downloadInpxFile();
+ await remoteLib.downloadInpxFile();
}
config.recreateDb = argv.recreate || false;
@@ -207,10 +208,10 @@ function initStatic(app, config) {
const filesDir = `${config.publicDir}/files`;
app.use(express.static(config.publicDir, {
setHeaders: (res, filePath) => {
- res.set('Cache-Control', 'no-cache');
- res.set('Expires', '-1');
+ //res.set('Cache-Control', 'no-cache');
+ //res.set('Expires', '-1');
- if (path.dirname(filePath) == filesDir) {
+ if (utils.toUnixPath(path.dirname(filePath)) == utils.toUnixPath(filesDir)) {
res.set('Content-Encoding', 'gzip');
if (res.downFileName)