163 lines
No EOL
6.2 KiB
JavaScript
163 lines
No EOL
6.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
'use strict';
|
|
|
|
const blankOrEmptyTranslationRegex = /^\s*"\s*"$/
|
|
|
|
if (process.argv[2]) {
|
|
var no_build = (process.argv[2].toLowerCase() == '--nobuild')
|
|
if (no_build == false) {
|
|
console.log('Incorrect arg. Please use --nobuild if you would like to download without api key.');
|
|
process.exit(1);
|
|
};
|
|
} else {
|
|
var no_build = false;
|
|
console.log('\n' +
|
|
'Please note: If you do not have the crowdin API key and would like to download the ' +
|
|
'translations without building anyways, please make sure your English files are the same ' +
|
|
'version as crowdin, and then run this script with --nobuild\n\n' +
|
|
'eg. "node crowdin_download.js --nobuild"\n\n');
|
|
};
|
|
|
|
var fs = require('fs');
|
|
var path = require('path');
|
|
var https = require('https');
|
|
var AdmZip = require('adm-zip');
|
|
|
|
var crowdin_identifier = 'bitcoincom-wallet'
|
|
|
|
try {
|
|
// obtain the crowdin api key
|
|
var crowdin_api_key = fs.readFileSync(path.join(__dirname, 'crowdin_api_key.txt'), 'utf8')
|
|
} catch (e) {
|
|
console.log('### ERROR ### You do not have the crowdin api key in ./crowdin_api_key.txt');
|
|
process.exit(1);
|
|
};
|
|
|
|
if (no_build == false) { // Reminder: Any changes to the script below must also be made to the else clause and vice versa.
|
|
|
|
// This call will tell the server to generate a new zip file for you based on most recent translations.
|
|
https.get('https://api.crowdin.com/api/project/' + crowdin_identifier + '/export?key=' + crowdin_api_key, function(res) {
|
|
|
|
console.log('Export Got response: ' + res.statusCode);
|
|
|
|
res.on('data', function(chunk) {
|
|
var resxml = chunk.toString('utf8');
|
|
console.log(resxml);
|
|
|
|
if (resxml.indexOf('status="skipped"') >= 0) {
|
|
console.log('Translation build was skipped due to either:\n' +
|
|
'1. No changes since last translation build, or\n' +
|
|
'2. API limit of once per 30 minutes has not been waited.\n\n' +
|
|
'Since we can not guarantee that translations have been built properly, this script will end here.\n' +
|
|
'Log in to Bitcoin.com Wallet\'s Crowdin Settings and click the "Build Project" button to assure it is built recently, and then run this ' +
|
|
'script again with the --nobuild arg to download translations without checking if built.');
|
|
process.exit(1);
|
|
};
|
|
|
|
downloadAllTranslationsAfterLastBuild();
|
|
});
|
|
}).on('error', function(e) {
|
|
console.log('Export Got error: ' + e.message);
|
|
});
|
|
|
|
} else { // Reminder: Any changes to the script below must also be made to the above and vice versa.
|
|
downloadAllTranslationsAfterLastBuild();
|
|
};
|
|
|
|
function downloadAllTranslationsAfterLastBuild () {
|
|
// Download most recent translations for all languages.
|
|
https.get('https://api.crowdin.com/api/project/' + crowdin_identifier + '/download/all.zip?key=' + crowdin_api_key, function(res) {
|
|
var data = [], dataLen = 0;
|
|
|
|
res.on('data', function(chunk) {
|
|
data.push(chunk);
|
|
dataLen += chunk.length;
|
|
}).on('end', function() {
|
|
var buf = new Buffer(dataLen);
|
|
for (var i=0, len = data.length, pos = 0; i < len; i++) {
|
|
data[i].copy(buf, pos);
|
|
pos += data[i].length;
|
|
};
|
|
|
|
updateLocalFilesFromDownloadedZipBuffer(buf);
|
|
});
|
|
});
|
|
}
|
|
|
|
function updateLocalFilesFromDownloadedZipBuffer(buf) {
|
|
|
|
var zip = new AdmZip(buf);
|
|
const extractionPath = path.join(__dirname, 'po')
|
|
zip.extractAllTo(extractionPath, true);
|
|
console.log('Done extracting ZIP file.');
|
|
|
|
let untranslatedPoFileDeletedCount = 0;
|
|
var files = fs.readdirSync(extractionPath);
|
|
|
|
for (var i in files) {
|
|
const name = files[i];
|
|
if (name == 'template.pot') {
|
|
continue;
|
|
}
|
|
|
|
const fullPath = path.join(extractionPath, name);
|
|
const status = fs.statSync(fullPath);
|
|
if (!status.isDirectory()) {
|
|
console.log(`Not a directory. Don't know what to do with "%{name}", skipping.`);
|
|
continue;
|
|
}
|
|
|
|
const filePath = path.join(fullPath, `template-${name}.po`);
|
|
|
|
if (name === "zh-HK") {
|
|
console.log("Deleting zh-HK, because we also have zh-CN and the app uses 2-character locales. Also zh-HK was untranslated at time of writing.");
|
|
fs.unlinkSync(filePath);
|
|
continue
|
|
}
|
|
|
|
var po_file = fs.readFileSync(filePath, 'utf8');
|
|
var po_array = po_file.split('\n');
|
|
const linesCount = po_array.length;
|
|
for (let j = 0; j < linesCount; j++) {
|
|
if (po_array[j].slice(0,5) === 'msgid') {
|
|
var source_text = po_array[j].slice(5);
|
|
} else if (po_array[j].slice(0,6) === 'msgstr') {
|
|
var translate_text = po_array[j].slice(6);
|
|
// If a line is not == English, it means there is at least one translation. Keep this entire file.
|
|
if ((!blankOrEmptyTranslationRegex.test(translate_text)) &&
|
|
source_text !== translate_text) {
|
|
console.log(`Keeping ${name}`);
|
|
// erase email addresses of last translator for privacy
|
|
po_file = po_file.replace(/ <.+@.+\..+>/, '')
|
|
fs.writeFileSync(filePath, po_file);
|
|
|
|
// split the file into 3 parts, before locale, locale, and after locale.
|
|
var lang_pos = po_file.search('"Language: ') + 11;
|
|
var po_start = po_file.slice(0,lang_pos);
|
|
var po_locale = po_file.slice(lang_pos,lang_pos + 5);
|
|
var po_end = po_file.slice(lang_pos + 5);
|
|
|
|
// check for underscore, if it's there, only take the first 2 letters and reconstruct the po file.
|
|
// TODO: Fix how this is done, because it won't work properly for
|
|
// Chinese, Traditional and Chinese, Simplified, they will clash.
|
|
if (po_locale.search('_') > 0) {
|
|
fs.writeFileSync(filePath, po_start + po_locale.slice(0,2) + po_end);
|
|
po_start = '';
|
|
po_locale = '';
|
|
po_end = '';
|
|
};
|
|
break;
|
|
};
|
|
};
|
|
if (j === (linesCount - 1)) { // All strings are exactly identical to English. Delete po file.
|
|
fs.unlinkSync(filePath);
|
|
console.log(`Deleted ${name}`)
|
|
untranslatedPoFileDeletedCount++;
|
|
};
|
|
|
|
};
|
|
};
|
|
|
|
console.log(`Completely untranslated po files cleaned out: ${untranslatedPoFileDeletedCount} (Not including zh-HK)`);
|
|
} |