UNPKG

9.43 kBJavaScriptView Raw
1const tjs = require("translation.js-fix");
2
3// log
4const {
5 logger,
6 loggerStart,
7 loggerText,
8 oneOra,
9} = require("./config/loggerConfig.js");
10
11// get config.json
12const { getOptions } = require("./config/work-options.js");
13const configs = getOptions();
14
15let tranF = configs["from"],
16 tranT = configs["to"],
17 COM = configs["com"],
18 Force = configs["force"];
19(timeWait = configs["timewait"]),
20 (getValuesFile = configs["getvalues"]),
21 (zhSymbal = configs["zh"]),
22 (gotTranslateFile = configs["translate"]),
23 (apis = configs["apis"]);
24
25// Cache right result
26let cache = configs["cache"];
27let cacheName = configs["cacheName"];
28let diskState = configs["disk"];
29
30const { setDisk, getDisk } = require("./util/diskCache")(cacheName);
31
32// Fix china symbal
33const fixZhtoEn = require("./Fix/fixZhtoEn.js");
34// Fix result.length no equal
35const { translateLengthEquals } = require("./Fix/lengthEqual.js");
36// Fix Too Big Array to Chunk
37const { fixFileTooBig, indexMergeArr } = require("./Fix/fixFileTooBig.js");
38const {
39 tc,
40 time,
41 g,
42 y,
43 yow,
44 m,
45 b,
46 r,
47 relaPath,
48 newObject,
49 asyncWrite,
50 asyncRead,
51} = require("./util/util.js");
52const debugMsg = require("./util/debugMsg.js");
53
54const MAXstring = 1300;
55
56//
57// get translate result
58
59/**
60 * @description
61 * @param {String|String[]} value
62 * @param {String} api
63 * @returns {String[]}
64 */
65async function translateValue(value, api) {
66 let thisTranString;
67 if (value instanceof Array) {
68 thisTranString = value.join("\n");
69 } else {
70 thisTranString = value;
71 }
72 await time(timeWait);
73
74 if (tranT === "zh") tranT = "zh-CN";
75
76 let tjsOpts = {
77 text: thisTranString,
78 to: tranT,
79 com: COM,
80 };
81
82 if (tranF) {
83 tjsOpts["from"] = tranF;
84 }
85
86 return tjs[api]
87 .translate(tjsOpts)
88 .then((result) => {
89 if (!result.result) {
90 throw new Error("「结果为空」");
91 }
92
93 if (value.length == result.result.length) {
94 return result.result;
95 }
96
97 if (value.length > result.result.length) {
98 return translateValue(value.slice(result.result.length), api)
99 .then((youdao) => {
100 // tjs translate youdao BUG and tjs baidu will return undefined
101 if (youdao) {
102 if (youdao instanceof Array) {
103 youdao.forEach((x) => result.result.push(x));
104 } else {
105 result.result.push(youdao);
106 }
107 }
108 return result.result;
109 })
110 .catch((x) => {
111 if (api == "baidu") {
112 result.result = result.result.concat(
113 value.slice(result.result.length)
114 );
115 }
116 return result.result;
117 });
118 }
119
120 return result.result;
121 })
122 .catch((err) => {
123 throw err;
124 });
125}
126
127const { getTypeValue, setTypeValue } = require("./typeSetAndGet");
128
129/**
130 * @description translate AST Key == value, return new Object
131 * @param {Object} obj - remark AST
132 * @param {Object} Opts - options
133 * @param {String} Opts.api - defuault api
134 * @param {String} Opts.name - file name
135
136 * @returns {Object} - newObject
137 */
138async function setObjectKey(obj, opts) {
139 let allAPi = apis;
140 let api = opts.api;
141
142 let howManyValNoTran = 0;
143 let errMsg = "";
144
145 let tranArray = [];
146 let thisTranArray = [];
147 let resultArray = [];
148
149 let newObj = newObject(obj);
150 let tips = `${r("If slow/stagnant , should try again")}`;
151 // put obj values to tranArray
152 let sum = getTypeValue(obj, tranArray);
153 if (!sum || !tranArray.length) {
154 loggerText("no value " + sum, {
155 level: "error",
156 });
157 return "no value";
158 }
159
160 if (tranArray.length) {
161 // remove all \n
162 tranArray = tranArray.map((x) => {
163 if (x.indexOf("\n") >= 0) {
164 return x.replace(/[\n]/g, " ");
165 }
166 return x;
167 });
168 thisTranArray = tranArray;
169 tranArray = [];
170 // --values {cli options}
171 if (getValuesFile) {
172 await asyncWrite(getValuesFile, thisTranArray).then(function (ok) {
173 loggerText(`${getValuesFile} saved`);
174 });
175
176 return `you want ${g(relaPath(getValuesFile))} values save, so ${r(
177 "skip"
178 )} translate`;
179 }
180 }
181
182 if (gotTranslateFile) {
183 // custom translate file with single file
184 let tContent = await asyncRead(gotTranslateFile);
185 let relaP = relaPath(gotTranslateFile);
186 if (tContent.length === thisTranArray.length) {
187 oneOra(`you choose ${y(relaP)} be The translation`);
188 resultArray = tContent;
189 } else {
190 throw new Error(
191 `${g(relaP)} value length ${r("no equal")}\n translate-content:${y(
192 tContent.length
193 )}\n wait-translate:${y(thisTranArray.length)}`
194 );
195 }
196 } else {
197 // Fix file Too Big
198 let chunkTranArray = fixFileTooBig(thisTranArray);
199
200 for (let third in chunkTranArray) {
201 let thisChunkTran = chunkTranArray[third];
202 let thisInfo = "";
203 let isWork = true;
204 // auto change translate source
205 allAPi = allAPi.filter((x) => x != api);
206 allAPi.push(api);
207 let thisResult = [];
208
209 // get cache disk with chunk result
210 let cacheRes = getDisk(cacheName, { source: thisChunkTran.join("\n") });
211 if (cacheRes && cacheRes.result && diskState) {
212 thisResult = cacheRes.result;
213 isWork = false;
214 thisInfo = y(`result: come from Cache disk` + diskState);
215 }
216
217 if (isWork)
218 for (let i in allAPi) {
219 // Auto next api
220
221 loggerText(
222 `2. ${yow(relaPath(opts.name))} use ${g(api)} ${
223 resultArray.length
224 }/${thisTranArray.length} - ${tips}`
225 );
226
227 try {
228 if (thisChunkTran.join("").length > MAXstring) {
229 // string > 300
230
231 let thisChunkTranL_2 = Math.ceil(thisChunkTran.length / 2);
232
233 let left = indexMergeArr(thisChunkTran, 0, thisChunkTranL_2);
234 let right = indexMergeArr(
235 thisChunkTran,
236 thisChunkTranL_2,
237 thisChunkTranL_2
238 );
239
240 let t0 = await translateValue(left, api);
241 let t1 = await translateValue(right, api);
242
243 thisResult = t0.concat(t1);
244 } else {
245 thisResult = await translateValue(thisChunkTran, api);
246 } // get Result Arr
247 } catch (error) {
248 if (!error.code) {
249 loggerText(`${error.message} tjs-error, api:${y(api)}`, {
250 level: "error",
251 color: "red",
252 });
253 } else {
254 loggerText(`${error.code} ,api:${y(api)}`, {
255 level: "error",
256 color: "red",
257 });
258 }
259 thisResult = [];
260 }
261
262 // debug
263 debugMsg(1, thisChunkTran, thisResult);
264
265 // result-1 return translate value, break for allAPi
266 if (
267 thisResult.length > 0 &&
268 thisResult.length >= thisChunkTran.length
269 ) {
270 let markChunkTran = [].concat(thisChunkTran); // mark some emoji, display the split
271 if (thisChunkTran.length < thisResult.length) {
272 // Fix use Fix/lengthEqual.js in every Chunk
273 markChunkTran = translateLengthEquals(thisChunkTran, thisResult); // Fix
274 }
275
276 if (markChunkTran.length != thisResult.length) {
277 // debug only unequal
278
279 debugMsg(2, markChunkTran, thisResult);
280 }
281
282 if (thisChunkTran.length == thisResult.length) {
283 // Fix Upper/Lower case
284 for (let i in thisChunkTran) {
285 if (
286 thisChunkTran[i].trim().toLowerCase() ==
287 thisResult[i].trim().toLowerCase()
288 ) {
289 thisResult[i] = thisChunkTran[i];
290 }
291 }
292 break;
293 }
294 }
295
296 api = allAPi[i];
297 // result-2 return source value
298 if (+i + 1 == allAPi.length) {
299 // ending is no result
300
301 // count how many string no translate
302 howManyValNoTran += thisChunkTran.length;
303 isWork = false;
304 thisResult = thisChunkTran; // Add source tran
305 errMsg = `PS: can not get translation from API`;
306 }
307 }
308
309 resultArray = resultArray.concat(thisResult); // Add result
310
311 loggerText(
312 `3. translate loading - ${resultArray.length}/${thisTranArray.length} < ${thisInfo}`
313 );
314
315 if (errMsg && !Force) {
316 break;
317 } else if (!errMsg && cache && !thisInfo) {
318 // cache with cache-name
319 let cacheStruct = {
320 time: new Date().getTime(),
321 api: api,
322 f: tranF,
323 t: tranT,
324 source: thisChunkTran.join("\n"),
325 result: thisResult,
326 };
327
328 setDisk(cacheName, { source: cacheStruct.source }, cacheStruct);
329 loggerText(`3.1. ${g("cached")} the translate result`);
330 }
331 }
332 }
333
334 if (!errMsg || Force) {
335 // default: zh symbal ,。!
336 !zhSymbal && (resultArray = fixZhtoEn(resultArray));
337
338 setTypeValue(newObj, resultArray);
339 }
340
341 if (howManyValNoTran > 0) {
342 newObj.Error = `translated number: ${
343 resultArray.length - howManyValNoTran
344 }/${thisTranArray.length} ${errMsg}`;
345 }
346
347 return newObj;
348}
349
350module.exports = {
351 setObjectKey,
352 translateValue,
353};