|
10 | 10 |
|
11 | 11 | import re |
12 | 12 | from pathlib import Path |
13 | | -from sys import argv |
| 13 | +from sys import argv, exit |
14 | 14 | from languageUtil import namebyid |
15 | 15 |
|
16 | 16 | LANGHOME = "Marlin/src/lcd/language" |
17 | 17 |
|
18 | 18 | # Write multiple sheets if true, otherwise write one giant sheet |
19 | 19 | MULTISHEET = '--single' not in argv[1:] |
| 20 | +DO_TRANSLATE = '--translate' in argv[1:] |
20 | 21 | OUTDIR = Path('out-csv') |
21 | 22 |
|
22 | 23 | # Check for the path to the language files |
@@ -121,6 +122,55 @@ def write_csv_lang(f, strings, name): |
121 | 122 | f.write(',') |
122 | 123 | if name in strings['tall']: f.write('"%s"' % strings['tall'][name]) |
123 | 124 |
|
| 125 | +if DO_TRANSLATE: |
| 126 | + |
| 127 | + import ollama |
| 128 | + |
| 129 | + OLLAMA_MODEL = ("gpt-oss:20b", "llama3.3")[0] |
| 130 | + system_prompt_text = """You are an expert in language translation in the context of 3D printing. |
| 131 | +You will be given a list of existing translations and will be asked to provide a new translation in the given language. |
| 132 | +Your translations must be no more than 18 characters long! Use common abbreviations whenever necessary. |
| 133 | +Assume that named substitutions such as (MACHINE_NAME) are short strings for the purpose of character counting. |
| 134 | +For each translation requested, respond only with the translated string, no introduction, explanation, or assessment. |
| 135 | +This clean output will be perfect for our use case. |
| 136 | +""" |
| 137 | + SYSTEM_PROMPT = [{ 'role': 'system', 'content': system_prompt_text }] |
| 138 | + |
| 139 | + # Send a prompt to Ollama |
| 140 | + def prompt_with_ollama(prompt:str): |
| 141 | + msg = [{ 'role': 'user', 'content': prompt }] |
| 142 | + response = ollama.chat(model=OLLAMA_MODEL, messages=SYSTEM_PROMPT + msg, stream=False) |
| 143 | + return response['message']['content'] |
| 144 | + |
| 145 | + # For each named string find all existing and needed translations |
| 146 | + for name in names.keys(): |
| 147 | + done = {} |
| 148 | + todo = [] |
| 149 | + for lang in langcodes: |
| 150 | + lname = f"{namebyid(lang)} ({lang})" |
| 151 | + strings = language_strings[lang] |
| 152 | + if name in strings['narrow']: |
| 153 | + done[lang] = strings['narrow'][name] |
| 154 | + else: |
| 155 | + todo += [lang] |
| 156 | + |
| 157 | + # For each untranslated language, fill in a translation |
| 158 | + for lang in todo: |
| 159 | + # Show existing translations to the LLM and ask for one more |
| 160 | + prompt = [ f"Please translate the following string into {namebyid(lang)} ({lang})." ] |
| 161 | + if lang == "fr_na": |
| 162 | + prompt += [ "(Substitute plain unaccented ASCII characters for accented characters in the output.)" ] |
| 163 | + prompt += [ "Here are the existing translations:" ] |
| 164 | + for lang in done.keys(): |
| 165 | + prompt += [ f"- {lang} {namebyid(lang)}: \"{done[lang]}\"" ] |
| 166 | + prompt = '\n'.join(prompt) |
| 167 | + #print(f"Prompt: {prompt}") |
| 168 | + newstring = prompt_with_ollama(prompt) |
| 169 | + print(f"{name} ({lang}) = \"{newstring}\"") |
| 170 | + done[lang] = newstring |
| 171 | + if not 'narrow' in language_strings[lang]: language_strings[lang]['narrow'] = {} |
| 172 | + language_strings[lang]['narrow'][name] = newstring |
| 173 | + |
124 | 174 | if MULTISHEET: |
125 | 175 | # |
126 | 176 | # Export a separate sheet for each language |
|
0 commit comments