Start work on translation of web pages using --translate.
Ylian Saint-Hilaire committed
Jan 26, 2020 at 11:59 UTC
b1c391a37c7fc77e104d4e1ce81897b9a47e5c56
2 files changed
+67
-37
meshcentral.js
+19
-1
@@ -123,7 +123,7 @@ function CreateMeshCentralServer(config, args) {
123
try { require('./pass').hash('test', function () { }, 0); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not.
124
125
// Check for invalid arguments
126
- var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'rediraliasport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'showusergroups', 'shownodes', 'showmeshes', 'showevents', 'showsmbios', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'xinstall', 'xuninstall', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbexportmin', 'dbimport', 'dbmerge', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'userblockedip', 'swarmallowedip', 'agentallowedip', 'agentblockedip', 'fastcert', 'swarmport', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore', 'dblistconfigfiles', 'dbshowconfigfile', 'dbpushconfigfiles', 'dbpullconfigfiles', 'dbdeleteconfigfiles', 'vaultpushconfigfiles', 'vaultpullconfigfiles', 'vaultdeleteconfigfiles', 'configkey', 'loadconfigfromdb', 'npmpath', 'memorytracking', 'serverid', 'recordencryptionrecode', 'vault', 'token', 'unsealkey', 'name', 'log', 'dbstats'];
126
+ var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'rediraliasport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'showusergroups', 'shownodes', 'showmeshes', 'showevents', 'showsmbios', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'xinstall', 'xuninstall', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbexportmin', 'dbimport', 'dbmerge', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'userblockedip', 'swarmallowedip', 'agentallowedip', 'agentblockedip', 'fastcert', 'swarmport', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore', 'dblistconfigfiles', 'dbshowconfigfile', 'dbpushconfigfiles', 'dbpullconfigfiles', 'dbdeleteconfigfiles', 'vaultpushconfigfiles', 'vaultpullconfigfiles', 'vaultdeleteconfigfiles', 'configkey', 'loadconfigfromdb', 'npmpath', 'memorytracking', 'serverid', 'recordencryptionrecode', 'vault', 'token', 'unsealkey', 'name', 'log', 'dbstats', 'translate'];
127
for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
128
if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; }
129
for (i in obj.config.settings) { obj.args[i] = obj.config.settings[i]; } // Place all settings into arguments, arguments have already been placed into settings so arguments take precedence.
@@ -152,6 +152,24 @@ function CreateMeshCentralServer(config, args) {
152
return;
153
}
154
155
+ // Perform web site translations into different languages
156
+ if (obj.args.translate) {
157
+ // Check if translate.json is in the "meshcentral-data" folder, if so use that and translate default pages.
158
+ // TODO
159
+
160
+ process.chdir('./translate');
161
+ var translateEngine = require('./translate/translate.js')
162
+ translateEngine.startEx(['', '', 'minifyall']);
163
+ translateEngine.startEx(['', '', 'translateall']);
164
+ translateEngine.startEx(['', '', 'extractall']);
165
+ process.exit();
166
+
167
+ // Check is "meshcentral-web" exists, if so, translate all pages in that folder.
168
+ // TODO
169
+
170
+ return;
171
+ }
172
+
173
// Linux background service systemd handling
174
if (obj.platform == 'linux') {
175
if (obj.args.install == true) {
translate/translate.js
+48
-36
@@ -33,9 +33,12 @@ var meshCentralSourceFiles = [
33
"../public/player.htm"
34
];
35
36
+// True is this module is run directly using NodeJS
37
+var directRun = (require.main === module);
38
+
39
// Check NodeJS version
40
const NodeJSVer = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
38
-if (NodeJSVer < 8) { log("Translate.js requires Node v8 or above, current version is " + process.version + "."); return; }
41
+if (directRun && (NodeJSVer < 8)) { log("Translate.js requires Node v8 or above, current version is " + process.version + "."); return; }
42
43
// node translate.json CHECK ../meshcentral/views/default.handlebars
44
// node translate.json EXTRACT bob.json ../meshcentral/views/default.handlebars
@@ -50,7 +53,7 @@ function log() {
53
}
54
}
55
53
-if (NodeJSVer >= 12) {
56
+if (directRun && (NodeJSVer >= 12)) {
57
const xworker = require('worker_threads');
58
try {
59
if (xworker.isMainThread == false) {
@@ -76,12 +79,18 @@ if (NodeJSVer >= 12) {
79
} catch (ex) { log(ex); }
80
}
81
79
-var libs = ['jsdom', 'esprima', 'minify-js'];
80
-if (minifyLib == 1) { libs.push('minify-js'); }
81
-if (minifyLib == 2) { libs.push('html-minifier'); }
82
-InstallModules(libs, start);
82
+if (directRun) { setup(); }
83
+
84
+function setup() {
85
+ var libs = ['jsdom', 'esprima', 'minify-js'];
86
+ if (minifyLib == 1) { libs.push('minify-js'); }
87
+ if (minifyLib == 2) { libs.push('html-minifier'); }
88
+ InstallModules(libs, start);
89
+}
90
+
91
+function start() { startEx(process.argv); }
92
84
-function start() {
93
+function startEx(argv) {
94
// Load dependencies
95
jsdom = require('jsdom');
96
esprima = require('esprima'); // https://www.npmjs.com/package/esprima
@@ -89,10 +98,10 @@ function start() {
98
if (minifyLib == 2) { minify = require('html-minifier').minify; } // https://www.npmjs.com/package/html-minifier
99
100
var command = null;
92
- if (process.argv.length > 2) { command = process.argv[2].toLowerCase(); }
101
+ if (argv.length > 2) { command = argv[2].toLowerCase(); }
102
if (['check', 'extract', 'extractall', 'translate', 'translateall', 'minifyall', 'merge', 'totext', 'fromtext'].indexOf(command) == -1) { command = null; }
103
95
- log('MeshCentral web site translator');
104
+ if (directRun) { log('MeshCentral web site translator'); }
105
if (command == null) {
106
log('Usage "node translate.js [command] [options]');
107
log('Possible commands:');
@@ -130,7 +139,7 @@ function start() {
139
// Extract strings from web pages and display a report
140
if (command == 'check') {
141
var sources = [];
133
- for (var i = 3; i < process.argv.length; i++) { if (fs.existsSync(process.argv[i]) == false) { log('Missing file: ' + process.argv[i]); process.exit(); return; } sources.push(process.argv[i]); }
142
+ for (var i = 3; i < argv.length; i++) { if (fs.existsSync(argv[i]) == false) { log('Missing file: ' + argv[i]); process.exit(); return; } sources.push(argv[i]); }
143
if (sources.length == 0) { log('No source files specified.'); process.exit(); return; }
144
performCheck = true;
145
sourceStrings = {};
@@ -144,18 +153,18 @@ function start() {
153
154
// Extract strings from web pages
155
if (command == 'extract') {
147
- if (process.argv.length < 4) { log('No language file specified.'); process.exit(); return; }
156
+ if (argv.length < 4) { log('No language file specified.'); process.exit(); return; }
157
var sources = [];
149
- for (var i = 4; i < process.argv.length; i++) { if (fs.existsSync(process.argv[i]) == false) { log('Missing file: ' + process.argv[i]); process.exit(); return; } sources.push(process.argv[i]); }
158
+ for (var i = 4; i < argv.length; i++) { if (fs.existsSync(argv[i]) == false) { log('Missing file: ' + argv[i]); process.exit(); return; } sources.push(argv[i]); }
159
if (sources.length == 0) { log('No source files specified.'); process.exit(); return; }
151
- extract(process.argv[3], sources);
160
+ extract(argv[3], sources);
161
}
162
163
// Save a text file with all the strings for a given language
164
if (command == 'totext') {
156
- if ((process.argv.length == 6)) {
157
- if (fs.existsSync(process.argv[3]) == false) { log('Unable to find: ' + process.argv[3]); return; }
158
- totext(process.argv[3], process.argv[4], process.argv[5]);
165
+ if ((argv.length == 6)) {
166
+ if (fs.existsSync(argv[3]) == false) { log('Unable to find: ' + argv[3]); return; }
167
+ totext(argv[3], argv[4], argv[5]);
168
} else {
169
log('Usage: TOTEXT [translationfile] [textfile] [language code]');
170
}
@@ -164,10 +173,10 @@ function start() {
173
174
// Read a text file and use it as translation for a given language
175
if (command == 'fromtext') {
167
- if ((process.argv.length == 6)) {
168
- if (fs.existsSync(process.argv[3]) == false) { log('Unable to find: ' + process.argv[3]); return; }
169
- if (fs.existsSync(process.argv[4]) == false) { log('Unable to find: ' + process.argv[4]); return; }
170
- fromtext(process.argv[3], process.argv[4], process.argv[5]);
176
+ if ((argv.length == 6)) {
177
+ if (fs.existsSync(argv[3]) == false) { log('Unable to find: ' + argv[3]); return; }
178
+ if (fs.existsSync(argv[4]) == false) { log('Unable to find: ' + argv[4]); return; }
179
+ fromtext(argv[3], argv[4], argv[5]);
180
} else {
181
log('Usage: FROMTEXT [translationfile] [textfile] [language code]');
182
}
@@ -176,10 +185,10 @@ function start() {
185
186
// Merge one language from a language file into another language file.
187
if (command == 'merge') {
179
- if ((process.argv.length == 6)) {
180
- if (fs.existsSync(process.argv[3]) == false) { log('Unable to find: ' + process.argv[3]); return; }
181
- if (fs.existsSync(process.argv[4]) == false) { log('Unable to find: ' + process.argv[4]); return; }
182
- merge(process.argv[3], process.argv[4], process.argv[5]);
188
+ if ((argv.length == 6)) {
189
+ if (fs.existsSync(argv[3]) == false) { log('Unable to find: ' + argv[3]); return; }
190
+ if (fs.existsSync(argv[4]) == false) { log('Unable to find: ' + argv[4]); return; }
191
+ merge(argv[3], argv[4], argv[5]);
192
} else {
193
log('Usage: MERGE [sourcefile] [tartgetfile] [language code]');
194
}
@@ -192,12 +201,12 @@ function start() {
201
if (fs.existsSync('../views/translations') == false) { fs.mkdirSync('../views/translations'); }
202
if (fs.existsSync('../public/translations') == false) { fs.mkdirSync('../public/translations'); }
203
var lang = null;
195
- if (process.argv.length > 4) { lang = process.argv[4].toLowerCase(); }
196
- if (process.argv.length > 3) {
197
- if (fs.existsSync(process.argv[3]) == false) {
198
- log('Unable to find: ' + process.argv[3]);
204
+ if (argv.length > 4) { lang = argv[4].toLowerCase(); }
205
+ if (argv.length > 3) {
206
+ if (fs.existsSync(argv[3]) == false) {
207
+ log('Unable to find: ' + argv[3]);
208
} else {
200
- translate(lang, process.argv[3], meshCentralSourceFiles, 'translations');
209
+ translate(lang, argv[3], meshCentralSourceFiles, 'translations');
210
}
211
} else {
212
if (fs.existsSync('translate.json') == false) {
@@ -211,14 +220,14 @@ function start() {
220
221
// Translate web pages to a given language given a language file
222
if (command == 'translate') {
214
- if (process.argv.length < 4) { log("No language specified."); process.exit(); return; }
215
- if (process.argv.length < 5) { log("No language file specified."); process.exit(); return; }
216
- var lang = process.argv[3].toLowerCase();
217
- var langFile = process.argv[4];
223
+ if (argv.length < 4) { log("No language specified."); process.exit(); return; }
224
+ if (argv.length < 5) { log("No language file specified."); process.exit(); return; }
225
+ var lang = argv[3].toLowerCase();
226
+ var langFile = argv[4];
227
if (fs.existsSync(langFile) == false) { log("Missing language file: " + langFile); process.exit(); return; }
228
229
var sources = [];
221
- for (var i = 5; i < process.argv.length; i++) { if (fs.existsSync(process.argv[i]) == false) { log("Missing file: " + process.argv[i]); process.exit(); return; } sources.push(process.argv[i]); }
230
+ for (var i = 5; i < argv.length; i++) { if (fs.existsSync(argv[i]) == false) { log("Missing file: " + argv[i]); process.exit(); return; } sources.push(argv[i]); }
231
if (sources.length == 0) { log("No source files specified."); process.exit(); return; }
232
233
translate(lang, langFile, sources, false);
@@ -374,7 +383,7 @@ function merge(source, target, lang) {
383
}
384
385
function translate(lang, langFile, sources, createSubDir) {
377
- if ((NodeJSVer >= 12) && (lang == null)) {
386
+ if (directRun && (NodeJSVer >= 12) && (lang == null)) {
387
// Multi threaded translation
388
log("Multi-threaded translation.");
389
@@ -732,4 +741,7 @@ function translationsToJson(t) {
741
}
742
arr2.sort(function (a, b) { if (a.en > b.en) return 1; if (a.en < b.en) return -1; return 0; });
743
return JSON.stringify({ strings: arr2 }, null, ' ');
735
-}
\ No newline at end of file
744
+}
745
+
746
+// Export table
747
+module.exports.startEx = startEx;
\ No newline at end of file