Skip to content

Commit

Permalink
Fix locale scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Evgencheg committed Oct 6, 2024
1 parent 6f332a1 commit a4f8d77
Show file tree
Hide file tree
Showing 19 changed files with 268 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Tools/ss14_ru/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from fluentformatter import FluentFile, FluentFormatter
from fluentformatter import FluentFile, FluentFormatter
119 changes: 119 additions & 0 deletions Tools/ss14_ru/clean_duplicates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import os
import re
import chardet
from datetime import datetime

def find_top_level_dir(start_dir):
marker_file = 'SpaceStation14.sln'
current_dir = start_dir
while True:
if marker_file in os.listdir(current_dir):
return current_dir
parent_dir = os.path.dirname(current_dir)
if parent_dir == current_dir:
print(f"Не удалось найти {marker_file} начиная с {start_dir}")
exit(-1)
current_dir = parent_dir
def find_ftl_files(root_dir):
ftl_files = []
for root, dirs, files in os.walk(root_dir):
for file in files:
if file.endswith('.ftl'):
ftl_files.append(os.path.join(root, file))
return ftl_files

def detect_encoding(file_path):
with open(file_path, 'rb') as file:
raw_data = file.read()
return chardet.detect(raw_data)['encoding']

def parse_ent_blocks(file_path):
try:
encoding = detect_encoding(file_path)
with open(file_path, 'r', encoding=encoding) as file:
content = file.read()
except UnicodeDecodeError:
print(f"Ошибка при чтении файла {file_path}. Попытка чтения в UTF-8.")
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
except UnicodeDecodeError:
print(f"Не удалось прочитать файл {file_path}. Пропускаем.")
return {}

ent_blocks = {}
current_ent = None
current_block = []

for line in content.split('\n'):
if line.startswith('ent-'):
if current_ent:
ent_blocks[current_ent] = '\n'.join(current_block)
current_ent = line.split('=')[0].strip()
current_block = [line]
elif current_ent and (line.strip().startswith('.desc') or line.strip().startswith('.suffix')):
current_block.append(line)
elif line.strip() == '':
if current_ent:
ent_blocks[current_ent] = '\n'.join(current_block)
current_ent = None
current_block = []
else:
if current_ent:
ent_blocks[current_ent] = '\n'.join(current_block)
current_ent = None
current_block = []

if current_ent:
ent_blocks[current_ent] = '\n'.join(current_block)

return ent_blocks

def remove_duplicates(root_dir):
ftl_files = find_ftl_files(root_dir)
all_ents = {}
removed_duplicates = []

for file_path in ftl_files:
ent_blocks = parse_ent_blocks(file_path)
for ent, block in ent_blocks.items():
if ent not in all_ents:
all_ents[ent] = (file_path, block)

for file_path in ftl_files:
try:
encoding = detect_encoding(file_path)
with open(file_path, 'r', encoding=encoding) as file:
content = file.read()

ent_blocks = parse_ent_blocks(file_path)
for ent, block in ent_blocks.items():
if all_ents[ent][0] != file_path:
content = content.replace(block, '')
removed_duplicates.append((ent, file_path, block))

content = re.sub(r'\n{3,}', '\n\n', content)

with open(file_path, 'w', encoding=encoding) as file:
file.write(content)
except Exception as e:
print(f"Ошибка при обработке файла {file_path}: {str(e)}")

# Сохранение лога удаленных дубликатов
log_filename = f"removed_duplicates_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
with open(log_filename, 'w', encoding='utf-8') as log_file:
for ent, file_path, block in removed_duplicates:
log_file.write(f"Удален дубликат: {ent}\n")
log_file.write(f"Файл: {file_path}\n")
log_file.write("Содержимое:\n")
log_file.write(block)
log_file.write("\n\n")

print(f"Обработка завершена. Проверено файлов: {len(ftl_files)}")
print(f"Лог удаленных дубликатов сохранен в файл: {log_filename}")

if __name__ == "__main__":
script_dir = os.path.dirname(os.path.abspath(__file__))
main_folder = find_top_level_dir(script_dir)
root_dir = os.path.join(main_folder, "Resources\\Locale\\ru-RU")
remove_duplicates(root_dir)
61 changes: 61 additions & 0 deletions Tools/ss14_ru/clean_empty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import os
import logging
from datetime import datetime

def find_top_level_dir(start_dir):
marker_file = 'SpaceStation14.sln'
current_dir = start_dir
while True:
if marker_file in os.listdir(current_dir):
return current_dir
parent_dir = os.path.dirname(current_dir)
if parent_dir == current_dir:
print(f"Не удалось найти {marker_file} начиная с {start_dir}")
exit(-1)
current_dir = parent_dir
def setup_logging():
log_filename = f"cleanup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
logging.basicConfig(filename=log_filename, level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
console = logging.StreamHandler()
console.setLevel(logging.INFO)
logging.getLogger('').addHandler(console)
return log_filename

def remove_empty_files_and_folders(path):
removed_files = 0
removed_folders = 0

for root, dirs, files in os.walk(path, topdown=False):
# Удаление пустых файлов
for file in files:
file_path = os.path.join(root, file)
if os.path.getsize(file_path) == 0:
try:
os.remove(file_path)
logging.info(f"Удален пустой файл: {file_path}")
removed_files += 1
except Exception as e:
logging.error(f"Ошибка при удалении файла {file_path}: {str(e)}")

# Удаление пустых папок
if not os.listdir(root):
try:
os.rmdir(root)
logging.info(f"Удалена пустая папка: {root}")
removed_folders += 1
except Exception as e:
logging.error(f"Ошибка при удалении папки {root}: {str(e)}")

return removed_files, removed_folders

if __name__ == "__main__":
script_dir = os.path.dirname(os.path.abspath(__file__))
main_folder = find_top_level_dir(script_dir)
root_dir = os.path.join(main_folder, "Resources\\Locale")
log_file = setup_logging()

logging.info(f"Начало очистки в директории: {root_dir}")
files_removed, folders_removed = remove_empty_files_and_folders(root_dir)
logging.info(f"Очистка завершена. Удалено файлов: {files_removed}, удалено папок: {folders_removed}")
print(f"Лог операций сохранен в файл: {log_file}")
43 changes: 40 additions & 3 deletions Tools/ss14_ru/file.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import typing
import typing

from fluent.syntax import ast
from yamlmodels import YAMLElements
import os
import re


class File:
Expand Down Expand Up @@ -42,17 +43,53 @@ def get_name(self):
class FluentFile(File):
def __init__(self, full_path):
super().__init__(full_path)

self.newline_exceptions_regex = re.compile(r"^\s*[\[\]{}#%^*]")
self.newline_remover_tag = "%ERASE_NEWLINE%"
self.newline_remover_regex = re.compile(r"\n?\s*" + self.newline_remover_tag)

"%ERASE_NEWLINE%"

self.full_path = full_path

def kludge(self, element):
return str.replace(
element.value,
self.prefixed_newline,
self.prefixed_newline_substitute
)


def parse_data(self, file_data: typing.AnyStr):
from fluent.syntax import FluentParser

return FluentParser().parse(file_data)
parsed_data = FluentParser().parse(file_data)

for body_element in parsed_data.body:
if not isinstance(body_element, ast.Term) and not isinstance(body_element, ast.Message):
continue

if not len(body_element.value.elements):
continue

first_element = body_element.value.elements[0]
if not isinstance(first_element, ast.TextElement):
continue

if not self.newline_exceptions_regex.match(first_element.value):
continue

first_element.value = f"{self.newline_remover_tag}{first_element.value}"

return parsed_data

def serialize_data(self, parsed_file_data: ast.Resource):
from fluent.syntax import FluentSerializer

return FluentSerializer(with_junk=True).serialize(parsed_file_data)
serialized_data = FluentSerializer(with_junk=True).serialize(parsed_file_data)
serialized_data = self.newline_remover_regex.sub(' ', serialized_data)

return serialized_data

def read_serialized_data(self):
return self.serialize_data(self.parse_data(self.read_data()))
Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/fluentast.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import typing
import typing

from fluent.syntax import ast, FluentParser, FluentSerializer
from lokalisemodels import LokaliseKey
Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/fluentastcomparer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from fluent.syntax import ast
from fluent.syntax import ast
from fluentast import FluentAstAbstract
from pydash import py_

Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/fluentastmanager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from fluent.syntax import ast
from fluent.syntax import ast
from fluentast import FluentAstAbstract


Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/fluentformatter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python3

# Форматтер, приводящий fluent-файлы (.ftl) в соответствие стайлгайду
# path - путь к папке, содержащий форматируемые файлы. Для форматирования всего проекта, необходимо заменить значение на root_dir_path
Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/keyfinder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import typing
import typing
import logging

from pydash import py_
Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/lokalise_fluent_ast_comparer_manager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from fluent.syntax import ast
from fluent.syntax import ast

from fluentast import FluentAstMessage
from fluentastcomparer import FluentAstComparer
Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/lokalise_project.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import lokalise
import lokalise
import typing
from lokalisemodels import LokaliseKey
from pydash import py_
Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/lokalisemodels.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import typing
import typing
import os
from pydash import py_
from project import Project
Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/project.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pathlib
import pathlib
import os
import glob
from file import FluentFile
Expand Down
Binary file modified Tools/ss14_ru/requirements.txt
Binary file not shown.
7 changes: 7 additions & 0 deletions Tools/ss14_ru/translation.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@echo off

call pip install -r requirements.txt
call python ./yamlextractor.py
call python ./keyfinder.py
call python ./clean_duplicates.py
call python ./clean_empty.py
12 changes: 12 additions & 0 deletions Tools/ss14_ru/translation.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env sh

# make sure to start from script dir
if [ "$(dirname $0)" != "." ]; then
cd "$(dirname $0)"
fi

pip install -r requirements.txt
python3 ./yamlextractor.py
python3 ./keyfinder.py
python3 ./clean_duplicates.py
python3 ./clean_empty.py
2 changes: 1 addition & 1 deletion Tools/ss14_ru/translationsassembler.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import logging
import logging
import typing

from fluent.syntax import FluentParser, FluentSerializer
Expand Down
22 changes: 17 additions & 5 deletions Tools/ss14_ru/yamlextractor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os
import os

from fluent.syntax.parser import FluentParser
from fluent.syntax.serializer import FluentSerializer
Expand Down Expand Up @@ -34,10 +34,23 @@ def execute(self):
en_fluent_file_path = self.create_en_fluent_file(relative_parent_dir, file_name, pretty_fluent_file_serialized)
ru_fluent_file_path = self.create_ru_fluent_file(en_fluent_file_path)

@classmethod
def serialize_yaml_element(cls, element):
parent_id = element.parent_id
if isinstance(parent_id, list):
parent_id = parent_id[0] if parent_id else 'None'

message = FluentSerializedMessage.from_yaml_element(
element.id, element.name,
FluentAstAttributeFactory.from_yaml_element(element),
parent_id
)

return message


def get_serialized_fluent_from_yaml_elements(self, yaml_elements):
fluent_serialized_messages = list(
map(lambda el: FluentSerializedMessage.from_yaml_element(el.id, el.name, FluentAstAttributeFactory.from_yaml_element(el), el.parent_id), yaml_elements)
)
fluent_serialized_messages = list(map(YAMLExtractor.serialize_yaml_element, yaml_elements))
fluent_exist_serialized_messages = list(filter(lambda m: m, fluent_serialized_messages))

if not len(fluent_exist_serialized_messages):
Expand All @@ -49,7 +62,6 @@ def create_en_fluent_file(self, relative_parent_dir, file_name, file_data):
en_new_dir_path = os.path.join(project.en_locale_prototypes_dir_path, relative_parent_dir)
en_fluent_file = FluentFile(os.path.join(en_new_dir_path, f'{file_name}.ftl'))
en_fluent_file.save_data(file_data)
logging.info(f'Актуализирован файл английской локали {en_fluent_file.full_path}')

return en_fluent_file.full_path

Expand Down
2 changes: 1 addition & 1 deletion Tools/ss14_ru/yamlmodels.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class YAMLEntity:
class YAMLEntity:
def __init__(self, id, name, description, suffix, parent_id = None):
self.id = id
self.name = name
Expand Down

0 comments on commit a4f8d77

Please sign in to comment.