Skip to content

Commit c05b28b

Browse files
author
Cori Hudson
committed
feat: use transifex v3 api to pull translations
1 parent eb25805 commit c05b28b

File tree

3 files changed

+100
-20
lines changed

3 files changed

+100
-20
lines changed

i18n/sync_tx_translations.js

+10-20
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,16 @@ if (!process.env.TX_TOKEN || process.argv.length !== 2) {
2323
const fs = require('fs');
2424
const path = require('path');
2525
const assert = require('assert');
26-
const transifex = require('transifex');
2726
const locales = require('scratch-l10n').default;
27+
const txPull = require('./transifex.js');
2828

2929
// Globals
3030
const PATH_OUTPUT = path.resolve(__dirname, '../msg');
3131
const PROJECT = 'scratch-editor'
3232
const RESOURCE = 'blocks';
33-
const MODE = {mode: 'reviewed'};
33+
const MODE = 'reviewed';
34+
3435

35-
const TX = new transifex({
36-
project_slug: PROJECT,
37-
credential: 'api:' + process.env.TX_TOKEN
38-
});
3936

4037
let en = fs.readFileSync(path.resolve(__dirname, '../msg/json/en.json'));
4138
en = JSON.parse(en);
@@ -88,20 +85,13 @@ let localeMap = {
8885
'zh-tw': 'zh_TW'
8986
};
9087

91-
function getLocaleData (locale) {
92-
let txLocale = localeMap[locale] || locale;
93-
return new Promise (function (resolve, reject) {
94-
TX.translationInstanceMethod(PROJECT, RESOURCE, txLocale, MODE, function (err, data) {
95-
if (err) {
96-
reject(err);
97-
} else {
98-
resolve({
99-
locale: locale,
100-
translations: JSON.parse(data)
101-
});
102-
}
103-
})
104-
})
88+
const getLocaleData = async function (locale) {
89+
let txLocale = localeMap[locale] || locale;
90+
const data = await txPull(PROJECT, RESOURCE, txLocale, MODE);
91+
return {
92+
locale: locale,
93+
translations: data
94+
};
10595
};
10696

10797
Promise.all(Object.keys(locales).map(getLocaleData)).then(function (values) {

i18n/transifex.js

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env babel-node
2+
3+
/**
4+
* @fileoverview
5+
* Utilities for interfacing with Transifex API 3.
6+
* TODO: add functions for pushing to Transifex
7+
*/
8+
9+
const transifexApi = require('@transifex/api').transifexApi;
10+
const download = require('download');
11+
12+
const ORG_NAME = 'llk';
13+
const SOURCE_LOCALE = 'en';
14+
15+
try {
16+
transifexApi.setup({
17+
auth: process.env.TX_TOKEN
18+
});
19+
} catch (err) {
20+
if (!process.env.TX_TOKEN) {
21+
throw new Error('TX_TOKEN is not defined.');
22+
}
23+
throw err;
24+
}
25+
26+
/**
27+
* Creates a download event for a specific project, resource, and locale.
28+
* @param {string} projectSlug - project slug (for example, "scratch-editor")
29+
* @param {string} resourceSlug - resource slug (for example, "blocks")
30+
* @param {string} localeCode - language code (for example, "ko")
31+
* @param {string} mode - translation status of strings to include
32+
* @returns {string} - id of the created download event
33+
*/
34+
const downloadResource = async function (projectSlug, resourceSlug, localeCode, mode = 'default') {
35+
const resource = {
36+
data: {
37+
id: `o:${ORG_NAME}:p:${projectSlug}:r:${resourceSlug}`,
38+
type: 'resources'
39+
}
40+
};
41+
42+
// if locale is English, create a download event of the source file
43+
if (localeCode === SOURCE_LOCALE) {
44+
return await transifexApi.ResourceStringsAsyncDownload.download({
45+
resource
46+
});
47+
}
48+
49+
const language = {
50+
data: {
51+
id: `l:${localeCode}`,
52+
type: 'languages'
53+
}
54+
};
55+
56+
// if locale is not English, create a download event of the translation file
57+
return await transifexApi.ResourceTranslationsAsyncDownload.download({
58+
mode,
59+
resource,
60+
language
61+
});
62+
};
63+
64+
/**
65+
* Pulls a translation json from transifex, for a specific project, resource, and locale.
66+
* @param {string} project - project slug (for example, "scratch-editor")
67+
* @param {string} resource - resource slug (for example, "blocks")
68+
* @param {string} locale - language code (for example, "ko")
69+
* @param {string} mode - translation status of strings to include
70+
* @returns {object} - JSON object of translated resource strings (or, of the original resourse
71+
* strings, if the local is the source language)
72+
*/
73+
const txPull = async function (project, resource, locale, mode = 'default') {
74+
const url = await downloadResource(project, resource, locale, mode);
75+
let buffer;
76+
for (let i = 0; i < 5; i++) {
77+
try {
78+
buffer = await download(url);
79+
return JSON.parse(buffer.toString());
80+
} catch (e) {
81+
process.stdout.write(`got ${e.message}, retrying after ${i + 1} failed attempt(s)\n`);
82+
}
83+
}
84+
throw Error('failed to pull after 5 retries');
85+
};
86+
87+
module.exports = txPull;
88+

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
"scratch-l10n": "3.15.20221024032103"
3232
},
3333
"devDependencies": {
34+
"@transifex/api": "4.2.5",
3435
"async": "2.6.4",
3536
"chromedriver": "105.0.1",
3637
"copy-webpack-plugin": "4.6.0",
38+
"download": "^8.0.0",
3739
"eslint": "4.19.1",
3840
"event-stream": "3.3.5",
3941
"gh-pages": "0.12.0",

0 commit comments

Comments
 (0)