From 9ea47a1962beb320cba52512cc75e958a31192be Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Tue, 28 Feb 2017 01:11:05 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B8=D0=BD=D1=82=D0=B5=D0=B3=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=81=20API=20OneSky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + scripts/i18n-onesky.js | 131 ++++++++++++++++++++++++++++++++++++ scripts/package.json | 1 + scripts/test-async-await.js | 13 ---- scripts/unescape-i18n.js | 16 ----- 5 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 scripts/i18n-onesky.js delete mode 100644 scripts/test-async-await.js delete mode 100644 scripts/unescape-i18n.js diff --git a/package.json b/package.json index 44a4967..d2063df 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "lint": "eslint ./src", "i18n:collect": "babel-node ./scripts/i18n-collect.js", "i18n:unescape": "babel-node ./scripts/unescape-i18n.js", + "i18n:pull": "babel-node --presets es2015,stage-0 ./scripts/i18n-onesky.js pull", + "i18n:publish": "babel-node --presets es2015,stage-0 ./scripts/i18n-onesky.js publish", "build": "npm run clean && npm run build:webpack -- --progress", "build:webpack": "webpack --colors -p", "build:quite": "npm run clean && npm run build:webpack -- --quite", diff --git a/scripts/i18n-onesky.js b/scripts/i18n-onesky.js new file mode 100644 index 0000000..0c96131 --- /dev/null +++ b/scripts/i18n-onesky.js @@ -0,0 +1,131 @@ +/* eslint-env node */ +/* eslint-disable no-console */ + +import onesky from 'onesky-utils'; +import fs from 'fs'; +import chalk from 'chalk'; + +const LANG_DIR = `${__dirname}/../src/i18n`; +const SOURCE_LANG = 'en'; // Базовый язык, относительно которого будут формироваться все остальные переводы +const SOURCE_FILE_NAME = 'i18n.json'; // Название файла с исходными строками внутри OneSky + +/** + * Массив локалей для соответствия каноничному виду в OneSky и нашему представлению + * о том, каким должны быть имена локалей + */ +const LOCALES_MAP = { + ru: 'ru-RU', + en: 'en-GB', +}; + +// https://ely-translates.oneskyapp.com/admin/site/settings +const defaultOptions = { + apiKey: '5MaW9TYp0S3qdJgkZ5QLgEIDeabkFDzB', + secret: 'qd075hUNpop4DItD6KOXKQnbqWPLZilf', + projectId: 201323, +}; + +/** + * Переводит из кода языка в OneSky в наше представление + * + * @param {string} code + * @return {string} + */ +function code2locale(code) { + for (const locale in LOCALES_MAP) { + if (code === LOCALES_MAP[locale]) { + return locale; + } + } + + return code; +} + +/** + * Переводит из нашего формата локалей в ожидаемое значение OneSky + * + * @param {string} locale + * @return {string} + */ +function locale2code(locale) { + return LOCALES_MAP[locale] || locale; +} + +/** + * Форматирует входящий объект с переводами в итоговую строку в том формате, в каком они + * хранятся в самом приложении + * + * @param {object} translates + * @return {string} + */ +function formatTranslates(translates) { + return JSON.stringify(sortByKeys(translates), null, 4) + '\n'; // eslint-disable-line prefer-template +} + +/** + * http://stackoverflow.com/a/29622653/5184751 + * + * @param {object} object + * @return {object} + */ +function sortByKeys(object) { + return Object.keys(object).sort().reduce((result, key) => { + result[key] = object[key]; + return result; + }, {}); +} + +async function pullReadyLanguages() { + const languages = JSON.parse(await onesky.getLanguages({...defaultOptions})); + return languages.data + .filter((elem) => elem.is_ready_to_publish) + .map((elem) => elem.custom_locale || elem.code); +} + +async function pullTranslate(language) { + const rawResponse = await onesky.getFile({...defaultOptions, language, fileName: SOURCE_FILE_NAME}); + const response = JSON.parse(rawResponse); + fs.writeFileSync(`${LANG_DIR}/${code2locale(language)}.json`, formatTranslates(response)); +} + +async function pull() { + console.log('Pulling locales list...'); + const langs = await pullReadyLanguages(); + + console.log(chalk.green('Pulled locales: ') + langs.map((lang) => code2locale(lang)).join(', ')); + + console.log('Pulling translates...'); + await Promise.all(langs.map(async (lang) => { + await pullTranslate(lang); + console.log(chalk.green('Locale ') + chalk.white.bold(code2locale(lang)) + chalk.green(' successfully pulled')); + })); +} + +async function publish() { + console.log(`Publishing ${chalk.bold(SOURCE_LANG)} translates file...`); + await onesky.postFile({ + ...defaultOptions, + format: 'HIERARCHICAL_JSON', + content: fs.readFileSync(`${LANG_DIR}/${SOURCE_LANG}.json`, 'utf8'), + keepStrings: false, + language: locale2code(SOURCE_LANG), + fileName: SOURCE_FILE_NAME, + }); + console.log('Success'); +} + +try { + const action = process.argv[2]; + switch (action) { + case 'pull': + pull(); + break; + case 'publish': + publish(); + break; + default: + throw new Error(`Unknown action ${action}`); + } +} catch (exception) { + console.error(exception); +} diff --git a/scripts/package.json b/scripts/package.json index 25bea1e..4497cfc 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -12,6 +12,7 @@ "dependencies": { "chalk": "^1.1.3", "node-babel": "^0.1.2", + "onesky-utils": "erickskrauch/nodejs-onesky-utils#locales_list", "prompt": "^1.0.0" } } diff --git a/scripts/test-async-await.js b/scripts/test-async-await.js deleted file mode 100644 index 811b012..0000000 --- a/scripts/test-async-await.js +++ /dev/null @@ -1,13 +0,0 @@ -const test = async () => { -}; - -const obj = {a: 1, b: 1}; - -const {a, b} = obj; - -console.log(a, b, 'ok'); - - -// how to: -// cd to frontend -// > ./node_modules/.bin/babel-node --presets es2015,es2017,stage-0 ./scripts/test-async-await.js diff --git a/scripts/unescape-i18n.js b/scripts/unescape-i18n.js deleted file mode 100644 index b4d9191..0000000 --- a/scripts/unescape-i18n.js +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-env node */ -/* eslint-disable no-console */ -import fs from 'fs'; -import {sync as globSync} from 'glob'; - -const LANG_DIR = `${__dirname}/../src/i18n`; - -/** - * При выгрузке из OneSky мы получаем json, в котором все не-латинские символы за-escape-ны. - * Это увеличивает вес переводов и портит дифы. Поэтому мы просто прокручиваем их json - * и на выходе получаем чистые файлы, без escape-последовательностей. - */ -globSync(`${LANG_DIR}/*.json`).forEach((filename) => { - const json = JSON.parse(fs.readFileSync(filename, 'utf8')); - fs.writeFileSync(filename, JSON.stringify(json, null, 4) + "\n"); -});