Работа над RemoteLib
This commit is contained in:
@@ -2,7 +2,6 @@ const path = require('path');
|
|||||||
const pckg = require('../../package.json');
|
const pckg = require('../../package.json');
|
||||||
|
|
||||||
const execDir = path.resolve(__dirname, '..');
|
const execDir = path.resolve(__dirname, '..');
|
||||||
const dataDir = `${execDir}/.${pckg.name}`;
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
branch: 'unknown',
|
branch: 'unknown',
|
||||||
@@ -10,10 +9,6 @@ module.exports = {
|
|||||||
name: pckg.name,
|
name: pckg.name,
|
||||||
|
|
||||||
execDir,
|
execDir,
|
||||||
dataDir,
|
|
||||||
tempDir: `${dataDir}/tmp`,
|
|
||||||
logDir: `${dataDir}/log`,
|
|
||||||
publicDir: `${dataDir}/public`,
|
|
||||||
|
|
||||||
accessPassword: '',
|
accessPassword: '',
|
||||||
bookReadLink: '',
|
bookReadLink: '',
|
||||||
@@ -27,6 +22,16 @@ module.exports = {
|
|||||||
|
|
||||||
webConfigParams: ['name', 'version', 'branch', 'bookReadLink'],
|
webConfigParams: ['name', 'version', 'branch', 'bookReadLink'],
|
||||||
|
|
||||||
|
allowRemoteLib: false,
|
||||||
|
remoteLib: false,
|
||||||
|
/*
|
||||||
|
allowRemoteLib: true, // на сервере
|
||||||
|
remoteLib: { // на клиенте
|
||||||
|
accessPassword: '',
|
||||||
|
url: 'wss://remoteInpxWeb.ru',
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
server: {
|
server: {
|
||||||
ip: '0.0.0.0',
|
ip: '0.0.0.0',
|
||||||
port: '22380',
|
port: '22380',
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
const path = require('path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
const branchFilename = __dirname + '/application_env';
|
const branchFilename = __dirname + '/application_env';
|
||||||
@@ -12,6 +13,8 @@ const propsToSave = [
|
|||||||
'cacheCleanInterval',
|
'cacheCleanInterval',
|
||||||
'inpxCheckInterval',
|
'inpxCheckInterval',
|
||||||
'lowMemoryMode',
|
'lowMemoryMode',
|
||||||
|
'allowRemoteLib',
|
||||||
|
'remoteLib',
|
||||||
'server',
|
'server',
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -29,7 +32,7 @@ class ConfigManager {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init(dataDir) {
|
||||||
if (this.inited)
|
if (this.inited)
|
||||||
throw new Error('already inited');
|
throw new Error('already inited');
|
||||||
|
|
||||||
@@ -44,10 +47,17 @@ class ConfigManager {
|
|||||||
process.env.NODE_ENV = this.branch;
|
process.env.NODE_ENV = this.branch;
|
||||||
|
|
||||||
this.branchConfigFile = __dirname + `/${this.branch}.js`;
|
this.branchConfigFile = __dirname + `/${this.branch}.js`;
|
||||||
this._config = require(this.branchConfigFile);
|
const config = require(this.branchConfigFile);
|
||||||
|
|
||||||
await fs.ensureDir(this._config.dataDir);
|
if (dataDir) {
|
||||||
this._userConfigFile = `${this._config.dataDir}/config.json`;
|
config.dataDir = path.resolve(dataDir);
|
||||||
|
} else {
|
||||||
|
config.dataDir = `${config.execDir}/.${config.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
await fs.ensureDir(config.dataDir);
|
||||||
|
this._userConfigFile = `${config.dataDir}/config.json`;
|
||||||
|
this._config = config;
|
||||||
|
|
||||||
this.inited = true;
|
this.inited = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const pckg = require('../../package.json');
|
|
||||||
const base = require('./base');
|
const base = require('./base');
|
||||||
|
|
||||||
const execDir = path.dirname(process.execPath);
|
const execDir = path.dirname(process.execPath);
|
||||||
const dataDir = `${execDir}/.${pckg.name}`;
|
|
||||||
|
|
||||||
module.exports = Object.assign({}, base, {
|
module.exports = Object.assign({}, base, {
|
||||||
branch: 'production',
|
branch: 'production',
|
||||||
|
|
||||||
execDir,
|
execDir,
|
||||||
dataDir,
|
|
||||||
tempDir: `${dataDir}/tmp`,
|
|
||||||
logDir: `${dataDir}/log`,
|
|
||||||
publicDir: `${dataDir}/public`,
|
|
||||||
|
|
||||||
server: {
|
server: {
|
||||||
ip: '0.0.0.0',
|
ip: '0.0.0.0',
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const WebSocket = require ('ws');
|
const fs = require('fs-extra');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
const WebSocket = require ('ws');
|
||||||
|
|
||||||
const WorkerState = require('../core/WorkerState');//singleton
|
const WorkerState = require('../core/WorkerState');//singleton
|
||||||
const WebWorker = require('../core/WebWorker');//singleton
|
const WebWorker = require('../core/WebWorker');//singleton
|
||||||
@@ -83,6 +84,9 @@ class WebSocketController {
|
|||||||
case 'get-book-link':
|
case 'get-book-link':
|
||||||
await this.getBookLink(req, ws); break;
|
await this.getBookLink(req, ws); break;
|
||||||
|
|
||||||
|
case 'get-inpx-file':
|
||||||
|
await this.getInpxFile(req, ws); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Action not found: ${req.action}`);
|
throw new Error(`Action not found: ${req.action}`);
|
||||||
}
|
}
|
||||||
@@ -162,6 +166,16 @@ class WebSocketController {
|
|||||||
|
|
||||||
this.send(result, req, ws);
|
this.send(result, req, ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getInpxFile(req, ws) {
|
||||||
|
if (!this.config.allowRemoteLib)
|
||||||
|
throw new Error('Remote lib access disabled');
|
||||||
|
|
||||||
|
const data = await fs.readFile(this.config.inpxFile, 'base64');
|
||||||
|
|
||||||
|
this.send({data}, req, ws);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = WebSocketController;
|
module.exports = WebSocketController;
|
||||||
|
|||||||
56
server/core/RemoteLib.js
Normal file
56
server/core/RemoteLib.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
const fs = require('fs-extra');
|
||||||
|
const utils = require('./utils');
|
||||||
|
|
||||||
|
const WebSocketConnection = require('./WebSocketConnection');
|
||||||
|
|
||||||
|
//singleton
|
||||||
|
let instance = null;
|
||||||
|
|
||||||
|
class RemoteLib {
|
||||||
|
constructor(config) {
|
||||||
|
if (!instance) {
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
|
this.wsc = new WebSocketConnection(config.remoteLib.url, 10, 30, {rejectUnauthorized: false});
|
||||||
|
if (config.remoteLib.accessPassword)
|
||||||
|
this.accessToken = utils.getBufHash(config.remoteLib.accessPassword, 'sha256', 'hex');
|
||||||
|
|
||||||
|
this.inpxFile = `${config.tempDir}/${utils.randomHexString(20)}`;
|
||||||
|
this.lastUpdateTime = 0;
|
||||||
|
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
async wsRequest(query) {
|
||||||
|
if (this.accessToken)
|
||||||
|
query.accessToken = this.accessToken;
|
||||||
|
|
||||||
|
const response = await this.wsc.message(
|
||||||
|
await this.wsc.send(query, 60),
|
||||||
|
60
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.error)
|
||||||
|
throw new Error(response.error);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getInpxFile(getPeriod = 0) {
|
||||||
|
if (getPeriod && Date.now() - this.lastUpdateTime < getPeriod)
|
||||||
|
return this.inpxFile;
|
||||||
|
|
||||||
|
const response = await this.wsRequest({action: 'get-inpx-file'});
|
||||||
|
|
||||||
|
await fs.writeFile(this.inpxFile, response.data, 'base64');
|
||||||
|
|
||||||
|
this.lastUpdateTime = Date.now();
|
||||||
|
|
||||||
|
return this.inpxFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RemoteLib;
|
||||||
@@ -5,11 +5,12 @@ const zlib = require('zlib');
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
||||||
const ZipReader = require('./ZipReader');
|
const ZipReader = require('./ZipReader');
|
||||||
const WorkerState = require('./WorkerState');
|
const WorkerState = require('./WorkerState');//singleton
|
||||||
const { JembaDbThread } = require('jembadb');
|
const { JembaDbThread } = require('jembadb');
|
||||||
const DbCreator = require('./DbCreator');
|
const DbCreator = require('./DbCreator');
|
||||||
const DbSearcher = require('./DbSearcher');
|
const DbSearcher = require('./DbSearcher');
|
||||||
const InpxHashCreator = require('./InpxHashCreator');
|
const InpxHashCreator = require('./InpxHashCreator');
|
||||||
|
const RemoteLib = require('./RemoteLib');//singleton
|
||||||
|
|
||||||
const ayncExit = new (require('./AsyncExit'))();
|
const ayncExit = new (require('./AsyncExit'))();
|
||||||
const log = new (require('./AppLogger'))().log;//singleton
|
const log = new (require('./AppLogger'))().log;//singleton
|
||||||
@@ -505,6 +506,11 @@ class WebWorker {
|
|||||||
while (this.myState != ssNormal)
|
while (this.myState != ssNormal)
|
||||||
await utils.sleep(1000);
|
await utils.sleep(1000);
|
||||||
|
|
||||||
|
if (this.config.remoteLib) {
|
||||||
|
const remoteLib = new RemoteLib(this.config);
|
||||||
|
await remoteLib.getInpxFile(60*1000);
|
||||||
|
}
|
||||||
|
|
||||||
const newInpxHash = await inpxHashCreator.getHash();
|
const newInpxHash = await inpxHashCreator.getHash();
|
||||||
|
|
||||||
const dbConfig = await this.dbConfig();
|
const dbConfig = await this.dbConfig();
|
||||||
|
|||||||
102
server/index.js
102
server/index.js
@@ -6,16 +6,18 @@ const compression = require('compression');
|
|||||||
const http = require('http');
|
const http = require('http');
|
||||||
const WebSocket = require ('ws');
|
const WebSocket = require ('ws');
|
||||||
|
|
||||||
const ayncExit = new (require('./core/AsyncExit'))();
|
const RemoteLib = require('./core/RemoteLib');//singleton
|
||||||
const utils = require('./core/utils');
|
const utils = require('./core/utils');
|
||||||
|
|
||||||
|
const ayncExit = new (require('./core/AsyncExit'))();
|
||||||
|
|
||||||
const maxPayloadSize = 50;//in MB
|
const maxPayloadSize = 50;//in MB
|
||||||
|
|
||||||
let log;
|
let log;
|
||||||
let config;
|
let config;
|
||||||
let argv;
|
let argv;
|
||||||
let branch = '';
|
let branch = '';
|
||||||
const argvStrings = ['lib-dir', 'inpx'];
|
const argvStrings = ['lib-dir', 'app-dir', 'inpx'];
|
||||||
|
|
||||||
function showHelp() {
|
function showHelp() {
|
||||||
console.log(utils.versionText(config));
|
console.log(utils.versionText(config));
|
||||||
@@ -24,6 +26,7 @@ function showHelp() {
|
|||||||
|
|
||||||
Options:
|
Options:
|
||||||
--help Print ${config.name} command line options
|
--help Print ${config.name} command line options
|
||||||
|
--app-dir=<dirpath> Set application working directory, default: "<execDir>/.${config.name}"
|
||||||
--lib-dir=<dirpath> Set library directory, default: the same as ${config.name} executable's
|
--lib-dir=<dirpath> Set library directory, default: the same as ${config.name} executable's
|
||||||
--inpx=<filepath> Set INPX collection file, default: the one that found in library dir
|
--inpx=<filepath> Set INPX collection file, default: the one that found in library dir
|
||||||
--recreate Force recreation of the search database on start
|
--recreate Force recreation of the search database on start
|
||||||
@@ -33,25 +36,30 @@ Options:
|
|||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
argv = require('minimist')(process.argv.slice(2), {string: argvStrings});
|
argv = require('minimist')(process.argv.slice(2), {string: argvStrings});
|
||||||
|
const dataDir = argv['app-dir'];
|
||||||
|
|
||||||
//config
|
//config
|
||||||
const configManager = new (require('./config'))();//singleton
|
const configManager = new (require('./config'))();//singleton
|
||||||
await configManager.init();
|
await configManager.init(dataDir);
|
||||||
//configManager.userConfigFile = argv.config;
|
|
||||||
await configManager.load();
|
await configManager.load();
|
||||||
config = configManager.config;
|
config = configManager.config;
|
||||||
branch = config.branch;
|
branch = config.branch;
|
||||||
|
|
||||||
|
//dirs
|
||||||
|
config.tempDir = `${config.dataDir}/tmp`;
|
||||||
|
config.logDir = `${config.dataDir}/log`;
|
||||||
|
config.publicDir = `${config.dataDir}/public`;
|
||||||
|
configManager.config = config;
|
||||||
|
|
||||||
|
await fs.ensureDir(config.dataDir);
|
||||||
|
await fs.ensureDir(config.tempDir);
|
||||||
|
await fs.emptyDir(config.tempDir);
|
||||||
|
|
||||||
//logger
|
//logger
|
||||||
const appLogger = new (require('./core/AppLogger'))();//singleton
|
const appLogger = new (require('./core/AppLogger'))();//singleton
|
||||||
await appLogger.init(config);
|
await appLogger.init(config);
|
||||||
log = appLogger.log;
|
log = appLogger.log;
|
||||||
|
|
||||||
//dirs
|
|
||||||
await fs.ensureDir(config.dataDir);
|
|
||||||
await fs.ensureDir(config.tempDir);
|
|
||||||
await fs.emptyDir(config.tempDir);
|
|
||||||
|
|
||||||
//web app
|
//web app
|
||||||
if (branch !== 'development') {
|
if (branch !== 'development') {
|
||||||
const createWebApp = require('./createWebApp');
|
const createWebApp = require('./createWebApp');
|
||||||
@@ -67,52 +75,49 @@ async function init() {
|
|||||||
log('Initializing');
|
log('Initializing');
|
||||||
}
|
}
|
||||||
|
|
||||||
const libDir = argv['lib-dir'];
|
if (!config.remoteLib) {
|
||||||
if (libDir) {
|
const libDir = argv['lib-dir'];
|
||||||
if (await fs.pathExists(libDir)) {
|
if (libDir) {
|
||||||
config.libDir = libDir;
|
if (await fs.pathExists(libDir)) {
|
||||||
} else {
|
config.libDir = libDir;
|
||||||
throw new Error(`Directory "${libDir}" not exists`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
config.libDir = config.execDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argv.inpx) {
|
|
||||||
if (await fs.pathExists(argv.inpx)) {
|
|
||||||
config.inpxFile = argv.inpx;
|
|
||||||
} else {
|
|
||||||
throw new Error(`File "${argv.inpx}" not found`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const inpxFiles = [];
|
|
||||||
await utils.findFiles((file) => {
|
|
||||||
if (path.extname(file) == '.inpx')
|
|
||||||
inpxFiles.push(file);
|
|
||||||
}, config.libDir, false);
|
|
||||||
|
|
||||||
if (inpxFiles.length) {
|
|
||||||
if (inpxFiles.length == 1) {
|
|
||||||
config.inpxFile = inpxFiles[0];
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Found more than one .inpx files: \n${inpxFiles.join('\n')}`);
|
throw new Error(`Directory "${libDir}" not exists`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`No .inpx files found here: ${config.libDir}`);
|
config.libDir = config.execDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argv.inpx) {
|
||||||
|
if (await fs.pathExists(argv.inpx)) {
|
||||||
|
config.inpxFile = argv.inpx;
|
||||||
|
} else {
|
||||||
|
throw new Error(`File "${argv.inpx}" not found`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const inpxFiles = [];
|
||||||
|
await utils.findFiles((file) => {
|
||||||
|
if (path.extname(file) == '.inpx')
|
||||||
|
inpxFiles.push(file);
|
||||||
|
}, config.libDir, false);
|
||||||
|
|
||||||
|
if (inpxFiles.length) {
|
||||||
|
if (inpxFiles.length == 1) {
|
||||||
|
config.inpxFile = inpxFiles[0];
|
||||||
|
} else {
|
||||||
|
throw new Error(`Found more than one .inpx files: \n${inpxFiles.join('\n')}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(`No .inpx files found here: ${config.libDir}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const remoteLib = new RemoteLib(config);
|
||||||
|
config.inpxFile = await remoteLib.getInpxFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
config.recreateDb = argv.recreate || false;
|
config.recreateDb = argv.recreate || false;
|
||||||
config.inpxFilterFile = `${config.execDir}/inpx-web-filter.json`;
|
config.inpxFilterFile = `${config.execDir}/inpx-web-filter.json`;
|
||||||
config.allowUnsafeFilter = argv['unsafe-filter'] || false;
|
config.allowUnsafeFilter = argv['unsafe-filter'] || false;
|
||||||
|
|
||||||
//app
|
|
||||||
const appDir = `${config.publicDir}/app`;
|
|
||||||
const appNewDir = `${config.publicDir}/app_new`;
|
|
||||||
if (await fs.pathExists(appNewDir)) {
|
|
||||||
await fs.remove(appDir);
|
|
||||||
await fs.move(appNewDir, appDir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
@@ -124,10 +129,8 @@ async function main() {
|
|||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
const wss = new WebSocket.Server({ server, maxPayload: maxPayloadSize*1024*1024 });
|
const wss = new WebSocket.Server({ server, maxPayload: maxPayloadSize*1024*1024 });
|
||||||
|
|
||||||
const serverConfig = Object.assign({}, config, config.server);
|
|
||||||
|
|
||||||
let devModule = undefined;
|
let devModule = undefined;
|
||||||
if (serverConfig.branch == 'development') {
|
if (branch == 'development') {
|
||||||
const devFileName = './dev.js'; //require ignored by pkg -50Mb executable size
|
const devFileName = './dev.js'; //require ignored by pkg -50Mb executable size
|
||||||
devModule = require(devFileName);
|
devModule = require(devFileName);
|
||||||
devModule.webpackDevMiddleware(app);
|
devModule.webpackDevMiddleware(app);
|
||||||
@@ -152,6 +155,7 @@ async function main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const serverConfig = config.server;
|
||||||
server.listen(serverConfig.port, serverConfig.ip, () => {
|
server.listen(serverConfig.port, serverConfig.ip, () => {
|
||||||
log(`Server is ready on http://${serverConfig.ip}:${serverConfig.port}`);
|
log(`Server is ready on http://${serverConfig.ip}:${serverConfig.port}`);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user