Handle repeating characters a bit better.

This commit is contained in:
dazedanon 2026-03-18 09:00:43 -05:00
parent 29e5899647
commit a89f347030
2 changed files with 80 additions and 2 deletions

View file

@ -168,6 +168,9 @@ def parseJSON(data, filename):
# GameSetting format (Nupu_GameSetting.json - fzCardDatas, fzDeckDatas, rentalDecks)
elif any(k in data for k in ["fzCardDatas", "fzDeckDatas", "rentalDecks"]):
result = translateGameSetting(data, filename)
# Src/Tl dialogue format (numeric-keyed entries with src and tl fields)
elif data and all(isinstance(v, dict) and "src" in v for v in data.values()):
result = translateDialogueSrcTl(data, filename)
else:
result = translateJSON(data, filename, [])
else:
@ -845,6 +848,79 @@ def translateGameSetting(data, filename):
return tokens
def translateDialogueSrcTl(data, filename):
"""Translate src/tl dialogue JSON format.
Format:
{
"0": {"type": "dialogue", "src": "Japanese text", "tl": ""},
"4": {"type": "dialogue", "speaker": "琴音", "src": "「...」", "tl": ""}
}
Translates 'src' into 'tl'. Uses 'speaker' as context only not translated.
Skips entries where 'tl' is already populated.
"""
global LOCK, ESTIMATE, FILENAME, PBAR, MISMATCH
tokens = [0, 0]
srcList = []
keyList = [] # list of (key, entry_type)
# Collect all entries with translatable content
for key, entry in data.items():
if not isinstance(entry, dict):
continue
src = entry.get("src", "")
if not src:
continue
tl = entry.get("tl", "")
entry_type = entry.get("type", "")
speaker = entry.get("speaker", "")
if tl:
# Already has a translation — send tl so the module can decide to skip it
srcList.append(tl)
else:
if not re.search(LANGREGEX, src):
continue
srcClean = src.replace("\r\n", " ").replace("\n", " ").strip()
if speaker:
srcList.append(f"[{speaker}]: {srcClean}")
else:
srcList.append(srcClean)
keyList.append((key, entry_type))
if not srcList:
return tokens
PBAR.total = len(srcList)
PBAR.refresh()
response = translateAI(srcList, "Reply with the English Translation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedList = response[0]
if len(srcList) != len(translatedList):
with LOCK:
if FILENAME not in MISMATCH:
MISMATCH.append(FILENAME)
for i, (key, entry_type) in enumerate(keyList):
if i >= len(translatedList):
break
translatedText = translatedList[i]
# Strip speaker prefix if the AI echoed it back
match = re.search(r'^\[.+?\]\s?[|:]\s?', translatedText)
if match:
translatedText = translatedText[match.end():]
data[key]["tl"] = translatedText
save_progress_json(data, filename)
return tokens
def translateJSON(data, filename, translatedList):
global LOCK, ESTIMATE, FILENAME, PBAR, MISMATCH
if translatedList:

View file

@ -1405,7 +1405,8 @@ def translateAI(text, history, config, filename=None, pbar=None, lock=None, mism
protected_items.append("Placeholder Text")
all_replacements[j] = {}
else:
protected_text, replacements = protect_script_codes(tItem[j])
collapsed = re.sub(r'(.)\1{9,}', lambda m: m.group(1) * 10, tItem[j])
protected_text, replacements = protect_script_codes(collapsed)
protected_items.append(protected_text)
all_replacements[j] = replacements
else:
@ -1413,7 +1414,8 @@ def translateAI(text, history, config, filename=None, pbar=None, lock=None, mism
protected_items = "Placeholder Text"
all_replacements[0] = {}
else:
protected_items, all_replacements[0] = protect_script_codes(tItem)
collapsed = re.sub(r'(.)\1{9,}', lambda m: m.group(1) * 10, tItem)
protected_items, all_replacements[0] = protect_script_codes(collapsed)
# Filter out corrupted/mojibake text (U+FFFD) from the batch before API call
corrupted_map = {} # original_index -> original_text