UI gradient intensity slider, update wgui Defaults for dashboard, prepend ui-related config entries with ui_
This commit is contained in:
@@ -9,187 +9,181 @@ const template_name = process.env["TEMPLATE"] as string;
|
||||
let lang_path = process.env["LANG_PATH"] as string;
|
||||
|
||||
if (model_name === undefined) {
|
||||
console.log("MODEL not set");
|
||||
exit(-1);
|
||||
console.log("MODEL not set");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (template_name === undefined) {
|
||||
console.log("TEMPLATE not set");
|
||||
exit(-1);
|
||||
console.log("TEMPLATE not set");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (lang_path === undefined) {
|
||||
console.log(
|
||||
`LANG_PATH is not set.
|
||||
console.log(
|
||||
`LANG_PATH is not set.
|
||||
Try one of these:
|
||||
LANG_PATH=../../uidev/assets/lang/ ./run.sh
|
||||
LANG_PATH=../../dash-frontend/assets/lang/ ./run.sh
|
||||
LANG_PATH=../../wayvr/src/assets/lang/ ./run.sh`);
|
||||
exit(-1);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
lang_path = path.resolve(__dirname + "/" + lang_path);
|
||||
if (lang_path === undefined || !fs.existsSync(lang_path)) {
|
||||
console.log("Invalid or non-existent LANG_PATH");
|
||||
exit(-1);
|
||||
console.log("Invalid or non-existent LANG_PATH");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
const current_path = path.resolve(__dirname);
|
||||
const templates_path = path.resolve(__dirname + "/templates");
|
||||
|
||||
async function loop_object(obj: any, initial_str: string, callback: (key: string, value: string) => Promise<void>) {
|
||||
for (var key in obj) {
|
||||
let full_key = initial_str + key;
|
||||
if (typeof obj[key] === "object" && obj[key] !== null) {
|
||||
await loop_object(obj[key], full_key + ".", callback)
|
||||
} else if (obj.hasOwnProperty(key)) {
|
||||
await callback(full_key, obj[key])
|
||||
}
|
||||
}
|
||||
for (var key in obj) {
|
||||
let full_key = initial_str + key;
|
||||
if (typeof obj[key] === "object" && obj[key] !== null) {
|
||||
await loop_object(obj[key], full_key + ".", callback)
|
||||
} else if (obj.hasOwnProperty(key)) {
|
||||
await callback(full_key, obj[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extract_backticks(str: string) {
|
||||
const regex = /`([^`]+)`/g;
|
||||
return str.match(regex)?.map(match => match.slice(1, -1).trim());
|
||||
const regex = /`([^`]+)`/g;
|
||||
return str.match(regex)?.map(match => match.slice(1, -1).trim());
|
||||
}
|
||||
|
||||
function set_i18n_key(obj: any, key: string, value: string | undefined) {
|
||||
const parts = key.split('.');
|
||||
let cur_level = obj;
|
||||
for (let i = 0; i < parts.length - 1; i++) {
|
||||
const part = parts[i]!;
|
||||
if (!cur_level[part]) {
|
||||
cur_level[part] = {};
|
||||
}
|
||||
cur_level = cur_level[part];
|
||||
}
|
||||
cur_level[parts[parts.length - 1]!] = value;
|
||||
const parts = key.split('.');
|
||||
let cur_level = obj;
|
||||
for (let i = 0; i < parts.length - 1; i++) {
|
||||
const part = parts[i]!;
|
||||
if (!cur_level[part]) {
|
||||
cur_level[part] = {};
|
||||
}
|
||||
cur_level = cur_level[part];
|
||||
}
|
||||
cur_level[parts[parts.length - 1]!] = value;
|
||||
}
|
||||
|
||||
function key_exists(obj: any, key: string) {
|
||||
const parts = key.split('.');
|
||||
let level = obj;
|
||||
const parts = key.split('.');
|
||||
let level = obj;
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i]!;
|
||||
if (!level || !level[part]) {
|
||||
return false;
|
||||
}
|
||||
level = level[part];
|
||||
}
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i]!;
|
||||
if (!level || !level[part]) {
|
||||
return false;
|
||||
}
|
||||
level = level[part];
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
};
|
||||
|
||||
interface Example {
|
||||
key: string;
|
||||
en: string;
|
||||
translated: string;
|
||||
key: string;
|
||||
en: string;
|
||||
translated: string;
|
||||
}
|
||||
|
||||
interface Template {
|
||||
full_name: string; // "Polish"
|
||||
examples: Example[]
|
||||
full_name: string; // "Polish"
|
||||
examples: Example[]
|
||||
}
|
||||
|
||||
function gen_prompt(description: string, template: Template, key: string, english_translation: string) {
|
||||
let num = 1;
|
||||
for (const example of template.examples) {
|
||||
description += "\nExample " + num + ":\n\n";
|
||||
description += "Translate key `" + example.key + "` from English to " + template.full_name + ":\n\n";
|
||||
description += "```\n";
|
||||
description += example.en + "\n";
|
||||
description += "```\n\n";
|
||||
description += "Result:\n\n";
|
||||
description += "```\n";
|
||||
description += example.translated + "\n";
|
||||
description += "```\n";
|
||||
num += 1;
|
||||
}
|
||||
description += "\nEnd of examples.\n\n";
|
||||
description += "Translate key `" + key + "` from English to " + template.full_name + ":\n\n";
|
||||
description += "```\n";
|
||||
description += english_translation + "\n";
|
||||
description += "```\n";
|
||||
return description;
|
||||
let num = 1;
|
||||
for (const example of template.examples) {
|
||||
description += "\nExample " + num + ":\n\n";
|
||||
description += "Translate key `" + example.key + "` from English to " + template.full_name + ":\n\n";
|
||||
description += "```\n";
|
||||
description += example.en + "\n";
|
||||
description += "```\n\n";
|
||||
description += "Result:\n\n";
|
||||
description += "```\n";
|
||||
description += example.translated + "\n";
|
||||
description += "```\n";
|
||||
num += 1;
|
||||
}
|
||||
description += "\nEnd of examples.\n\n";
|
||||
description += "Translate key `" + key + "` from English to " + template.full_name + ":\n\n";
|
||||
description += "```\n";
|
||||
description += english_translation + "\n";
|
||||
description += "```\n";
|
||||
return description;
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const template = JSON.parse(await fsp.readFile(templates_path + "/" + template_name + ".json", "utf-8")) as Template;
|
||||
const template = JSON.parse(await fsp.readFile(templates_path + "/" + template_name + ".json", "utf-8")) as Template;
|
||||
|
||||
let description_txt = await fsp.readFile(current_path + "/description.txt", "utf-8");
|
||||
description_txt = description_txt.replaceAll("{TARGET_LANG}", template.full_name);
|
||||
let description_txt = await fsp.readFile(current_path + "/description.txt", "utf-8");
|
||||
description_txt = description_txt.replaceAll("{TARGET_LANG}", template.full_name);
|
||||
|
||||
const orig_english_json = JSON.parse(await fsp.readFile(lang_path + "/en.json") as any);
|
||||
const orig_english_json = JSON.parse(await fsp.readFile(lang_path + "/en.json") as any);
|
||||
|
||||
let orig_translated_json = {};
|
||||
try {
|
||||
orig_translated_json = JSON.parse((await fsp.readFile(lang_path + "/" + template_name + ".json")).toString());
|
||||
}
|
||||
catch (_e) { }
|
||||
let orig_translated_json = {};
|
||||
try {
|
||||
orig_translated_json = JSON.parse((await fsp.readFile(lang_path + "/" + template_name + ".json")).toString());
|
||||
}
|
||||
catch (_e) { }
|
||||
|
||||
let llm_translated_json = {};
|
||||
const translated_json_path = lang_path + "/" + template_name + ".json";
|
||||
if (await fsp.exists(translated_json_path)) {
|
||||
console.log("Loading file", translated_json_path);
|
||||
llm_translated_json = JSON.parse((await fsp.readFile(translated_json_path)).toString());
|
||||
}
|
||||
let llm_translated_json = {};
|
||||
const translated_json_path = lang_path + "/" + template_name + ".json";
|
||||
if (await fsp.exists(translated_json_path)) {
|
||||
console.log("Loading file", translated_json_path);
|
||||
llm_translated_json = JSON.parse((await fsp.readFile(translated_json_path)).toString());
|
||||
}
|
||||
|
||||
let human = 0;
|
||||
let llm = 0;
|
||||
let total_count = 0;
|
||||
await loop_object(orig_english_json, "", async () => {
|
||||
total_count += 1;
|
||||
});
|
||||
|
||||
let total_count = 0;
|
||||
await loop_object(orig_english_json, "", async () => {
|
||||
total_count += 1;
|
||||
});
|
||||
await loop_object(llm_translated_json, "", async (key, _) => {
|
||||
if (!key_exists(orig_english_json, key)) {
|
||||
console.log("Removing key", key);
|
||||
set_i18n_key(llm_translated_json, key, undefined);
|
||||
fsp.writeFile(translated_json_path, JSON.stringify(llm_translated_json, undefined, 2));
|
||||
}
|
||||
});
|
||||
|
||||
await loop_object(llm_translated_json, "", async (key, _) => {
|
||||
if (!key_exists(orig_english_json, key)) {
|
||||
console.log("Removing key", key);
|
||||
set_i18n_key(llm_translated_json, key, undefined);
|
||||
fsp.writeFile(translated_json_path, JSON.stringify(llm_translated_json, undefined, 2));
|
||||
}
|
||||
});
|
||||
await loop_object(orig_english_json, "", async (key, english_translation) => {
|
||||
if (key_exists(orig_translated_json, key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await loop_object(orig_english_json, "", async (key, english_translation) => {
|
||||
if (key_exists(orig_translated_json, key)) {
|
||||
human += 1;
|
||||
return;
|
||||
}
|
||||
if (key_exists(llm_translated_json, key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_exists(llm_translated_json, key)) {
|
||||
llm += 1;
|
||||
return;
|
||||
}
|
||||
console.log("Translating", key, "...");
|
||||
|
||||
console.log("Translating", key, "...");
|
||||
llm++;
|
||||
const prompt = gen_prompt(description_txt, template, key, english_translation);
|
||||
|
||||
const prompt = gen_prompt(description_txt, template, key, english_translation);
|
||||
const response = await ollama.chat({
|
||||
model: model_name,
|
||||
messages: [{ role: "user", content: prompt }],
|
||||
options: {
|
||||
seed: 12345,
|
||||
}
|
||||
})
|
||||
|
||||
const response = await ollama.chat({
|
||||
model: model_name,
|
||||
messages: [{ role: "user", content: prompt }],
|
||||
options: {
|
||||
seed: 12345,
|
||||
}
|
||||
})
|
||||
const msg = extract_backticks(response.message.content);
|
||||
if (msg === undefined || msg[0] === undefined) {
|
||||
throw new Error("backticks failed. Raw content: " + response.message.content);
|
||||
}
|
||||
|
||||
const msg = extract_backticks(response.message.content);
|
||||
if (msg === undefined || msg[0] === undefined) {
|
||||
throw new Error("backticks failed. Raw content: " + response.message.content);
|
||||
}
|
||||
console.log(" >>>", msg);
|
||||
|
||||
console.log(" >>>", msg);
|
||||
set_i18n_key(llm_translated_json, key, msg[0]);
|
||||
fsp.writeFile(translated_json_path, JSON.stringify(llm_translated_json, undefined, 2));
|
||||
});
|
||||
|
||||
set_i18n_key(llm_translated_json, key, msg[0]);
|
||||
fsp.writeFile(translated_json_path, JSON.stringify(llm_translated_json, undefined, 2));
|
||||
});
|
||||
|
||||
console.log("\"" + template_name + "\" translation finished,", human, "were already human translated,", llm, "llm-translated (" + Math.round((llm / total_count) * 100.0) + "% machine-translated)");
|
||||
console.log("Translation", template_name, "finished");
|
||||
}
|
||||
|
||||
run().catch((e) => {
|
||||
console.log("Fatal error:", e);
|
||||
exit(-1);
|
||||
console.log("Fatal error:", e);
|
||||
exit(-1);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Do not run this script if you don’t have at least 32 GiB of system memory,
|
||||
# unless you have enabled the mmap option in the Ollama startup settings.
|
||||
# Submitting PRs that lack translated strings is okay if you don’t meet the
|
||||
# system requirements to run this script, or if you simply prefer not to; we are
|
||||
# regularly updating the missing translation strings anyway.
|
||||
#
|
||||
# Base language: English (en.json)
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user