Skip to content
This repository has been archived by the owner on May 2, 2022. It is now read-only.

Sync missing translation keys in app/locales/*.json files to a Google Sheet #481

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Prev Previous commit
linted
  • Loading branch information
michaelmcmillan committed Mar 29, 2020
commit be1a7e180936f47624fd6b9374a94cc725a83c5d
54 changes: 34 additions & 20 deletions ops/lost-in-translation.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-await-in-loop, global-require */
const { parse } = require('path');
const { readdirSync } = require('fs');
const { spawnSync } = require('child_process');
Expand All @@ -19,7 +20,7 @@ const { GoogleSpreadsheet } = require('google-spreadsheet');
* Calls git cli with arguments and returns stdout.
*/
function git(...args) {
const { stdout } = spawnSync('git', args, { encoding: 'utf-8'});
const { stdout } = spawnSync('git', args, { encoding: 'utf-8' });
return stdout;
}

Expand Down Expand Up @@ -66,8 +67,12 @@ function retrieveAllLocales(directoryPath) {
*/
async function addUniqueRowsToGoogleSheet(sheet, rowsToAdd) {
const alreadyAddedRows = await sheet.getRows({ limit: 1000 });
const uniqueRowsToAdd = rowsToAdd.filter(rowToAdd =>
!alreadyAddedRows.find(alreadyAddedRow => alreadyAddedRow.key === rowToAdd.key));
const uniqueRowsToAdd = rowsToAdd.filter(
rowToAdd =>
!alreadyAddedRows.find(
alreadyAddedRow => alreadyAddedRow.key === rowToAdd.key
)
);
await sheet.addRows(uniqueRowsToAdd);
return uniqueRowsToAdd;
}
Expand All @@ -77,7 +82,7 @@ async function addUniqueRowsToGoogleSheet(sheet, rowsToAdd) {
*/
async function retrieveSheetsInDocument(doc) {
const sheets = [];
for (let sheetIndex = 0; sheetIndex < doc.sheetCount; sheetIndex++) {
for (let sheetIndex = 0; sheetIndex < doc.sheetCount; sheetIndex += 1) {
const sheet = await doc.sheetsByIndex[sheetIndex];
sheets.push(sheet);
}
Expand Down Expand Up @@ -119,61 +124,70 @@ for (const locale of allLocales) {
* If there's a missing english translation key, we know that we're most likely missing
* a translation for that locale. So what we need to do is to translate it, or get help
* to translate it.
*
* We throw it into a dictionary where the key is the locale and the value is a set of
*
* We throw it into a dictionary where the key is the locale and the value is a set of
* missing translations from english to that locale.
*/
const translationKeysByLocale = {};
for (const locale of allLocales) {
const filePath = `app/locales/${locale}.json`;
for (const commitHash of findCommitHashesForFile(filePath)) {
const translation = retrieveJSONForFileAtCommitHash(filePath, commitHash);
const translationKeys = Object.keys(translation).map(key => normalizeTranslationKey(key));
const translationKeys = Object.keys(translation).map(key =>
normalizeTranslationKey(key)
);
if (translationKeysByLocale[locale] === undefined) {
translationKeysByLocale[locale] = new Set([]);
}
translationKeysByLocale[locale] = new Set([...translationKeysByLocale[locale], ...translationKeys]);
translationKeysByLocale[locale] = new Set([
...translationKeysByLocale[locale],
...translationKeys
]);
}
}

/**
* Step 3: Add rows of missing translations to Google Spreadsheet.
michaelmcmillan marked this conversation as resolved.
Show resolved Hide resolved
*
*
* https://docs.google.com/spreadsheets/d/1ILFfc1DX4ujMnLnf9UqhwQGM9Ke3s1cAWciy8VqMHZw
*/
(async () => {
const doc = new GoogleSpreadsheet('1ILFfc1DX4ujMnLnf9UqhwQGM9Ke3s1cAWciy8VqMHZw');
await doc.useServiceAccountAuth(require('./coronastatus-translation-486cef09736e-credentials.json'));
const doc = new GoogleSpreadsheet(
'1ILFfc1DX4ujMnLnf9UqhwQGM9Ke3s1cAWciy8VqMHZw'
);
await doc.useServiceAccountAuth(
require('./coronastatus-translation-486cef09736e-credentials.json')
);
await doc.loadInfo();

const sheets = await retrieveSheetsInDocument(doc);
const allLocales = retrieveAllLocales('app/locales/');

for (const locale of allLocales) {

// Create sheet for this locale if it doesn't already exist.
let matchingSheet = sheets.find(sheet => sheet.title === locale);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, much better 👍

if (!matchingSheet) {
matchingSheet = await doc.addSheet({ title: locale, headerValues: ['key', 'translation'] });
matchingSheet = await doc.addSheet({
title: locale,
headerValues: ['key', 'translation']
});
}

// Find rows that don't already exist by looking at the key column.
const rows = [];
for (const englishTranslationKey of allEnglishTranslationKeys) {
if (!translationKeysByLocale[locale].has(englishTranslationKey)) {
const row = { 'key': englishTranslationKey, translation: '' };
const row = { key: englishTranslationKey, translation: '' };
rows.push(row);
}
}

// Add and print out how many rows we added.
const addedRows = await addUniqueRowsToGoogleSheet(matchingSheet, rows);
console.log(`Added ${addedRows.length} of ${rows.length} missing translations to the ${locale} sheet.`);
console.log(
`Added ${addedRows.length} of ${rows.length} missing translations to the ${locale} sheet.`
);

// Avoid getting rate limited by Google's API (max writes per 100 seconds).
console.log('Waiting before processing the next sheet.');
await new Promise(resolve => setTimeout(resolve, 20*1000));

await new Promise(resolve => setTimeout(resolve, 20 * 1000));
}

})();