presets_merge_labels.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Updates XML presets files using translations from Transifex
  3. */
  4. const fs = require('fs');
  5. const xml2js = require('xml2js');
  6. const Hash = require("object-hash");
  7. const PRESETS_DIR = "./public/presets";
  8. const LOCALES_DIR = "./src/config/locales/presets";
  9. const XML_RGX = /^[A-Za-z0-9_\-]+\.xml$/;
  10. const JSON_RGX = /^[A-Za-z0-9_\-]+\.json$/;
  11. // Load in-memory all translation files
  12. let locales = {};
  13. fs.readdirSync(LOCALES_DIR).forEach((file) => {
  14. if(JSON_RGX.test(file) && file !== "en.json") {
  15. try {
  16. const localeJson = JSON.parse(fs.readFileSync(LOCALES_DIR+"/"+file, 'utf8'));
  17. locales = Object.assign(locales, localeJson);
  18. }
  19. catch(e) {
  20. throw new Error("Can't parse translation file: "+file+" ("+e.message+")");
  21. }
  22. }
  23. });
  24. // Function for adding translation to given object
  25. const addTranslation = entry => {
  26. Object.entries(entry).forEach(e => {
  27. const [ k, v ] = e;
  28. if(k === "$") {
  29. Object.entries(v).forEach(ve => {
  30. const [ vk, vv ] = ve;
  31. if([ "text", "name", "display_values", "display_value"].includes(vk)) {
  32. const strhash = Hash(vv);
  33. Object.keys(locales).forEach(l => {
  34. if(locales[l][strhash] && locales[l][strhash] !== vv) {
  35. v[l+"."+vk] = locales[l][strhash];
  36. }
  37. });
  38. }
  39. });
  40. }
  41. else {
  42. addTranslation(v);
  43. }
  44. });
  45. return entry;
  46. };
  47. // Read all presets files, add translations, and rewrite them
  48. fs.readdirSync(PRESETS_DIR).forEach((file) => {
  49. if(XML_RGX.test(file)) {
  50. try {
  51. const xml = fs.readFileSync(PRESETS_DIR+"/"+file, 'utf8');
  52. // Parse XML content
  53. xml2js.parseString(xml, (err, result) => {
  54. if (err) {
  55. throw new Error("Parse error", e.message);
  56. }
  57. else {
  58. // Append translations to JS object
  59. result = addTranslation(result);
  60. // Rewrite XML file
  61. const newXml = (new xml2js.Builder({ renderOpts: { pretty: true, indent: '\t' } })).buildObject(result);
  62. fs.writeFile(PRESETS_DIR+"/"+file, newXml, function(err) {
  63. if(err) {
  64. throw new Error(err);
  65. }
  66. else {
  67. console.log("[INFO] Preset file "+file+" updated");
  68. }
  69. });
  70. }
  71. });
  72. }
  73. catch(e) {
  74. throw new Error("Can't update preset: "+file+" ("+e.message+")");
  75. }
  76. }
  77. else {
  78. console.log("[INFO] Ignored file "+file);
  79. }
  80. });