mirror of
https://github.com/scratchfoundation/scratch-l10n.git
synced 2025-01-03 11:25:51 -05:00
Merge pull request #176 from corihudson/ce-180-push-help-article-strings
WIP CE-180: push help article strings
This commit is contained in:
commit
d9c2a94c05
3 changed files with 55 additions and 48 deletions
|
@ -103,6 +103,35 @@ const txResources = async function (project) {
|
|||
return slugs;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} project - project slug (for example)
|
||||
* @returns {object[]} - array of resource objects
|
||||
*/
|
||||
const txResourcesObjects = async function (project) {
|
||||
const resources = await transifexApi.Resource.filter({
|
||||
project: `o:${ORG_NAME}:p:${project}`
|
||||
});
|
||||
|
||||
await resources.fetch();
|
||||
return resources.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets available languages for a project
|
||||
* @param {string} slug - project slug (for example, "scratch-editor")
|
||||
* @returns {Promise<string[]>} - list of language codes
|
||||
*/
|
||||
const txAvailableLanguages = async function (slug) {
|
||||
const project = await transifexApi.Project.get({
|
||||
organization: `o:${ORG_NAME}`,
|
||||
slug: slug
|
||||
});
|
||||
|
||||
const languages = await project.fetch('languages');
|
||||
return languages.data.map(l => l.code);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Uploads English source strings to a resource in transifex
|
||||
* @param {string} project - project slug (for example, "scratch-editor")
|
||||
|
@ -160,4 +189,4 @@ const txCreateResource = async function (project, {slug, name, i18nType, sourceS
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = {txPull, txPush, txResources, txCreateResource};
|
||||
module.exports = {txPull, txPush, txResources, txResourcesObjects, txCreateResource, txAvailableLanguages};
|
||||
|
|
|
@ -5,19 +5,14 @@
|
|||
* Helper functions for syncing Freshdesk knowledge base articles with Transifex
|
||||
*/
|
||||
|
||||
const transifex = require('transifex');
|
||||
const FreshdeskApi = require('./freshdesk-api.js');
|
||||
const util = require('util');
|
||||
const fs = require('fs');
|
||||
const fsPromises = fs.promises;
|
||||
const mkdirp = require('mkdirp');
|
||||
const {txPull, txResourcesObjects, txAvailableLanguages} = require('../lib/transifex.js');
|
||||
|
||||
const FD = new FreshdeskApi('https://mitscratch.freshdesk.com', process.env.FRESHDESK_TOKEN);
|
||||
const TX_PROJECT = 'scratch-help';
|
||||
const TX = new transifex({
|
||||
project_slug: TX_PROJECT,
|
||||
credential: 'api:' + process.env.TX_TOKEN
|
||||
});
|
||||
|
||||
const freshdeskLocale = locale => {
|
||||
// map between Transifex locale and Freshdesk. Two letter codes are usually fine
|
||||
|
@ -38,10 +33,6 @@ const freshdeskLocale = locale => {
|
|||
return localeMap[locale] || locale;
|
||||
};
|
||||
|
||||
// Promisify Transifex async/callbacks to make them easier to use`
|
||||
const getResources = util.promisify(TX.resourcesSetMethod.bind(TX));
|
||||
const getResourceInfo = util.promisify(TX.resourcesInstanceMethods.bind(TX));
|
||||
const getTranslation = util.promisify(TX.translationInstanceMethod.bind(TX));
|
||||
|
||||
/**
|
||||
* Pull metadata from Transifex for the scratch-help project
|
||||
|
@ -51,17 +42,13 @@ const getTranslation = util.promisify(TX.translationInstanceMethod.bind(TX));
|
|||
* names: array of tx resources corresponding to the Freshdesk metadata
|
||||
*/
|
||||
exports.getInputs = async () => {
|
||||
const resources = await getResources(TX_PROJECT);
|
||||
const resources = await txResourcesObjects(TX_PROJECT);
|
||||
const languages = await txAvailableLanguages(TX_PROJECT);
|
||||
// there are three types of resources differentiated by the file type
|
||||
const folders = resources.filter(resource => resource.i18n_type === 'STRUCTURED_JSON');
|
||||
const names = resources.filter(resource => resource.i18n_type === 'KEYVALUEJSON');
|
||||
// ignore the yaml type because it's not possible to update via API
|
||||
|
||||
// Lookup available languages by getting metadata for a resource, they all have the
|
||||
// same set of languages, so it doesn't matter which one you get
|
||||
const resourceInfo = await getResourceInfo(TX_PROJECT, resources[0].slug, true);
|
||||
const languages = resourceInfo.available_languages.map(l => l.code);
|
||||
|
||||
return Promise.all([languages, folders, names]); // eslint-disable-line no-undef
|
||||
};
|
||||
|
||||
|
@ -139,11 +126,9 @@ const serializeFolderSave = async (json, locale) => {
|
|||
* @return {Promise} [description]
|
||||
*/
|
||||
exports.localizeFolder = async (folder, locale) => {
|
||||
getTranslation(TX_PROJECT, folder.slug, locale, {mode: 'default'})
|
||||
txPull(TX_PROJECT, folder.slug, locale, {mode: 'default'})
|
||||
.then(data => {
|
||||
const json = JSON.parse(data);
|
||||
|
||||
serializeFolderSave(json, locale);
|
||||
serializeFolderSave(data, locale);
|
||||
})
|
||||
.catch((e) => {
|
||||
process.stdout.write(`Error processing ${folder.slug}, ${locale}: ${e.message}\n`);
|
||||
|
@ -159,12 +144,11 @@ exports.localizeFolder = async (folder, locale) => {
|
|||
*/
|
||||
exports.debugFolder = async (folder, locale) => {
|
||||
mkdirp.sync('tmpDebug');
|
||||
getTranslation(TX_PROJECT, folder.slug, locale, {mode: 'default'})
|
||||
txPull(TX_PROJECT, folder.slug, locale, {mode: 'default'})
|
||||
.then(data => {
|
||||
const json = JSON.parse(data);
|
||||
fsPromises.writeFile(
|
||||
`tmpDebug/${folder.slug}_${locale}.json`,
|
||||
JSON.stringify(json, null, 2)
|
||||
JSON.stringify(data, null, 2)
|
||||
);
|
||||
})
|
||||
.catch((e) => {
|
||||
|
@ -181,10 +165,9 @@ exports.debugFolder = async (folder, locale) => {
|
|||
* @return {Promise} [description]
|
||||
*/
|
||||
exports.localizeNames = async (resource, locale) => {
|
||||
getTranslation(TX_PROJECT, resource.slug, locale, {mode: 'default'})
|
||||
txPull(TX_PROJECT, resource.slug, locale, {mode: 'default'})
|
||||
.then(data => {
|
||||
const json = JSON.parse(data);
|
||||
serializeNameSave(json, resource, locale);
|
||||
serializeNameSave(data, resource, locale);
|
||||
})
|
||||
.catch((e) => {
|
||||
process.stdout.write(`Error saving ${resource.slug}, ${locale}: ${e.message}\n`);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const {txPush, txCreateResource} = require('../lib/transifex.js');
|
||||
|
||||
const usage = `
|
||||
Pull knowledge base articles from Freshdesk and push to scratch-help project on transifex. Usage:
|
||||
|
@ -22,15 +23,10 @@ if (!process.env.TX_TOKEN || !process.env.FRESHDESK_TOKEN || args.length > 0) {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
import transifex from 'transifex';
|
||||
import FreshdeskApi from './freshdesk-api.js';
|
||||
|
||||
const FD = new FreshdeskApi('https://mitscratch.freshdesk.com', process.env.FRESHDESK_TOKEN);
|
||||
const TX_PROJECT = 'scratch-help';
|
||||
const TX = new transifex({
|
||||
project_slug: TX_PROJECT,
|
||||
credential: 'api:' + process.env.TX_TOKEN
|
||||
});
|
||||
|
||||
const categoryNames = {};
|
||||
const folderNames = {};
|
||||
|
@ -46,33 +42,32 @@ const makeTxId = item => {
|
|||
return `${item.name.replace(/[ /]/g, '').slice(0, 30)}_${item.id}`;
|
||||
};
|
||||
|
||||
const txPushResource = (name, articles, type) => {
|
||||
const txPushResource = async (name, articles, type) => {
|
||||
const resourceData = {
|
||||
slug: name,
|
||||
name: name,
|
||||
priority: 0, // default to normal priority
|
||||
i18n_type: type,
|
||||
content: '{}'
|
||||
priority: 0, // default to normal priority
|
||||
content: articles
|
||||
};
|
||||
TX.resourceCreateMethod(TX_PROJECT, resourceData, (err) => {
|
||||
// ignore already created error report others
|
||||
if (err && err.response.statusCode !== 400) {
|
||||
|
||||
try {
|
||||
await txPush(TX_PROJECT, name, articles);
|
||||
} catch (err) {
|
||||
if (err.statusCode !== 404) {
|
||||
process.stdout.write(`Transifex Error: ${err.message}\n`);
|
||||
process.stdout.write(
|
||||
`Transifex Error ${err.response.statusCode.toString()}: ${err.response.body}\n`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
// update Transifex with English source
|
||||
TX.uploadSourceLanguageMethod(TX_PROJECT, name,
|
||||
{content: JSON.stringify(articles, null, 2)}, (err1) => {
|
||||
if (err1) {
|
||||
process.stdout.write(`Transifex Error:${err1.name}, ${err1.message}\n`);
|
||||
process.stdout.write(`Transifex Error:${err1.toString()}\n`);
|
||||
process.exitCode = 1;
|
||||
|
||||
// file not found - create it, but also give message
|
||||
process.stdout.write(`Transifex Resource not found, creating: ${name}\n`);
|
||||
if (err.statusCode === 404) {
|
||||
await txCreateResource(TX_PROJECT, resourceData);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue