automatic i18n translation using google api
This commit is contained in:
parent
ee891e0585
commit
a66e87823c
0
package-lock.json
generated
0
package-lock.json
generated
4
tools/auto-i18n/README.md
Normal file
4
tools/auto-i18n/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Run Example
|
||||||
|
node translate.js ./../../apps/red-ui/src/assets/i18n/en.json de <YOUR_API_KEY>
|
||||||
|
# API KEY
|
||||||
|
AIzaSyC2fOUHLV6nhmCSwKcacaNqumn20k8Ic_M
|
||||||
115
tools/auto-i18n/translate.js
Normal file
115
tools/auto-i18n/translate.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const moment = require('moment');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const path = require('path');
|
||||||
|
const agent = require('superagent-promise')(require('superagent'), Promise);
|
||||||
|
const { translate } = require("google-translate-api-browser");
|
||||||
|
let dicc = {};
|
||||||
|
|
||||||
|
//Lang Codes https://ctrlq.org/code/19899-google-translate-languages
|
||||||
|
|
||||||
|
if (process.argv.length >= 4) {
|
||||||
|
|
||||||
|
//Args
|
||||||
|
const inputFile = process.argv[2];
|
||||||
|
const destinationCodes = process.argv[3].split(',');
|
||||||
|
const apiKey = process.argv.length > 4 && process.argv[4];
|
||||||
|
|
||||||
|
const apiUrl = _.template('https://www.googleapis.com/language/translate/v2?key=<%= apiKey %>&q=<%= value %>&source=en&target=<%= languageKey %>');
|
||||||
|
|
||||||
|
const transformResponse = (res) => {
|
||||||
|
return _.get(JSON.parse(res.text), ['data', 'translations', 0, 'translatedText'], '');
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCache = (languageKey) => {
|
||||||
|
try {
|
||||||
|
dicc[languageKey] = {};
|
||||||
|
let fileContent = fs.readFileSync(`./translateCache-${languageKey}.txt`, 'utf-8').split('\n');
|
||||||
|
fileContent.map((line)=> {
|
||||||
|
let cached = line.split('|');
|
||||||
|
if(cached[0]) dicc[languageKey][cached[0]] = cached[1];
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const cachedIndex = (key, value, languageKey) => {
|
||||||
|
const line = key + '|' + value + '\n';
|
||||||
|
dicc[languageKey][key] = value;
|
||||||
|
fs.appendFileSync(`./translateCache-${languageKey}.txt`, line);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function iterLeaves(value, keyChain, accumulator, languageKey) {
|
||||||
|
accumulator = accumulator || {};
|
||||||
|
keyChain = keyChain || [];
|
||||||
|
if (_.isObject(value)) {
|
||||||
|
return _.chain(value).reduce((handlers, v, k) => {
|
||||||
|
return handlers.concat(iterLeaves(v, keyChain.concat(k), accumulator, languageKey));
|
||||||
|
}, []).flattenDeep().value();
|
||||||
|
} else {
|
||||||
|
if(typeof value !== 'string')
|
||||||
|
return value;
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
if(!(value in dicc[languageKey])) {
|
||||||
|
console.log(_.template('Translating <%= value %> to <%= languageKey %>')({value, languageKey}));
|
||||||
|
|
||||||
|
let prom;
|
||||||
|
//Translates individual string to language code
|
||||||
|
if(apiKey != '') {
|
||||||
|
//using apiKey
|
||||||
|
prom = agent('GET', apiUrl({
|
||||||
|
value: encodeURI(value),
|
||||||
|
languageKey,
|
||||||
|
apiKey
|
||||||
|
})).then(transformResponse)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//using free api key
|
||||||
|
prom = translate(value, { to: languageKey })
|
||||||
|
}
|
||||||
|
|
||||||
|
return prom.then((res) => cachedIndex(value, res, languageKey))
|
||||||
|
.catch((err) => console.log(err))
|
||||||
|
.then((text) => {
|
||||||
|
//Sets the value in the accumulator
|
||||||
|
_.set(accumulator, keyChain, text);
|
||||||
|
|
||||||
|
//This needs to be returned to it's eventually written to json
|
||||||
|
return accumulator;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(value + ' cached: ' + dicc[languageKey][value]);
|
||||||
|
_.set(accumulator, keyChain, dicc[languageKey][value]);
|
||||||
|
return accumulator;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.all(_.reduce(destinationCodes, (sum, languageKey) => {
|
||||||
|
const fileName = _.template('./<%= languageKey %>-<%= timeStamp %>.json')({
|
||||||
|
languageKey,
|
||||||
|
timeStamp: moment().unix()
|
||||||
|
});
|
||||||
|
|
||||||
|
//read languageKey Cache.
|
||||||
|
getCache(languageKey);
|
||||||
|
|
||||||
|
//Starts with the top level strings
|
||||||
|
return sum.concat(_.reduce(iterLeaves(JSON.parse(fs.readFileSync(path.resolve(inputFile), 'utf-8')), undefined, undefined, languageKey), (promiseChain, fn) => {
|
||||||
|
return promiseChain.then(fn);
|
||||||
|
}, Promise.resolve()).then((payload) => {
|
||||||
|
fs.writeFileSync(fileName, JSON.stringify(payload));
|
||||||
|
}).then(_.partial(console.log, 'Successfully translated all nodes, file output at ' + fileName)));
|
||||||
|
}, [])).then(() => {
|
||||||
|
process.exit();
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('You must provide an input json file and a comma-separated list of destination language codes.');
|
||||||
|
}
|
||||||
33
tools/auto-i18n/translateCache-de.txt
Normal file
33
tools/auto-i18n/translateCache-de.txt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
Confirm Action|Aktion bestätigen
|
||||||
|
This action requires confirmation, do you wish to proceed?|Diese Aktion muss bestätigt werden. Möchten Sie fortfahren?
|
||||||
|
Yes|Ja
|
||||||
|
No|Nein
|
||||||
|
Projects|Projekte
|
||||||
|
My Account|Mein Konto
|
||||||
|
Logout|Ausloggen
|
||||||
|
New Project|Neues Projekt
|
||||||
|
Edit Project|Projekt bearbeiten
|
||||||
|
Description|Beschreibung
|
||||||
|
Name|Name
|
||||||
|
Save Project|Projekt speichern
|
||||||
|
You currently have no projects. You can start your work by creating a new one!|Sie haben derzeit keine Projekte. Sie können Ihre Arbeit beginnen, indem Sie eine neue erstellen!
|
||||||
|
Download Redaction Report|Redaktionsbericht herunterladen
|
||||||
|
Sorting|Sortierung
|
||||||
|
Last Updated (Desc)|Zuletzt aktualisiert (Beschreibung)
|
||||||
|
Last Updated (Asc)|Zuletzt aktualisiert (Asc)
|
||||||
|
Name (Desc)|Name (Beschreibung)
|
||||||
|
Failed to delete file: {{filename}}|Fehler beim Löschen der Datei: {{Dateiname}}
|
||||||
|
Status: {{status}}|Status: {{status}}
|
||||||
|
Number of pages: {{numberOfPages}}|Anzahl der Seiten: {{numberOfPages}}
|
||||||
|
Analysis count: {{numberOfAnalyses}}|Anzahl der Analysen: {{numberOfAnalyses}}
|
||||||
|
Last updated: {{lastUpdated}}|Letzte Aktualisierung: {{lastUpdated}}
|
||||||
|
Project Overview|Projektübersicht
|
||||||
|
Upload Files|Daten hochladen
|
||||||
|
Requested project: {{projectId}} does not exist! <a href='/ui/projects'>Back to Project Listing. <a/>|Angefordertes Projekt: {{projectId}} existiert nicht! <a href='/ui/projects'>Zurück zur Projektliste.</a>
|
||||||
|
Failed to delete project: {{projectName}}|Projekt konnte nicht gelöscht werden: {{projectName}}
|
||||||
|
File Details|Dateidetails
|
||||||
|
Date added: {{added}}|Datum hinzugefügt: {{hinzugefügt}}
|
||||||
|
Failed to upload file: {{name}}|Datei konnte nicht hochgeladen werden: {{name}}
|
||||||
|
Language|Sprache
|
||||||
|
English|Englisch
|
||||||
|
German|Deutsche
|
||||||
Loading…
x
Reference in New Issue
Block a user