боты русифицированы
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Build the static mod-playerbots ruRU SQL update from a reviewed TSV file."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import re
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
INPUT = ROOT / "playerbots-phrases-ru-reviewed.tsv"
|
||||
OUTPUT = (
|
||||
ROOT
|
||||
/ "modules/mod-playerbots/data/sql/playerbots/updates/"
|
||||
/ "2026_07_30_00_ai_playerbot_russian_texts.sql"
|
||||
)
|
||||
EXPECTED_FIELDS = ("id", "key", "original_en", "translation_ru")
|
||||
PLACEHOLDER_RE = re.compile(r"%[A-Za-z_][A-Za-z0-9_]*|<[^>]+>")
|
||||
|
||||
|
||||
def sql_quote(value: str) -> str:
|
||||
return "'" + value.replace("\\", "\\\\").replace("'", "\\'") + "'"
|
||||
|
||||
|
||||
def load_rows() -> list[dict[str, str]]:
|
||||
with INPUT.open(encoding="utf-8-sig", newline="") as input_file:
|
||||
reader = csv.DictReader(input_file, delimiter="\t")
|
||||
if tuple(reader.fieldnames or ()) != EXPECTED_FIELDS:
|
||||
raise RuntimeError(
|
||||
f"Unexpected TSV columns: {reader.fieldnames}; "
|
||||
f"expected {EXPECTED_FIELDS}"
|
||||
)
|
||||
rows = list(reader)
|
||||
|
||||
if not rows:
|
||||
raise RuntimeError(f"No translations found in {INPUT}")
|
||||
|
||||
seen_ids: set[int] = set()
|
||||
for line_number, row in enumerate(rows, start=2):
|
||||
try:
|
||||
row_id = int(row["id"])
|
||||
except ValueError as error:
|
||||
raise RuntimeError(
|
||||
f"{INPUT}:{line_number}: invalid id {row['id']!r}"
|
||||
) from error
|
||||
|
||||
if row_id in seen_ids:
|
||||
raise RuntimeError(f"{INPUT}:{line_number}: duplicate id {row_id}")
|
||||
seen_ids.add(row_id)
|
||||
|
||||
if not row["key"]:
|
||||
raise RuntimeError(f"{INPUT}:{line_number}: empty key")
|
||||
if not row["translation_ru"].strip():
|
||||
raise RuntimeError(f"{INPUT}:{line_number}: empty translation")
|
||||
|
||||
source_placeholders = Counter(PLACEHOLDER_RE.findall(row["original_en"]))
|
||||
target_placeholders = Counter(PLACEHOLDER_RE.findall(row["translation_ru"]))
|
||||
if source_placeholders != target_placeholders:
|
||||
raise RuntimeError(
|
||||
f"{INPUT}:{line_number}: placeholder mismatch: "
|
||||
f"{source_placeholders} != {target_placeholders}"
|
||||
)
|
||||
|
||||
return rows
|
||||
|
||||
|
||||
def write_sql(rows: list[dict[str, str]]) -> None:
|
||||
lines = [
|
||||
"-- MoonWell static Russian localization for mod-playerbots.",
|
||||
f"-- Generated from {INPUT.name}; edit the TSV and rebuild, not this file.",
|
||||
"-- Placeholder names and counts are validated; their order may differ in Russian.",
|
||||
"SET NAMES utf8mb4;",
|
||||
"",
|
||||
"START TRANSACTION;",
|
||||
]
|
||||
for row in rows:
|
||||
lines.append(
|
||||
"UPDATE `ai_playerbot_texts` "
|
||||
f"SET `text_loc8`={sql_quote(row['translation_ru'])} "
|
||||
f"WHERE `id`={int(row['id'])} AND `name`={sql_quote(row['key'])};"
|
||||
)
|
||||
lines.extend(["COMMIT;", ""])
|
||||
OUTPUT.write_text("\n".join(lines), encoding="utf-8")
|
||||
print(f"Wrote {len(rows)} reviewed translations to {OUTPUT}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
write_sql(load_rows())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user