Last active
August 2, 2020 21:27
-
-
Save zeel01/02d4018b09794b20b3f237f949fd959e to your computer and use it in GitHub Desktop.
FVTT Module Language Support Counter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This script can be used to generate an HTML list of modules that support localization | |
// each entry will have a list of transalations, and each translation will indicate | |
// how many strings are defined within. For translations that appear to be missing | |
// strings, a list of missing strings will be created. | |
// | |
// It is recommended that you pipe the output of this script into an HTML file to | |
// be viewed in your browser. | |
// | |
// Thanks to KaKaRoTo for his help on this | |
// You can run the following command from your modules folder: | |
// GLOB_PATTERN='' node languageCounter.js > languageCounts.html | |
const path = require("path"); | |
const fs = require("fs-extra"); // npm install fs-extra | |
const glob = require("glob"); // npm install glob | |
function globAsync(pattern, options) { | |
return new Promise((resolve, reject) => { | |
glob(pattern, options, async (err, files) => { | |
if (err) reject(err); | |
else resolve(files); | |
}); | |
}); | |
} | |
async function languageCounter() { | |
let modules; | |
try { | |
modules = await globAsync(process.env.GLOB_PATTERN || "*/module.json"); | |
} | |
catch (e) { | |
console.error(e); | |
return; | |
} | |
let supported = []; | |
for (let module of modules) { | |
try { | |
let manifest = await fs.readJSON(module); | |
manifest.ownPath = path.dirname(module); | |
if (manifest.languages && manifest.languages.length > 0) supported.push(manifest); | |
} | |
catch (e) { | |
console.error(e); | |
continue; | |
} | |
} | |
supported.sort((a, b) => a.title < b.title ? -1 : 1) | |
console.log(`<ul>`); | |
for (let module of supported) { | |
console.log(`<li> | |
<span><a href="${module.url}">${module.title}</a> - ${module.author}</span>`); | |
let languages = []; | |
let langs = module.languages; | |
for (let lang of langs) { | |
let entry = {}; | |
entry.meta = lang; | |
try { | |
entry.language = await fs.readJSON(path.resolve(module.ownPath, lang.path)); | |
let reducer = (acc, cur) => (typeof cur[1] !== "object") ? acc : acc + Object.entries(cur[1]).reduce(reducer, Object.keys(cur[1]).length) | |
entry.stringCount = Object.entries(entry.language).reduce(reducer, Object.keys(entry.language).length); | |
} | |
catch (e) { | |
console.error(e); | |
entry.language = {}; | |
entry.stringCount = -1; | |
} | |
languages.push(entry); | |
} | |
languages.sort((a, b) => { | |
if (a.stringCount > b.stringCount) return -1; | |
if (a.stringCount < b.stringCount) return 1; | |
if (a.meta.lang.toLowerCase() == "en") return -1; | |
if (b.meta.lang.toLowerCase() == "en") return 1; | |
return 0; | |
}); | |
for (let entry of languages) { | |
entry.flat = flatten(entry.language); | |
} | |
console.log(`<ul>`); | |
let first = true; | |
for (let entry of languages) { | |
console.log(`<li>${first ? "<strong>":""}${entry.meta.lang.toUpperCase()} - ${entry.meta.name}${first ? "</strong>":""}: ${entry.stringCount < 0 ? "MISSING" : entry.stringCount}`); | |
if (entry.stringCount > -1 && entry.stringCount < languages[0].stringCount){ | |
console.log(`<details><pre>`); | |
let diffs = 0; | |
Object.entries(languages[0].flat).forEach(([key, value]) => { | |
if (entry.flat[key]) return; | |
diffs++; | |
console.log(`"${key}": ${Array.isArray(value)?value.toString():value}`); | |
}); | |
console.log(`</pre><summary>Differences: ${diffs}</summary></details>`); | |
} | |
first = false; | |
console.log(`</li>`); | |
} | |
console.log(`</ul>`); | |
console.log(`</li>`); | |
} | |
console.log(`</ul>`); | |
} | |
function flatten(obj) { | |
let flat = {}; | |
Object.entries(obj).forEach(([key, value]) => { | |
if (typeof value !== "object" || Array.isArray(value)) return flat[key] = value; | |
Object.entries(flatten(value)).forEach(([k, v]) => flat[`${key}.${k}`] = v); | |
}); | |
return flat; | |
} | |
languageCounter(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment