Add scripts to convert ftl to/from Transifex JSON (#3058)
This commit is contained in:
parent
d5a584c28b
commit
afaf0b4968
6 changed files with 178 additions and 5 deletions
|
@ -55,8 +55,7 @@ file-interface-items-were-relinked = { $numRelinked ->
|
||||||
*[other] { $numRelinked } items were relinked
|
*[other] { $numRelinked } items were relinked
|
||||||
}
|
}
|
||||||
|
|
||||||
import-mendeley-encrypted = The selected Mendeley database cannot be read, likely because it is encrypted.
|
import-mendeley-encrypted = The selected Mendeley database cannot be read, likely because it is encrypted. See <a data-l10n-name="mendeley-import-kb">How do I import a Mendeley library into Zotero?</a> for more information.
|
||||||
See <a data-l10n-name="mendeley-import-kb">How do I import a Mendeley library into Zotero?</a> for more information.
|
|
||||||
|
|
||||||
file-interface-import-error-translator = An error occurred importing the selected file with “{ $translator }”. Please ensure that the file is valid and try again.
|
file-interface-import-error-translator = An error occurred importing the selected file with “{ $translator }”. Please ensure that the file is valid and try again.
|
||||||
|
|
||||||
|
|
38
js-build/ftl-to-json.mjs
Normal file
38
js-build/ftl-to-json.mjs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { ftlToJSON } from "ftl-tx";
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import { dirname, join } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { onError, onSuccess } from './utils.js';
|
||||||
|
|
||||||
|
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||||
|
const JSONDir = join(ROOT, 'tmp', 'tx');
|
||||||
|
|
||||||
|
async function getJSON() {
|
||||||
|
const t1 = performance.now();
|
||||||
|
await fs.mkdirp(JSONDir);
|
||||||
|
const sourcefile = join(ROOT, 'chrome', 'locale', 'en-US', 'zotero', 'zotero.ftl');
|
||||||
|
const destFile = join(JSONDir, 'zotero_en_US.json');
|
||||||
|
const ftl = await fs.readFile(sourcefile, 'utf8');
|
||||||
|
const json = ftlToJSON(ftl, { transformTerms: false, storeTermsInJSON: false });
|
||||||
|
await fs.outputJSON(destFile, json);
|
||||||
|
const t2 = performance.now();
|
||||||
|
return ({
|
||||||
|
action: 'ftl->json',
|
||||||
|
count: 1,
|
||||||
|
totalCount: 1,
|
||||||
|
processingTime: t2 - t1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
onSuccess(await getJSON());
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
process.exitCode = 1;
|
||||||
|
global.isError = true;
|
||||||
|
onError(err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
98
js-build/localize-ftl.mjs
Normal file
98
js-build/localize-ftl.mjs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
import { extractTerms, ftlToJSON, JSONToFtl } from 'ftl-tx';
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import { dirname, join } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { onError, onProgress, onSuccess } from './utils.js';
|
||||||
|
import { exit } from 'process';
|
||||||
|
|
||||||
|
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||||
|
const JSONDir = join(ROOT, 'tmp', 'tx');
|
||||||
|
const localesDir = join(ROOT, 'chrome', 'locale');
|
||||||
|
const sourceDir = join(localesDir, 'en-US', 'zotero');
|
||||||
|
|
||||||
|
const termsSourceFTLPath = join(ROOT, 'app', 'assets', 'branding', 'locale', 'brand.ftl');
|
||||||
|
const fallbackJSONPath = join(sourceDir, 'zotero.json');
|
||||||
|
|
||||||
|
// don't override source zotero.ftl
|
||||||
|
const localeToSkip = ['en-US'];
|
||||||
|
|
||||||
|
async function getFTL() {
|
||||||
|
const t1 = performance.now();
|
||||||
|
if (!(await fs.pathExists(fallbackJSONPath))) {
|
||||||
|
console.error(`File ${fallbackJSONPath} does not exist, please run 'ftl-to-json' first`);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await fs.pathExists(termsSourceFTLPath))) {
|
||||||
|
console.error(`Required file ${termsSourceFTLPath} does not exist`);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fallbackJSON = await fs.readJSON(fallbackJSONPath);
|
||||||
|
const terms = extractTerms(await fs.readFile(termsSourceFTLPath, 'utf-8'));
|
||||||
|
|
||||||
|
const expectedLocale = (await fs.readdir(localeDir, { withFileTypes: true }))
|
||||||
|
.filter(dirent => dirent.isDirectory())
|
||||||
|
.map(dirent => dirent.name);
|
||||||
|
|
||||||
|
const totalCount = expectedLocale.length;
|
||||||
|
let locale;
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
while ((locale = expectedLocale.pop())) {
|
||||||
|
if (localeToSkip.includes(locale)) {
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ftlFilePath = join(ROOT, 'chrome', 'locale', locale, 'zotero', 'zotero.ftl');
|
||||||
|
let JSONFromLocalFTL = {};
|
||||||
|
try {
|
||||||
|
const ftl = await fs.readFile(ftlFilePath, 'utf8');
|
||||||
|
JSONFromLocalFTL = ftlToJSON(ftl, { transformTerms: false, storeTermsInJSON: false });
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// no local .ftl file
|
||||||
|
}
|
||||||
|
|
||||||
|
const JSONFilePath = join(JSONDir, `zotero_${locale.replace('-', '_')}.json`);
|
||||||
|
let JSONFromTransifex = {};
|
||||||
|
try {
|
||||||
|
const json = await fs.readJSON(JSONFilePath);
|
||||||
|
JSONFromTransifex = json;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// no .json file from transifex
|
||||||
|
}
|
||||||
|
|
||||||
|
const mergedJSON = { ...fallbackJSON, ...JSONFromLocalFTL, ...JSONFromTransifex };
|
||||||
|
const ftl = JSONToFtl(mergedJSON, { addTermsToFTL: false, storeTermsInJSON: false, transformTerms: false, terms });
|
||||||
|
|
||||||
|
const outFtlPath = join(ROOT, 'chrome', 'locale', locale, 'zotero', 'zotero.ftl');
|
||||||
|
await fs.outputFile(outFtlPath, ftl);
|
||||||
|
onProgress(outFtlPath, outFtlPath, 'ftl');
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const t2 = performance.now();
|
||||||
|
return ({
|
||||||
|
action: 'ftl',
|
||||||
|
count,
|
||||||
|
totalCount,
|
||||||
|
processingTime: t2 - t1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
onSuccess(await getFTL());
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
process.exitCode = 1;
|
||||||
|
global.isError = true;
|
||||||
|
onError(err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
|
@ -21,7 +21,7 @@ function onSuccess(result) {
|
||||||
msg += ` | ${result.totalCount} checked`;
|
msg += ` | ${result.totalCount} checked`;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += ` [${yellow(`${result.processingTime}ms`)}]`;
|
msg += ` [${yellow(`${result.processingTime.toFixed(2)}ms`)}]`;
|
||||||
|
|
||||||
console.log(msg);
|
console.log(msg);
|
||||||
}
|
}
|
||||||
|
|
39
package-lock.json
generated
39
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "zotero",
|
"name": "zotero",
|
||||||
"version": "5.0.0",
|
"version": "7.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "zotero",
|
"name": "zotero",
|
||||||
"version": "5.0.0",
|
"version": "7.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@citeproc-rs/wasm": "^0.2.0",
|
"@citeproc-rs/wasm": "^0.2.0",
|
||||||
"ace-builds": "^1.4.12",
|
"ace-builds": "^1.4.12",
|
||||||
|
@ -40,6 +40,7 @@
|
||||||
"eslint-plugin-react": "^7.28.0",
|
"eslint-plugin-react": "^7.28.0",
|
||||||
"eslint-plugin-react-hooks": "^4.0.4",
|
"eslint-plugin-react-hooks": "^4.0.4",
|
||||||
"fs-extra": "^3.0.1",
|
"fs-extra": "^3.0.1",
|
||||||
|
"ftl-tx": "^0.6.0",
|
||||||
"globby": "^6.1.0",
|
"globby": "^6.1.0",
|
||||||
"jspath": "^0.4.0",
|
"jspath": "^0.4.0",
|
||||||
"mocha": "^3.5.3",
|
"mocha": "^3.5.3",
|
||||||
|
@ -919,6 +920,16 @@
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@fluent/syntax": {
|
||||||
|
"version": "0.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fluent/syntax/-/syntax-0.19.0.tgz",
|
||||||
|
"integrity": "sha512-5D2qVpZrgpjtqU4eNOcWGp1gnUCgjfM+vKGE2y03kKN6z5EBhtx0qdRFbg8QuNNj8wXNoX93KJoYb+NqoxswmQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0",
|
||||||
|
"npm": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@formatjs/intl-displaynames": {
|
"node_modules/@formatjs/intl-displaynames": {
|
||||||
"version": "1.2.10",
|
"version": "1.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-1.2.10.tgz",
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-1.2.10.tgz",
|
||||||
|
@ -3561,6 +3572,15 @@
|
||||||
"node": ">= 4.0"
|
"node": ">= 4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ftl-tx": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ftl-tx/-/ftl-tx-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-w7s0p6RNsaUKpiuQZ5Q0KIyiX2JIDItqI4qRKt49u0aMqdGp0gDc5G5Qnubgu6l2ww5PDt4wsyL7A1iZo1VGMQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@fluent/syntax": "^0.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
|
@ -7533,6 +7553,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@fluent/syntax": {
|
||||||
|
"version": "0.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fluent/syntax/-/syntax-0.19.0.tgz",
|
||||||
|
"integrity": "sha512-5D2qVpZrgpjtqU4eNOcWGp1gnUCgjfM+vKGE2y03kKN6z5EBhtx0qdRFbg8QuNNj8wXNoX93KJoYb+NqoxswmQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@formatjs/intl-displaynames": {
|
"@formatjs/intl-displaynames": {
|
||||||
"version": "1.2.10",
|
"version": "1.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-1.2.10.tgz",
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-1.2.10.tgz",
|
||||||
|
@ -9769,6 +9795,15 @@
|
||||||
"nan": "^2.12.1"
|
"nan": "^2.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ftl-tx": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ftl-tx/-/ftl-tx-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-w7s0p6RNsaUKpiuQZ5Q0KIyiX2JIDItqI4qRKt49u0aMqdGp0gDc5G5Qnubgu6l2ww5PDt4wsyL7A1iZo1VGMQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@fluent/syntax": "^0.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
"sass": "node ./js-build/sass.js",
|
"sass": "node ./js-build/sass.js",
|
||||||
"js": "node ./js-build/js.js",
|
"js": "node ./js-build/js.js",
|
||||||
"clean": "node ./js-build/clean.js",
|
"clean": "node ./js-build/clean.js",
|
||||||
|
"ftl-to-json": "node ./js-build/ftl-to-json.mjs",
|
||||||
|
"localize-ftl": "node ./js-build/localize-ftl.mjs",
|
||||||
"clean-build": "node ./js-build/clean.js && node ./js-build/build.js",
|
"clean-build": "node ./js-build/clean.js && node ./js-build/build.js",
|
||||||
"clean-start": "node ./js-build/clean.js && node ./js-build/build.js && node ./js-build/watch.js"
|
"clean-start": "node ./js-build/clean.js && node ./js-build/build.js && node ./js-build/watch.js"
|
||||||
},
|
},
|
||||||
|
@ -47,6 +49,7 @@
|
||||||
"eslint-plugin-react": "^7.28.0",
|
"eslint-plugin-react": "^7.28.0",
|
||||||
"eslint-plugin-react-hooks": "^4.0.4",
|
"eslint-plugin-react-hooks": "^4.0.4",
|
||||||
"fs-extra": "^3.0.1",
|
"fs-extra": "^3.0.1",
|
||||||
|
"ftl-tx": "^0.6.0",
|
||||||
"globby": "^6.1.0",
|
"globby": "^6.1.0",
|
||||||
"jspath": "^0.4.0",
|
"jspath": "^0.4.0",
|
||||||
"mocha": "^3.5.3",
|
"mocha": "^3.5.3",
|
||||||
|
|
Loading…
Reference in a new issue