Added --translate to MeshCentral server and allow translated custom web pages to be served.
Ylian Saint-Hilaire committed
Jan 27, 2020 at 17:52 UTC
790d5be6e935dd1dc95ef2904a4eddad348e5da8
4 files changed
+86
-16
meshcentral.js
+39
-6
@@ -154,19 +154,52 @@ function CreateMeshCentralServer(config, args) {
154
155
// Perform web site translations into different languages
156
if (obj.args.translate) {
157
+ // Check NodeJS version
158
+ const NodeJSVer = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
159
+ if (NodeJSVer < 8) { console.log("Translation feature requires Node v8 or above, current version is " + process.version + "."); process.exit(); return; }
160
+
161
// Check if translate.json is in the "meshcentral-data" folder, if so use that and translate default pages.
158
- // TODO
162
+ var translationFile = null, customTranslation = false;
163
+ if (require('fs').existsSync(obj.path.join(obj.datapath, 'translate.json'))) { translationFile = obj.path.join(obj.datapath, 'translate.json'); console.log("Using translate.json in meshentral-data."); customTranslation = true; }
164
+ if (translationFile == null) { if (require('fs').existsSync(obj.path.join(__dirname, 'translate', 'translate.json'))) { translationFile = obj.path.join(__dirname, 'translate', 'translate.json'); console.log("Using default translate.json."); } }
165
+ if (translationFile == null) { console.log("Unable to find translate.json."); process.exit(); return; }
166
167
+ // Perform translation operations
168
+ var didSomething = false;
169
process.chdir('./translate');
170
var translateEngine = require('./translate/translate.js')
162
- translateEngine.startEx(['', '', 'minifyall']);
163
- translateEngine.startEx(['', '', 'translateall']);
164
- translateEngine.startEx(['', '', 'extractall']);
165
- process.exit();
171
+ if (customTranslation == true) {
172
+ // Translate all of the default files using custom translation file
173
+ translateEngine.startEx(['', '', 'minifyall']);
174
+ translateEngine.startEx(['', '', 'translateall', translationFile]);
175
+ translateEngine.startEx(['', '', 'extractall', translationFile]);
176
+ didSomething = true;
177
+ }
178
179
// Check is "meshcentral-web" exists, if so, translate all pages in that folder.
168
- // TODO
180
+ if (obj.webViewsOverridePath != null) {
181
+ didSomething = true;
182
+ var files = obj.fs.readdirSync(obj.webViewsOverridePath);
183
+ for (var i in files) {
184
+ var file = obj.path.join(obj.webViewsOverridePath, files[i]);
185
+ if (file.endsWith('.handlebars') && !file.endsWith('-min.handlebars')) {
186
+ translateEngine.startEx(['', '', 'translate', '*', translationFile, file, '--subdir:translations']);
187
+ }
188
+ }
189
+ }
190
+ if (obj.webPublicOverridePath != null) {
191
+ didSomething = true;
192
+ var files = obj.fs.readdirSync(obj.webPublicOverridePath);
193
+ for (var i in files) {
194
+ var file = obj.path.join(obj.webPublicOverridePath, files[i]);
195
+ if (file.endsWith('.htm') && !file.endsWith('-min.htm')) {
196
+ translateEngine.startEx(['', '', 'translate', '*', translationFile, file, '--subdir:translations']);
197
+ }
198
+ }
199
+ }
200
201
+ if (didSomething == false) { console.log("Nothing to do."); }
202
+ process.exit();
203
return;
204
}
205
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.4.8-a",
3
+ "version": "0.4.8-b",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
translate/translate.js
+25
-8
@@ -112,7 +112,7 @@ function startEx(argv) {
112
log(' EXTRACT [languagefile] [files]');
113
log(' Extract strings from web pages and generate a language (.json) file.');
114
log('');
115
- log(' EXTRACTALL');
115
+ log(' EXTRACTALL (languagefile)');
116
log(' Extract all MeshCentral strings from web pages and generate the languages.json file.');
117
log('');
118
log(' TRANSLATE [language] [languagefile] [files]');
@@ -196,7 +196,15 @@ function startEx(argv) {
196
}
197
198
// Extract or translate all MeshCentral strings
199
- if (command == 'extractall') { extract("translate.json", meshCentralSourceFiles); }
199
+ if (command == 'extractall') {
200
+ if (argv.length > 4) { lang = argv[4].toLowerCase(); }
201
+ var translationFile = 'translate.json';
202
+ if (argv.length > 3) {
203
+ if (fs.existsSync(argv[3]) == false) { log('Unable to find: ' + argv[3]); return; } else { translationFile = argv[3]; }
204
+ }
205
+ extract(translationFile, meshCentralSourceFiles, translationFile);
206
+ }
207
+
208
if (command == 'translateall') {
209
if (fs.existsSync('../views/translations') == false) { fs.mkdirSync('../views/translations'); }
210
if (fs.existsSync('../public/translations') == false) { fs.mkdirSync('../public/translations'); }
@@ -226,11 +234,16 @@ function startEx(argv) {
234
var langFile = argv[4];
235
if (fs.existsSync(langFile) == false) { log("Missing language file: " + langFile); process.exit(); return; }
236
229
- var sources = [];
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]); }
237
+ var sources = [], subdir = null;
238
+ for (var i = 5; i < argv.length; i++) {
239
+ if (argv[i].startsWith('--subdir:')) {
240
+ subdir = argv[i].substring(9);
241
+ } else {
242
+ if (fs.existsSync(argv[i]) == false) { log("Missing file: " + argv[i]); process.exit(); return; } sources.push(argv[i]);
243
+ }
244
+ }
245
if (sources.length == 0) { log("No source files specified."); process.exit(); return; }
232
-
233
- translate(lang, langFile, sources, false);
246
+ translate(lang, langFile, sources, subdir);
247
}
248
249
if (command == 'minifyall') {
@@ -414,7 +427,7 @@ function translateSingleThreaded(lang, langFile, sources, createSubDir) {
427
try { langFileData = JSON.parse(fs.readFileSync(langFile)); } catch (ex) { }
428
if ((langFileData == null) || (langFileData.strings == null)) { log("Invalid language file."); process.exit(); return; }
429
417
- if (lang != null) {
430
+ if ((lang != null) && (lang != '*')) {
431
// Translate a single language
432
translateEx(lang, langFileData, sources, createSubDir);
433
} else {
@@ -553,7 +566,11 @@ function translateFromHtml(lang, file, createSubDir) {
566
567
var outname = file;
568
var outnamemin = null;
556
- if (createSubDir != null) { outname = path.join(path.dirname(file), createSubDir, path.basename(file)); }
569
+ if (createSubDir != null) {
570
+ var outfolder = path.join(path.dirname(file), createSubDir);
571
+ if (fs.existsSync(outfolder) == false) { fs.mkdirSync(outfolder); }
572
+ outname = path.join(path.dirname(file), createSubDir, path.basename(file));
573
+ }
574
if (outname.endsWith('.handlebars')) {
575
outnamemin = (outname.substring(0, outname.length - 11) + '-min_' + lang + '.handlebars');
576
outname = (outname.substring(0, outname.length - 11) + '_' + lang + '.handlebars');
webserver.js
+21
-1
@@ -4332,7 +4332,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4332
4333
// Render a page using the proper language
4334
function render(req, res, filename, args) {
4335
- if ((obj.parent.webViewsOverridePath == null) && (obj.renderPages != null)) {
4335
+ if (obj.renderPages != null) {
4336
// If a user set a localization, use that
4337
if ((req.query.lang == null) && (req.session != null) && (req.session.userid)) {
4338
var user = obj.users[req.session.userid];
@@ -4375,6 +4375,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4375
4376
// Get the list of pages with different languages that can be rendered
4377
function getRenderList() {
4378
+ // Fetch default rendeing pages
4379
var translateFolder = null;
4380
if (obj.fs.existsSync('views/translations')) { translateFolder = 'views/translations'; }
4381
if (obj.fs.existsSync(obj.path.join(__dirname, 'views', 'translations'))) { translateFolder = obj.path.join(__dirname, 'views', 'translations'); }
@@ -4395,6 +4396,25 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4396
}
4397
}
4398
}
4399
+
4400
+ // See if there are any custom rending pages that will override the default ones
4401
+ if (obj.parent.webViewsOverridePath != null) {
4402
+ translateFolder = null;
4403
+ if (obj.fs.existsSync(obj.path.join(obj.parent.webViewsOverridePath, 'translations'))) { translateFolder = obj.path.join(obj.parent.webViewsOverridePath, 'translations'); }
4404
+ var files = obj.fs.readdirSync(translateFolder);
4405
+ for (var i in files) {
4406
+ var name = files[i];
4407
+ if (name.endsWith('.handlebars')) {
4408
+ name = name.substring(0, name.length - 11);
4409
+ var xname = name.split('_');
4410
+ if (xname.length == 2) {
4411
+ if (obj.renderPages[xname[0]] == null) { obj.renderPages[xname[0]] = {}; }
4412
+ obj.renderPages[xname[0]][xname[1]] = obj.path.join(translateFolder, name);
4413
+ if (obj.renderLanguages.indexOf(xname[1]) == -1) { obj.renderLanguages.push(xname[1]); }
4414
+ }
4415
+ }
4416
+ }
4417
+ }
4418
}
4419
}
4420