Merge pull request #9375 from openstreetmap/transifex-v3

Upgrade Transifex API and CLI to v3
This commit is contained in:
Martin Raifer
2022-11-18 16:59:46 +01:00
committed by GitHub
13 changed files with 111 additions and 147 deletions
+3 -10
View File
@@ -20,14 +20,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install transifex-client
curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash
source ~/.bashrc
- name: Create .transifexrc
uses: DamianReeves/write-file-action@e19fd875ed54f16fc583a3486e62547ce4a5dde8
with:
@@ -35,9 +31,6 @@ jobs:
write-mode: overwrite
contents: |
[https://www.transifex.com]
api_hostname = https://api.transifex.com
hostname = https://www.transifex.com
password = ${{secrets.TX_TOKEN}}
username = api
token = ${{secrets.TX_TOKEN}}
- name: Push source strings to Transifex
run: tx push --source --no-interactive
+15 -12
View File
@@ -1,24 +1,27 @@
[main]
host = https://www.transifex.com
minimum_perc = 1
[id-editor.community]
[o:openstreetmap:p:id-editor:r:community]
file_filter = .tx/tmp/community/<lang>.yaml
source_file = .tx/tmp/community/en.yaml
source_lang = en
type = YAML
type = YAML
[id-editor.core]
[o:openstreetmap:p:id-editor:r:core]
file_filter = .tx/tmp/core/<lang>.yaml
source_file = data/core.yaml
source_lang = en
type = YAML
type = YAML
[id-editor.presets]
file_filter = .tx/tmp/presets/<lang>.yaml
source_lang = en
type = YAML
[id-editor.imagery]
[o:openstreetmap:p:id-editor:r:imagery]
file_filter = .tx/tmp/imagery/<lang>.yaml
source_file = .tx/tmp/imagery/en.yaml
source_lang = en
type = YAML
type = YAML
[o:openstreetmap:p:id-editor:r:presets]
file_filter = .tx/tmp/presets/<lang>.yaml
source_file = .tx/tmp/presets/en.yaml
source_lang = en
type = YAML
+4 -2
View File
@@ -40,12 +40,14 @@ _Breaking developer changes, which may affect downstream projects or sites that
#### :sparkles: Usability & Accessibility
#### :white_check_mark: Validation
#### :bug: Bugfixes
* Fix bug which made it impossible to change an object's preset from a sub-preset to the respective parents preset (e.g. from Driveway to Service Road) ([#9372])
* Fix bug which made it impossible to change an object's preset from a sub-preset to the respective parents preset (e.g. from Driveway to Service Road) ([#9372])
#### :hourglass: Performance
#### :rocket: Presets
#### :hammer: Development
* Upgrade to Transifex API v3 ([#9375])
[#9372]: https://github.com/openstreetmap/iD/issues/9372
[#9375]: https://github.com/openstreetmap/iD/pull/9375
# 2.23.2
@@ -185,7 +187,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
[@renancleyson-dev]: https://github.com/renancleyson-dev
[@bvercelli99]: https://github.com/bvercelli99
[@faebebin]: https://github.com/faebebin
[@bgo-eiu]: https://github.com/bgo-eiu
[@bgo-eiu]: https://github.com/bgo-eiu
# 2.21.1
+1 -1
View File
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
{"bg-BG":{}}
-1
View File
@@ -1 +0,0 @@
{"bg@Cyrl":{}}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"af":{"rtl":false,"pct":0.04},"ak":{"rtl":false,"pct":0},"am":{"rtl":false,"pct":0},"ar":{"rtl":true,"pct":0.94},"ar-AA":{"rtl":true,"pct":0.01},"as":{"rtl":false,"pct":0},"ast":{"rtl":false,"pct":0.14},"ay":{"rtl":false,"pct":0},"az":{"rtl":false,"pct":0},"ba":{"rtl":false,"pct":0},"be":{"rtl":false,"pct":0.19},"bg":{"rtl":false,"pct":0.42},"bn":{"rtl":false,"pct":0.06},"bo":{"rtl":false,"pct":0},"br":{"rtl":false,"pct":0.56},"bs":{"rtl":false,"pct":0.02},"ca":{"rtl":false,"pct":0.51},"ckb":{"rtl":true,"pct":0.04},"cs":{"rtl":false,"pct":1},"cv":{"rtl":false,"pct":0},"cy":{"rtl":false,"pct":0.02},"da":{"rtl":false,"pct":0.46},"de":{"rtl":false,"pct":1},"de-AT":{"rtl":false,"pct":0},"de-CH":{"rtl":false,"pct":0},"dv":{"rtl":true,"pct":0.01},"ee":{"rtl":false,"pct":0},"el":{"rtl":false,"pct":0.34},"en":{"rtl":false,"pct":1},"en-AU":{"rtl":false,"pct":0},"en-CA":{"rtl":false,"pct":0},"en-GB":{"rtl":false,"pct":0.22},"en-IE":{"rtl":false,"pct":0},"en-IN":{"rtl":false,"pct":0},"en-NZ":{"rtl":false,"pct":0},"en-US":{"rtl":false,"pct":1},"eo":{"rtl":false,"pct":0.69},"es":{"rtl":false,"pct":1},"et":{"rtl":false,"pct":0.18},"eu":{"rtl":false,"pct":0.05},"fa":{"rtl":true,"pct":0.56},"fa-IR":{"rtl":true,"pct":0},"ff":{"rtl":false,"pct":0},"fi":{"rtl":false,"pct":0.38},"fil":{"rtl":false,"pct":0},"fr":{"rtl":false,"pct":0.99},"fr-FR":{"rtl":false,"pct":0.09},"fy":{"rtl":false,"pct":0.01},"ga":{"rtl":false,"pct":0},"gan":{"rtl":false,"pct":0},"gl":{"rtl":false,"pct":0.56},"grt":{"rtl":false,"pct":0},"gu":{"rtl":false,"pct":0.01},"ha":{"rtl":false,"pct":0},"he":{"rtl":true,"pct":0.66},"he-IL":{"rtl":true,"pct":0},"hi":{"rtl":false,"pct":0.01},"hr":{"rtl":false,"pct":0.16},"hu":{"rtl":false,"pct":0.93},"hy":{"rtl":false,"pct":0.03},"ia":{"rtl":false,"pct":0},"id":{"rtl":false,"pct":0.07},"ig":{"rtl":false,"pct":0},"is":{"rtl":false,"pct":0.31},"it":{"rtl":false,"pct":0.59},"ja":{"rtl":false,"pct":0.99},"jam":{"rtl":false,"pct":0},"jv":{"rtl":false,"pct":0},"ka":{"rtl":false,"pct":0},"kbd":{"rtl":false,"pct":0},"kha":{"rtl":false,"pct":0},"ki":{"rtl":false,"pct":0},"kk":{"rtl":false,"pct":0},"km":{"rtl":false,"pct":0.01},"kn":{"rtl":false,"pct":0.06},"ko":{"rtl":false,"pct":0.37},"ks":{"rtl":false,"pct":0},"ku":{"rtl":false,"pct":0},"ky":{"rtl":false,"pct":0},"lb":{"rtl":false,"pct":0.17},"lg":{"rtl":false,"pct":0},"lij":{"rtl":false,"pct":0},"ln":{"rtl":false,"pct":0},"lo":{"rtl":false,"pct":0},"lt":{"rtl":false,"pct":0.14},"lus":{"rtl":false,"pct":0},"lv":{"rtl":false,"pct":0.24},"mg":{"rtl":false,"pct":0.06},"mi":{"rtl":false,"pct":0},"mk":{"rtl":false,"pct":0.37},"ml":{"rtl":false,"pct":0.01},"mn":{"rtl":false,"pct":0},"mr":{"rtl":false,"pct":0},"ms":{"rtl":false,"pct":0.12},"my":{"rtl":false,"pct":0},"nb":{"rtl":false,"pct":0},"nd":{"rtl":false,"pct":0},"ne":{"rtl":false,"pct":0.01},"nl":{"rtl":false,"pct":0.72},"nl-BE":{"rtl":false,"pct":0},"nl-NL":{"rtl":false,"pct":0},"nn":{"rtl":false,"pct":0.02},"no":{"rtl":false,"pct":0.48},"nr":{"rtl":false,"pct":0},"nso":{"rtl":false,"pct":0},"nv":{"rtl":false,"pct":0},"ny":{"rtl":false,"pct":0},"oc":{"rtl":false,"pct":0},"om":{"rtl":false,"pct":0},"or":{"rtl":false,"pct":0},"pa":{"rtl":false,"pct":0},"pa-PK":{"rtl":true,"pct":0.12},"pap":{"rtl":false,"pct":0},"pl":{"rtl":false,"pct":0.73},"ps":{"rtl":true,"pct":0},"pt":{"rtl":false,"pct":0.62},"pt-BR":{"rtl":false,"pct":0.56},"qu":{"rtl":false,"pct":0},"rm":{"rtl":false,"pct":0},"ro":{"rtl":false,"pct":0.12},"ru":{"rtl":false,"pct":0.48},"rw":{"rtl":false,"pct":0},"sat":{"rtl":false,"pct":0.03},"sc":{"rtl":false,"pct":0},"sd":{"rtl":false,"pct":0},"sg":{"rtl":false,"pct":0},"si":{"rtl":false,"pct":0.02},"sk":{"rtl":false,"pct":0.54},"sl":{"rtl":false,"pct":0.15},"sm":{"rtl":false,"pct":0},"sn":{"rtl":false,"pct":0},"so":{"rtl":false,"pct":0.01},"sq":{"rtl":false,"pct":0.07},"sr":{"rtl":false,"pct":0.36},"ss":{"rtl":false,"pct":0},"st":{"rtl":false,"pct":0},"su":{"rtl":false,"pct":0},"sv":{"rtl":false,"pct":0.9},"sw":{"rtl":false,"pct":0},"ta":{"rtl":false,"pct":0.08},"te":{"rtl":false,"pct":0.02},"tg":{"rtl":false,"pct":0},"th":{"rtl":false,"pct":0.01},"ti":{"rtl":false,"pct":0},"tk":{"rtl":false,"pct":0},"tl":{"rtl":false,"pct":0.03},"tn":{"rtl":false,"pct":0},"tr":{"rtl":false,"pct":0.66},"ts":{"rtl":false,"pct":0},"tt":{"rtl":false,"pct":0},"tum":{"rtl":false,"pct":0},"ug":{"rtl":true,"pct":0},"uk":{"rtl":false,"pct":1},"ur":{"rtl":true,"pct":0.05},"uz":{"rtl":false,"pct":0},"ve":{"rtl":false,"pct":0},"vi":{"rtl":false,"pct":0.86},"wo":{"rtl":false,"pct":0},"xh":{"rtl":false,"pct":0},"yo":{"rtl":false,"pct":0},"yue":{"rtl":false,"pct":0.1},"zh":{"rtl":false,"pct":0.02},"zh-CN":{"rtl":false,"pct":0.74},"zh-HK":{"rtl":false,"pct":0.31},"zh-TW":{"rtl":false,"pct":0.9},"zu":{"rtl":false,"pct":0}}
{"af":{"rtl":false,"pct":0.04},"ak":{"rtl":false,"pct":0},"am":{"rtl":false,"pct":0},"ar":{"rtl":true,"pct":1},"ar-AA":{"rtl":true,"pct":0.01},"as":{"rtl":false,"pct":0},"ast":{"rtl":false,"pct":0.14},"ay":{"rtl":false,"pct":0},"az":{"rtl":false,"pct":0},"ba":{"rtl":false,"pct":0},"be":{"rtl":false,"pct":0.19},"bg":{"rtl":false,"pct":0.42},"bn":{"rtl":false,"pct":0.06},"bo":{"rtl":false,"pct":0},"br":{"rtl":false,"pct":0.58},"bs":{"rtl":false,"pct":0.02},"ca":{"rtl":false,"pct":0.51},"ckb":{"rtl":true,"pct":0.04},"cs":{"rtl":false,"pct":1},"cv":{"rtl":false,"pct":0},"cy":{"rtl":false,"pct":0.02},"da":{"rtl":false,"pct":0.46},"de":{"rtl":false,"pct":1},"de-AT":{"rtl":false,"pct":0},"de-CH":{"rtl":false,"pct":0},"dv":{"rtl":true,"pct":0.01},"ee":{"rtl":false,"pct":0},"el":{"rtl":false,"pct":0.34},"en":{"rtl":false,"pct":1},"en-AU":{"rtl":false,"pct":0},"en-CA":{"rtl":false,"pct":0},"en-GB":{"rtl":false,"pct":0.22},"en-IE":{"rtl":false,"pct":0},"en-IN":{"rtl":false,"pct":0},"en-NZ":{"rtl":false,"pct":0},"en-US":{"rtl":false,"pct":1},"eo":{"rtl":false,"pct":0.69},"es":{"rtl":false,"pct":1},"et":{"rtl":false,"pct":0.18},"eu":{"rtl":false,"pct":0.05},"fa":{"rtl":true,"pct":0.56},"fa-IR":{"rtl":true,"pct":0},"ff":{"rtl":false,"pct":0},"fi":{"rtl":false,"pct":0.38},"fil":{"rtl":false,"pct":0},"fr":{"rtl":false,"pct":0.99},"fr-FR":{"rtl":false,"pct":0.09},"fy":{"rtl":false,"pct":0.01},"ga":{"rtl":false,"pct":0},"gan":{"rtl":false,"pct":0},"gl":{"rtl":false,"pct":0.56},"grt":{"rtl":false,"pct":0},"gu":{"rtl":false,"pct":0.01},"ha":{"rtl":false,"pct":0},"he":{"rtl":true,"pct":0.66},"he-IL":{"rtl":true,"pct":0},"hi":{"rtl":false,"pct":0.01},"hr":{"rtl":false,"pct":0.16},"hu":{"rtl":false,"pct":0.93},"hy":{"rtl":false,"pct":0.03},"ia":{"rtl":false,"pct":0},"id":{"rtl":false,"pct":0.07},"ig":{"rtl":false,"pct":0},"is":{"rtl":false,"pct":0.31},"it":{"rtl":false,"pct":0.59},"ja":{"rtl":false,"pct":0.99},"jam":{"rtl":false,"pct":0},"jv":{"rtl":false,"pct":0},"ka":{"rtl":false,"pct":0},"kbd":{"rtl":false,"pct":0},"kha":{"rtl":false,"pct":0},"ki":{"rtl":false,"pct":0},"kk":{"rtl":false,"pct":0},"km":{"rtl":false,"pct":0.01},"kn":{"rtl":false,"pct":0.06},"ko":{"rtl":false,"pct":0.37},"ks":{"rtl":false,"pct":0},"ku":{"rtl":false,"pct":0},"ky":{"rtl":false,"pct":0},"lb":{"rtl":false,"pct":0.17},"lg":{"rtl":false,"pct":0},"lij":{"rtl":false,"pct":0},"ln":{"rtl":false,"pct":0},"lo":{"rtl":false,"pct":0},"lt":{"rtl":false,"pct":0.14},"lus":{"rtl":false,"pct":0},"lv":{"rtl":false,"pct":0.24},"mg":{"rtl":false,"pct":0.06},"mi":{"rtl":false,"pct":0},"mk":{"rtl":false,"pct":0.37},"ml":{"rtl":false,"pct":0.01},"mn":{"rtl":false,"pct":0},"mr":{"rtl":false,"pct":0},"ms":{"rtl":false,"pct":0.12},"my":{"rtl":false,"pct":0},"nb":{"rtl":false,"pct":0},"nd":{"rtl":false,"pct":0},"ne":{"rtl":false,"pct":0.01},"nl":{"rtl":false,"pct":0.72},"nl-BE":{"rtl":false,"pct":0},"nl-NL":{"rtl":false,"pct":0},"nn":{"rtl":false,"pct":0.02},"no":{"rtl":false,"pct":0.48},"nr":{"rtl":false,"pct":0},"nso":{"rtl":false,"pct":0},"nv":{"rtl":false,"pct":0},"ny":{"rtl":false,"pct":0},"oc":{"rtl":false,"pct":0},"om":{"rtl":false,"pct":0},"or":{"rtl":false,"pct":0},"pa":{"rtl":false,"pct":0},"pa-PK":{"rtl":true,"pct":0.12},"pap":{"rtl":false,"pct":0},"pl":{"rtl":false,"pct":0.75},"ps":{"rtl":true,"pct":0},"pt":{"rtl":false,"pct":0.62},"pt-BR":{"rtl":false,"pct":0.56},"qu":{"rtl":false,"pct":0},"rm":{"rtl":false,"pct":0},"ro":{"rtl":false,"pct":0.12},"ru":{"rtl":false,"pct":0.48},"rw":{"rtl":false,"pct":0},"sat":{"rtl":false,"pct":0.03},"sc":{"rtl":false,"pct":0},"sd":{"rtl":false,"pct":0},"sg":{"rtl":false,"pct":0},"si":{"rtl":false,"pct":0.02},"sk":{"rtl":false,"pct":0.54},"sl":{"rtl":false,"pct":0.15},"sm":{"rtl":false,"pct":0},"sn":{"rtl":false,"pct":0},"so":{"rtl":false,"pct":0.01},"sq":{"rtl":false,"pct":0.07},"sr":{"rtl":false,"pct":0.36},"ss":{"rtl":false,"pct":0},"st":{"rtl":false,"pct":0},"su":{"rtl":false,"pct":0},"sv":{"rtl":false,"pct":0.9},"sw":{"rtl":false,"pct":0},"ta":{"rtl":false,"pct":0.08},"te":{"rtl":false,"pct":0.02},"tg":{"rtl":false,"pct":0},"th":{"rtl":false,"pct":0.01},"ti":{"rtl":false,"pct":0},"tk":{"rtl":false,"pct":0},"tl":{"rtl":false,"pct":0.03},"tn":{"rtl":false,"pct":0},"tr":{"rtl":false,"pct":0.66},"ts":{"rtl":false,"pct":0},"tt":{"rtl":false,"pct":0},"tum":{"rtl":false,"pct":0},"ug":{"rtl":true,"pct":0},"uk":{"rtl":false,"pct":1},"ur":{"rtl":true,"pct":0.05},"uz":{"rtl":false,"pct":0},"ve":{"rtl":false,"pct":0},"vi":{"rtl":false,"pct":0.86},"wo":{"rtl":false,"pct":0},"xh":{"rtl":false,"pct":0},"yo":{"rtl":false,"pct":0},"yue":{"rtl":false,"pct":0.1},"zh":{"rtl":false,"pct":0.02},"zh-CN":{"rtl":false,"pct":0.74},"zh-HK":{"rtl":false,"pct":0.31},"zh-TW":{"rtl":false,"pct":0.91},"zu":{"rtl":false,"pct":0}}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -76,8 +76,8 @@
"@ideditor/temaki": "~5.2.0",
"@mapbox/maki": "^8.0.0",
"@openstreetmap/id-tagging-schema": "^5.0.1",
"@transifex/api": "^4.2.5",
"autoprefixer": "^10.0.1",
"btoa": "^1.2.1",
"chai": "^4.3.4",
"chalk": "^4.1.2",
"cldr-core": "^41.0.0",
+82 -114
View File
@@ -3,45 +3,33 @@
const chalk = require('chalk');
const fs = require('fs');
const fetch = require('node-fetch');
const btoa = require('btoa');
const YAML = require('js-yaml');
const transifexApi = require('@transifex/api').transifexApi;
const resourceIds = ['core', 'imagery', 'community'];
const reviewedOnlyLangs = ['vi'];
const outdir = 'dist/locales/';
const apiroot = 'https://www.transifex.com/api/2';
const projectURL = `${apiroot}/project/id-editor`;
const languageNames = require('./language_names.js');
const transifexOrganization = 'openstreetmap';
const transifexProject = 'id-editor';
// Transifex doesn't allow anonymous downloading
let auth;
/* eslint-disable no-process-env */
if (process.env.transifex_password) {
// Deployment scripts may prefer environment variables
auth = {
user: process.env.transifex_user || 'api',
password: process.env.transifex_password
};
transifexApi.setup({ auth: process.env.transifex_password });
} else {
// Credentials can be stored in transifex.auth as a json object. This file is gitignored.
// You can use an API key instead of your password: https://docs.transifex.com/api/introduction#authentication
// in which case for user parameter value should be: "api"
// You must use an API token for authentication: You can generate one at https://www.transifex.com/user/settings/api/.
// {
// "user": "username",
// "password": "password"
// "password": "<api_key>"
// }
auth = JSON.parse(fs.readFileSync('./transifex.auth', 'utf8'));
transifexApi.setup({ auth: JSON.parse(fs.readFileSync('./transifex.auth', 'utf8')).password });
}
/* eslint-enable no-process-env */
const fetchOpts = {
headers: {
'Authorization': 'Basic ' + btoa(auth.user + ':' + auth.password),
}
};
const dataShortcuts = JSON.parse(fs.readFileSync('data/shortcuts.json', 'utf8'));
let shortcuts = [];
@@ -69,33 +57,36 @@ let coverageByLocaleCode = {};
asyncMap(resourceIds, getResourceInfo, gotResourceInfo);
asyncMap(resourceIds, getResource, gotResource);
function getResourceInfo(resourceId, callback) {
let url = 'https://api.transifex.com/organizations/openstreetmap/projects/id-editor/resources/' + resourceId;
fetch(url, fetchOpts)
.then(res => {
console.log(`${res.status}: ${url}`);
return res.json();
})
.then(json => {
callback(null, json);
})
.catch(err => callback(err));
async function getResourceInfo(resourceId, callback) {
try {
const result = [];
for await (const stat of transifexApi.ResourceLanguageStats.filter({
project: `o:${transifexOrganization}:p:${transifexProject}`,
resource: `o:${transifexOrganization}:p:${transifexProject}:r:${resourceId}`
}).all()) {
result.push(stat);
}
console.log(`got resource language stats collection for ${resourceId}`);
callback(null, result);
} catch (err) {
console.error(`error while getting resource language stats collection for ${resourceId}`);
callback(err);
}
}
function gotResourceInfo(err, results) {
if (err) return console.log(err);
results.forEach(function(info) {
for (let code in info.stats) {
let type = 'translated';
results.forEach(info => {
info.forEach(stat => {
let code = stat.relationships.language.data.id.substr(2).replace(/_/g, '-');
let type = 'translated_strings';
if (reviewedOnlyLangs.indexOf(code) !== -1) {
// reviewed_1 = reviewed, reviewed_2 = proofread
type = 'reviewed_1';
type = 'reviewed_strings';
}
let coveragePart = info.stats[code][type].percentage / results.length;
let coveragePart = (stat.attributes[type] / stat.attributes.total_strings) / results.length;
code = code.replace(/_/g, '-');
if (coverageByLocaleCode[code] === undefined) coverageByLocaleCode[code] = 0;
coverageByLocaleCode[code] += coveragePart;
}
});
});
}
@@ -135,7 +126,9 @@ function gotResource(err, results) {
fs.writeFileSync(`${outdir}${code}.min.json`, JSON.stringify(obj));
getLanguageInfo(code, (err, info) => {
let rtl = info && info.rtl;
if (err) return console.log(err);
let rtl = info && info.attributes && info.attributes.rtl;
// exceptions: see #4783
if (code === 'ckb') {
rtl = true;
@@ -145,7 +138,7 @@ function gotResource(err, results) {
let coverage = coverageByLocaleCode[code];
if (coverage === undefined) {
console.log('Could not get language coverage');
console.log(`Could not get language coverage for ${code}`, coverageByLocaleCode);
process.exit(1);
}
// we don't need high precision here, but we need to know if it's exactly 100% or not
@@ -174,11 +167,10 @@ function gotResource(err, results) {
function getResource(resourceId, callback) {
let resourceURL = `${projectURL}/resource/${resourceId}`;
getLanguages(resourceURL, (err, codes) => {
getLanguages((err, codes) => {
if (err) return callback(err);
asyncMap(codes, getLanguage(resourceURL), (err, results) => {
asyncMap(codes, getLanguage(resourceId), (err, results) => {
if (err) return callback(err);
let locale = {};
@@ -187,35 +179,7 @@ function getResource(resourceId, callback) {
locale[codes[i]] = { community: result }; // add namespace
} else {
if (resourceId === 'presets') {
// remove terms that were not really translated
let presets = (result.presets && result.presets.presets) || {};
for (const key of Object.keys(presets)) {
let preset = presets[key];
if (!preset.terms) continue;
preset.terms = preset.terms.replace(/<.*>/, '').trim();
if (!preset.terms) {
delete preset.terms;
if (!Object.keys(preset).length) {
delete presets[key];
}
}
}
} else if (resourceId === 'fields') {
// remove terms that were not really translated
let fields = (result.presets && result.presets.fields) || {};
for (const key of Object.keys(fields)) {
let field = fields[key];
if (!field.terms) continue;
field.terms = field.terms.replace(/\[.*\]/, '').trim();
if (!field.terms) {
delete field.terms;
if (!Object.keys(field).length) {
delete fields[key];
}
}
}
} else if (resourceId === 'core') {
if (resourceId === 'core') {
checkForDuplicateShortcuts(codes[i], result);
}
@@ -229,56 +193,60 @@ function getResource(resourceId, callback) {
}
function getLanguage(resourceURL) {
return (code, callback) => {
code = code.replace(/-/g, '_');
let url = `${resourceURL}/translation/${code}`;
// fetch only reviewed strings for some languages
if (reviewedOnlyLangs.indexOf(code) !== -1) {
url += '?mode=reviewed';
function getLanguage(resourceId) {
return async (code, callback) => {
try {
code = code.replace(/-/g, '_');
const url = await transifexApi.ResourceTranslationsAsyncDownload.download({
resource: {data:{type:'resources', id:`o:${transifexOrganization}:p:${transifexProject}:r:${resourceId}`}},
language: {data:{type:'languages', id:`l:${code}`}},
// fetch only reviewed strings for some languages
mode: reviewedOnlyLangs.indexOf(code) !== -1 ? 'reviewed' : 'default'
});
const data = await fetch(url).then(d => d.text());
console.log(`got translations for ${resourceId}, language ${code}`);
callback(null, YAML.load(data)[code]);
} catch (err) {
console.error(`error while getting translations for ${resourceId}, language ${code}`, err);
callback(err);
}
fetch(url, fetchOpts)
.then(res => {
console.log(`${res.status}: ${url}`);
return res.json();
})
.then(json => {
callback(null, YAML.load(json.content)[code]);
})
.catch(err => callback(err));
};
}
function getLanguageInfo(code, callback) {
async function getLanguageInfo(code, callback) {
code = code.replace(/-/g, '_');
let url = `${apiroot}/language/${code}`;
fetch(url, fetchOpts)
.then(res => {
console.log(`${res.status}: ${url}`);
return res.json();
})
.then(json => {
callback(null, json);
})
.catch(err => callback(err));
try {
const lng = await transifexApi.Language.get({
code: code
});
console.log(`got language details for ${code}`);
callback(null, lng);
} catch (err) {
console.error(`error while getting language details for ${code}`);
callback(err);
}
}
function getLanguages(resourceURL, callback) {
let url = `${resourceURL}?details`;
fetch(url, fetchOpts)
.then(res => {
console.log(`${res.status}: ${url}`);
return res.json();
})
.then(json => {
callback(null, json.available_languages
.map(d => d.code.replace(/_/g, '-'))
.filter(d => d !== 'en')
);
})
.catch(err => callback(err));
async function getLanguages(callback) {
try {
const result = [];
const project = await transifexApi.Project.get({
organization: `o:${transifexOrganization}`,
slug: transifexProject
});
const lngs = await project.fetch('languages');
for await (const lng of lngs.all()) {
if (lng.attributes.code === 'en') continue;
result.push(lng.attributes.code.replace(/_/g, '-'));
}
console.log('got project languages');
callback(null, result);
} catch (err) {
console.error('error while getting project languages');
callback(err);
}
}
@@ -293,7 +261,7 @@ function asyncMap(inputs, func, callback) {
function next() {
callFunc(index++);
if (index < inputs.length) {
setTimeout(next, 200);
setTimeout(next, 50);
}
}