tencent_cloud_chat_uikit/scan.js

242 lines
6.5 KiB
JavaScript

const fs = require("fs");
const path = require("path");
const readline = require("readline").createInterface({
input: process.stdin,
output: process.stdout,
});
let pathList = [];
const keyMap = new Map();
const keyMapRevert = new Map();
const dirPaths = ["lib/business_logic", "lib/data_services", "lib/ui"];
const singleREP = /'([^']*[^\x00-\xff]{0,200}[^']*)'/g;
const doubleREP = /"([^"]*[^\x00-\xff]{0,200}[^"]*)"/g;
const parameterREP = /(?<=\{{)[^}]*(?=\}})/g;
const dartParameterREP = /(?<=\${)[^}]*(?=\})/g;
const extractDartParaOutREP = /\${[^}]+}/g;
const readPath = (currentDirPath) => {
fs.readdirSync(currentDirPath).forEach(function (name) {
var filePath = path.join(currentDirPath, name);
var stat = fs.statSync(filePath);
if (stat.isFile()) {
pathList.push(filePath);
} else if (stat.isDirectory()) {
readPath(filePath);
}
});
};
const detectChinese = (filePath, resolve, reject) => {
fs.readFile(filePath, "utf8", (err, data) => {
const temp = [];
if (err) {
console.error(err);
reject(err);
}
const resultSingle = data.match(singleREP);
if (Array.isArray(resultSingle) && resultSingle.length > 0) {
temp.push(...resultSingle.map((item) => item.split("'")[1]));
}
const resultDouble = data.match(doubleREP);
if (Array.isArray(resultDouble) && resultDouble.length > 0) {
temp.push(...resultDouble.map((item) => item.split('"')[1]));
}
resolve(temp);
});
};
const flatArray = (arr) => {
if (Object.prototype.toString.call(arr) != "[object Array]") {
return false;
}
let res = [];
arr.map((item) => {
if (item instanceof Array) {
res.push(...item);
} else {
res.push(item);
}
});
return res;
};
const dealWithResult = (originResult) => {
const arr = flatArray(originResult).filter((item) => item);
const noRepeatArr = Array.from(new Set(arr));
const chineseArr = noRepeatArr.filter((item) => /[\u4e00-\u9fa5]/.test(item));
const finalArr = chineseArr.filter((item) => !parameterREP.test(item));
return finalArr;
};
const hashStr = (text) => {
"use strict";
let hash = 5381,
index = text.length;
while (index) {
hash = (hash * 33) ^ text.charCodeAt(--index);
}
return hash >>> 0;
};
const hashKey = (value, context, onError) => {
const key =
"k_" + ("0000" + hashStr(value.replace(/\s+/g, "")).toString(36)).slice(-7);
const existedValue = keyMap.get(context ? `${key}_${context}` : key);
if (existedValue && existedValue !== value) {
onError &&
onError((filepath) => {
console.error("");
console.error(filepath);
console.error("Same sentence in different forms found:");
console.error(` "${existedValue}"`);
console.error(` "${value}"`);
});
} else {
keyMap.set(context ? `${key}_${context}` : key, value);
keyMapRevert.set(value, context ? `${key}_${context}` : key);
}
return key;
};
const replace = () => {
const getReplaceValue = (origin, quotation) => {
const val = origin.split(quotation == 1 ? "'" : '"')[1];
const ifReplace = val && keyMapRevert.get(val) && origin.indexOf("imt") === -1;
if(origin.indexOf("${") === -1 && ifReplace){
return ifReplace ? `ttBuild.imt("${val}")` : origin;
}else if(ifReplace){
const parameter = val.match(dartParameterREP)[0];
const template = val.replace(extractDartParaOutREP, `{{${parameter}}}`);
return parameter;
}else{
return origin;
}
};
pathList.forEach((path) => {
if (path.indexOf("i18n") > -1) {
return;
}
let data;
try {
data = fs.readFileSync(path, "utf8");
} catch (err) {
console.error(err);
return;
}
const newData = data
.replace(doubleREP, (val) => getReplaceValue(val, 2))
.replace(singleREP, (val) => getReplaceValue(val, 1));
if (newData != data) {
fs.writeFile(path, newData, (err) => {
if (err) {
console.error(err);
return;
}
});
}
});
};
dirPaths.forEach((item) => readPath(item));
pathList = Array.from(new Set(pathList));
Promise.all(
pathList.map((item) => {
return new Promise((resolve, reject) => {
return detectChinese(item, resolve, reject);
});
})
).then((res) => {
const resultArray = dealWithResult(res);
const chineseDict = {};
resultArray.forEach((item) => (chineseDict[hashKey(item)] = item));
try{
const data = fs.readFileSync('lib/i18n/i18n_utils.dart', 'utf8').split('\n');
const lineIndex = data.findIndex(item => item.indexOf("final zhJson =") > -1);
data[lineIndex] = ` final zhJson = `;
data[lineIndex + 1] = ` '''${JSON.stringify(chineseDict).replace(/\$/g, "\\$")}''';`;
// data.splice(lineIndex + 1, 0, ` '''${JSON.stringify(chineseDict).replace(/\$/g, "\\$")}''';`);
fs.writeFileSync('lib/i18n/i18n_utils.dart', data.join('\n'), 'utf8');
}catch(err){
console.log(`替换dart文件失败, ${err}`);
}
try{
// 增补英文JSON
const enDataFile = fs.readFileSync('lib/i18n/strings.i18n.json');
const enData = JSON.parse(enDataFile);
for(const item in chineseDict){
if(!enData.hasOwnProperty(item)){
enData[item] = chineseDict[item];
}
}
fs.writeFile(
"lib/i18n/strings.i18n.json",
JSON.stringify(enData),
(err) => {
if (err) {
console.error(err);
return;
}
}
);
}catch(err){
console.error(err);
}
try{
// 增补繁体中文JSON
const hantDataFile = fs.readFileSync('lib/i18n/strings_zh-Hant.i18n.json');
const hantData = JSON.parse(hantDataFile);
for(const item in chineseDict){
if(!hantData.hasOwnProperty(item)){
hantData[item] = chineseDict[item];
}
}
fs.writeFile(
"lib/i18n/strings_zh-Hant.i18n.json",
JSON.stringify(hantData),
(err) => {
if (err) {
console.error(err);
return;
}
}
);
}catch(err){
console.error(err);
}
try{
// 增补简体中文JSON
const zhDataFile = fs.readFileSync('lib/i18n/strings_zh-Hans.i18n.json');
const zhData = JSON.parse(zhDataFile);
for(const item in chineseDict){
if(!zhData.hasOwnProperty(item)){
zhData[item] = chineseDict[item];
}
}
fs.writeFile(
"lib/i18n/strings_zh-Hans.i18n.json",
JSON.stringify(zhData),
(err) => {
if (err) {
console.error(err);
return;
}
}
);
}catch(err){
console.error(err);
}
readline.close();
});