mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
feat: async/await admin/search
This commit is contained in:
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const async = require('async');
|
|
||||||
const sanitizeHTML = require('sanitize-html');
|
const sanitizeHTML = require('sanitize-html');
|
||||||
const nconf = require('nconf');
|
const nconf = require('nconf');
|
||||||
|
const winston = require('winston');
|
||||||
|
|
||||||
const file = require('../file');
|
const file = require('../file');
|
||||||
const Translator = require('../translator').Translator;
|
const Translator = require('../translator').Translator;
|
||||||
@@ -26,14 +26,9 @@ function filterDirectories(directories) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAdminNamespaces(callback) {
|
async function getAdminNamespaces() {
|
||||||
file.walk(path.resolve(nconf.get('views_dir'), 'admin'), function (err, directories) {
|
const directories = await file.walk(path.resolve(nconf.get('views_dir'), 'admin'));
|
||||||
if (err) {
|
return filterDirectories(directories);
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, filterDirectories(directories));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitize(html) {
|
function sanitize(html) {
|
||||||
@@ -61,144 +56,89 @@ function nsToTitle(namespace) {
|
|||||||
.replace(/[^a-zA-Z> ]/g, ' ');
|
.replace(/[^a-zA-Z> ]/g, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
var fallbackCacheInProgress = {};
|
const fallbackCache = {};
|
||||||
var fallbackCache = {};
|
|
||||||
|
|
||||||
function initFallback(namespace, callback) {
|
async function initFallback(namespace) {
|
||||||
fs.readFile(path.resolve(nconf.get('views_dir'), namespace + '.tpl'), 'utf8', function (err, template) {
|
const template = await fs.promises.readFile(path.resolve(nconf.get('views_dir'), namespace + '.tpl'), 'utf8');
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var title = nsToTitle(namespace);
|
var title = nsToTitle(namespace);
|
||||||
|
var translations = sanitize(template);
|
||||||
|
translations = Translator.removePatterns(translations);
|
||||||
|
translations = simplify(translations);
|
||||||
|
translations += '\n' + title;
|
||||||
|
|
||||||
var translations = sanitize(template);
|
return {
|
||||||
translations = Translator.removePatterns(translations);
|
namespace: namespace,
|
||||||
translations = simplify(translations);
|
translations: translations,
|
||||||
translations += '\n' + title;
|
title: title,
|
||||||
|
};
|
||||||
callback(null, {
|
|
||||||
namespace: namespace,
|
|
||||||
translations: translations,
|
|
||||||
title: title,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fallback(namespace, callback) {
|
async function fallback(namespace) {
|
||||||
if (fallbackCache[namespace]) {
|
if (fallbackCache[namespace]) {
|
||||||
return callback(null, fallbackCache[namespace]);
|
return fallbackCache[namespace];
|
||||||
}
|
|
||||||
if (fallbackCacheInProgress[namespace]) {
|
|
||||||
return fallbackCacheInProgress[namespace].push(callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fallbackCacheInProgress[namespace] = [function (err, params) {
|
const params = await initFallback(namespace);
|
||||||
if (err) {
|
fallbackCache[namespace] = params;
|
||||||
return callback(err);
|
return params;
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, params);
|
|
||||||
}];
|
|
||||||
initFallback(namespace, function (err, params) {
|
|
||||||
fallbackCacheInProgress[namespace].forEach(function (fn) {
|
|
||||||
fn(err, params);
|
|
||||||
});
|
|
||||||
fallbackCacheInProgress[namespace] = null;
|
|
||||||
fallbackCache[namespace] = params;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDict(language, callback) {
|
async function initDict(language) {
|
||||||
var translator = Translator.create(language);
|
const namespaces = await getAdminNamespaces();
|
||||||
|
return await Promise.all(namespaces.map(ns => buildNamespace(language, ns)));
|
||||||
getAdminNamespaces(function (err, namespaces) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
async.map(namespaces, function (namespace, cb) {
|
|
||||||
async.waterfall([
|
|
||||||
function (next) {
|
|
||||||
translator.getTranslation(namespace).then(function (translations) {
|
|
||||||
next(null, translations);
|
|
||||||
}, next);
|
|
||||||
},
|
|
||||||
function (translations, next) {
|
|
||||||
if (!translations || !Object.keys(translations).length) {
|
|
||||||
return next(Error('No translations for ' + language + '/' + namespace));
|
|
||||||
}
|
|
||||||
|
|
||||||
// join all translations into one string separated by newlines
|
|
||||||
var str = Object.keys(translations).map(function (key) {
|
|
||||||
return translations[key];
|
|
||||||
}).join('\n');
|
|
||||||
str = sanitize(str);
|
|
||||||
|
|
||||||
var title = namespace;
|
|
||||||
if (/admin\/general\/dashboard$/.test(title)) {
|
|
||||||
title = '[[admin/menu:dashboard]]';
|
|
||||||
} else {
|
|
||||||
title = title.match(/admin\/(.+?)\/(.+?)$/);
|
|
||||||
title = '[[admin/menu:section-' +
|
|
||||||
(title[1] === 'development' ? 'advanced' : title[1]) +
|
|
||||||
']]' + (title[2] ? (' > [[admin/menu:' +
|
|
||||||
title[1] + '/' + title[2] + ']]') : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
translator.translate(title).then(function (title) {
|
|
||||||
next(null, {
|
|
||||||
namespace: namespace,
|
|
||||||
translations: str + '\n' + title,
|
|
||||||
title: title,
|
|
||||||
});
|
|
||||||
}).catch(err);
|
|
||||||
},
|
|
||||||
], function (err, params) {
|
|
||||||
if (err) {
|
|
||||||
return fallback(namespace, function (err, params) {
|
|
||||||
if (err) {
|
|
||||||
return cb(null, {
|
|
||||||
namespace: namespace,
|
|
||||||
translations: '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(null, params);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(null, params);
|
|
||||||
});
|
|
||||||
}, callback);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var cacheInProgress = {};
|
async function buildNamespace(language, namespace) {
|
||||||
var cache = {};
|
const translator = Translator.create(language);
|
||||||
|
try {
|
||||||
|
const translations = await translator.getTranslation(namespace);
|
||||||
|
if (!translations || !Object.keys(translations).length) {
|
||||||
|
return await fallback(namespace);
|
||||||
|
}
|
||||||
|
// join all translations into one string separated by newlines
|
||||||
|
let str = Object.keys(translations).map(function (key) {
|
||||||
|
return translations[key];
|
||||||
|
}).join('\n');
|
||||||
|
str = sanitize(str);
|
||||||
|
|
||||||
function getDictionary(language, callback) {
|
let title = namespace;
|
||||||
|
if (/admin\/general\/dashboard$/.test(title)) {
|
||||||
|
title = '[[admin/menu:dashboard]]';
|
||||||
|
} else {
|
||||||
|
title = title.match(/admin\/(.+?)\/(.+?)$/);
|
||||||
|
title = '[[admin/menu:section-' +
|
||||||
|
(title[1] === 'development' ? 'advanced' : title[1]) +
|
||||||
|
']]' + (title[2] ? (' > [[admin/menu:' +
|
||||||
|
title[1] + '/' + title[2] + ']]') : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
title = await translator.translate(title);
|
||||||
|
return {
|
||||||
|
namespace: namespace,
|
||||||
|
translations: str + '\n' + title,
|
||||||
|
title: title,
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
winston.error(err.stack);
|
||||||
|
return {
|
||||||
|
namespace: namespace,
|
||||||
|
translations: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cache = {};
|
||||||
|
|
||||||
|
async function getDictionary(language) {
|
||||||
|
console.log('get dictionary', language);
|
||||||
if (cache[language]) {
|
if (cache[language]) {
|
||||||
return callback(null, cache[language]);
|
return cache[language];
|
||||||
}
|
|
||||||
if (cacheInProgress[language]) {
|
|
||||||
return cacheInProgress[language].push(callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheInProgress[language] = [function (err, params) {
|
const params = await initDict(language);
|
||||||
if (err) {
|
cache[language] = params;
|
||||||
return callback(err);
|
return params;
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, params);
|
|
||||||
}];
|
|
||||||
initDict(language, function (err, params) {
|
|
||||||
cacheInProgress[language].forEach(function (fn) {
|
|
||||||
fn(err, params);
|
|
||||||
});
|
|
||||||
cacheInProgress[language] = null;
|
|
||||||
cache[language] = params;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getDictionary = getDictionary;
|
module.exports.getDictionary = getDictionary;
|
||||||
|
|||||||
Reference in New Issue
Block a user