Skip to content

Commit

Permalink
upd locale validator, checks for non lokalized strings in ru-RU
Browse files Browse the repository at this point in the history
  • Loading branch information
Rinary1 committed Oct 21, 2024
1 parent 4fe70e6 commit 074d33c
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/validate-locale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ jobs:
pip install --no-cache-dir PyYAML
- name: Validate Locales
run: |
python3 Tools/_sunrise/Schemas/validate_yml.py Resources/Prototypes/
python3 Tools/_sunrise/Schemas/validate_yml.py Resources/Locale/ Resources/Prototypes/ --ignore Tools/_sunrise/Schemas/ignore_list.yml
147 changes: 147 additions & 0 deletions Tools/_sunrise/Schemas/ignore_list.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
ignore_list:
- 'EntityUid'
- 'Zzz...'
- 'playglobalsound'
- 'variantize'
- 'ID'
- 'IP'
- 'TileY'
- 'TileX'
- 'X'
- 'Y'
- 'EI NATH'
- '>MFW'
- 'Hello world!'
- 'green'
- 'red'
- 'purple'
- 'yellow'
- 'orange'
- '$count'
- 'v1'
- 'Nanotrasen'
- 'float'
- '$open'
- '$rate'
- LV-426
- 'LOOC'
- 'OOC'
- 'white'
- 'blue'
- 'grey '
- '#1b487e'
- '#B50F1D'
- 'Never gonna let you down!'
- 'Never gonna give you up!'
- 'power_net_query'
- 'zzz...'
- 'GENDER'
- '$initialCount'
- 'Github'
- 'GitHub'
- 'Space Station 14'
- 'AHelp'
- 'TARCOL MINTI ZHERI'
- "ONI'SOMA!"
- 'AIE KHUSE EU'
- 'Gray'
- '$enabled'
- 'FOO-BAR-BAZ'
- '$state'
- 'Float'
- 'Integer'
- 'left-4-zed'
- 'plant-B-gone'
- 'Pwr Game'
- 'sol dry'
- 'gray'
- 'UITest2'
- 'EVA'
- 'MK58'
- 'WT550'
- 'N1984'
- 'DEUS VULT'
- 'AMS-42'
- 'SAM-300'
- 'AJ-100'
- 'Deus vult! Ave maria!'
- TR-263'
- 'G-Man'
- 'RGB'
- 'Changelog'
- 'M1 Garand'
- 'BR-64'
- 'MG-42'
- 'MG-60'
- 'RPD'
- "Monkin' Donuts"
- 'P-90'
- 'MP-38'
- 'MP5'
- 'MP7'
- 'PPSH-41'
- 'AKMS'
- 'AK74-U'
- 'G-36'
- 'M-28'
- 'AR-18'
- 'M16A4'
- 'STG 44'
- 'ACP-14'
- 'Glock-22'
- 'GL-79'
- 'M-41'
- 'DEAD-BEEF'
- 'UwU'
- 'C-4'
- 'Who ya gonna call?'
- 'Ue No'
- 'Carpe diem!'
- 'Space-Up!'
- 'Sun-kist'
- 'Robust Softdrinks'
- 'C-20r'
- 'Donut Corp.'
- 'LV426'
- 'Kept ya waiting, huh?'
- 'Getmore Chocolate Corp'
- 'Discount Dan'
- 'L6 SAW'
- 'L6C ROW'
- 'China Lake'
- 'Plant-B-Gone'
- 'Bon appétit!'
- 'Bon ap-petite!'
- 'Sol dry'
- 'hover entity' # Спорная хуйня, проверить в игре
- 'drag shadow' # Спорная хуйня, проверить в игре
- 'dbg_rotation1'
- 'dbg_rotation4'
- 'dbg_rotationTex'
- 'plague inc 2.0'
- 'False'
- 'True'
- 'chèvre'
- 'Bon appétit!'
- 'Susnet'
- 'RL-5'
- 'Zauer'
- 'Trenchgun L-4034'
- 'SPAS-12'
- 'TBD'
- '°C ( K)'
- 'Plague inc 2.0'
- 'Discord'
- 'Telegram'

ignore_files:
- italian.ftl
- russian.ftl
- popup.ftl
- controls.ftl
- input.ftl
- speech-chatsan.ftl
- speech-liar.ftl
- german.ftl
- southern.ftl
- tts-voices-sunrise.ftl
129 changes: 87 additions & 42 deletions Tools/_sunrise/Schemas/validate_yml.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,108 @@
#!/usr/bin/env python3

import argparse
import os
import re
import sys
import yaml
import argparse
from glob import iglob
from typing import List

# Общий список ошибок
errors: List["LocaleError"] = []

def main() -> int:
parser = argparse.ArgumentParser("validate_yml.py", description="Validates YML files for Russian characters in specific fields.")
parser.add_argument("directories", nargs="+", help="Directories to look for YML files in")

args = parser.parse_args()
class LocaleError:
def __init__(self, path: str, line: int, message: str):
self.path = path
self.line = line
self.message = message

for dir in args.directories:
check_dir(dir)
def add_error(file_path: str, line: int, message: str):
errors.append(LocaleError(file_path, line, message))

for error in errors:
print(f"{error.path} (строка {error.line}): {error.message}")
def is_english(text):
return bool(re.search(r'[a-zA-Z]', text))

return 1 if errors else 0
def has_russian(text):
return bool(re.search(r'[а-яА-Я]', text))

def check_dir(dir: str):
def remove_braces_content(text):
text1 = re.sub(r'\{.*?\}', '', text)
text2 = re.sub(r'\[.*?\]', '', text1)
text3 = re.sub(r'\<.*?\>', '', text2)
return text3

def contains_ignored_word(text, ignore_list):
return any(ignored_word in text for ignored_word in ignore_list)

def check_translations(root_dir, ignore_list, ignore_files):
ru_locale_dir = f'{root_dir}ru-RU/'
root_dir_abs = os.path.abspath(ru_locale_dir)

for dirpath, _, filenames in os.walk(ru_locale_dir):
for filename in filenames:
if filename.endswith('.ftl'):
file_path = os.path.join(dirpath, filename)
rel_path = os.path.relpath(file_path, root_dir_abs)

if filename in ignore_files:
#print(f'Игнорирование файла: {filename}') Не нужно, если много файлов игнорирует
continue

with open(file_path, 'r', encoding='utf-8') as ftl_file:
lines = ftl_file.readlines()
for line_num, line in enumerate(lines, start=1):
if '=' in line and not line.strip().startswith('#'):
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
value = remove_braces_content(value)

if not has_russian(value) and not contains_ignored_word(value, ignore_list):
if key.endswith('.desc') or key.endswith('.suffix'):
if is_english(value):
add_error(rel_path, line_num, f'Не переведённая строка "{key}": {line.strip()}')
elif is_english(value):
add_error(rel_path, line_num, f'Не переведённая строка "{key}": {line.strip()}')

def check_yml_files(dir: str, ignore_list: List[str]):
key_pattern = re.compile(r'^(name|description|suffix|rules|desc):\s*(.+)')

for yml_rel in iglob("**/*.yml", root_dir=dir, recursive=True):
yml_path = os.path.join(dir, yml_rel)
check_yml(yml_path)

def check_yml(yml_path: str):
try:
with open(yml_path, "r", encoding="utf-8") as file:
with open(yml_path, 'r', encoding='utf-8') as file:
content = file.readlines()

for i, line in enumerate(content, start=1):
match = key_pattern.match(line.strip())
if match:
key, value = match.groups()
if has_russian(value):
add_error(yml_path, i, f'Поле "{key}" содержит русские символы.')

def load_ignore_list(ignore_file):
with open(ignore_file, 'r', encoding='utf-8') as f:
ignore_data = yaml.safe_load(f)
return ignore_data.get('ignore_list', []), ignore_data.get('ignore_files', [])

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Проверка локализационных файлов и YML файлов на русские символы.")
parser.add_argument("localization_dir", help="Каталог с локализационными файлами")
parser.add_argument("yml_dir", help="Каталог с YML файлами")
parser.add_argument("--ignore", help="YAML-файл со списком слов и файлов для игнорирования", required=True)

# Оставляем только строки с ключами 'name:', 'description:', 'suffix:', 'rules:'
filter_and_check(content, yml_path)

except Exception as e:
add_error(yml_path, -1, f"Ошибка чтения файла: {e}")

def filter_and_check(content: List[str], yml_path: str):
key_pattern = re.compile(r'^(name|description|suffix|rules|desc):\s*(.+)')

for i, line in enumerate(content, start=1):
match = key_pattern.match(line.strip())
if match:
key, value = match.groups()
if has_russian_chars(value):
add_error(yml_path, i, f"Поле '{key}' содержит русские символы.")
args = parser.parse_args()

def has_russian_chars(text: str) -> bool:
return bool(re.search(r'[а-яА-Я]', text))
ignore_list, ignore_files = load_ignore_list(args.ignore)

def add_error(yml: str, line: int, message: str):
errors.append(LocaleError(yml, line, message))
check_translations(args.localization_dir, ignore_list, ignore_files)

class LocaleError:
def __init__(self, path: str, line: int, message: str):
self.path = path
self.line = line
self.message = message
check_yml_files(args.yml_dir, ignore_list)

exit(main())
if errors:
for error in errors:
print(f"{error.path} (строка {error.line}): {error.message}")
sys.exit(1)
else:
print("Ошибок не найдено.")
sys.exit(0)

0 comments on commit 074d33c

Please sign in to comment.