Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # presentation/bot/scripts/generate_i18n_stub.py
- from pathlib import Path
- import re
- LOCALES_PATH = Path(__file__).parent.parent / "locales"
- STUB_FILE = Path(__file__).parent.parent / "i18n.pyi"
- LANGUAGES = ["ru", "en"]
- def extract_key_value(ftl_path: Path) -> dict[str, str]:
- """Извлекает ключи и значения из одного .ftl файла."""
- key_values = {}
- current_key = None
- current_value = []
- for line in ftl_path.read_text(encoding="utf-8").splitlines():
- if not line.strip() or line.strip().startswith("#"):
- continue
- if "=" in line and not line.startswith(" "):
- # Сохраняем предыдущий ключ-значение
- if current_key and current_value:
- key_values[current_key] = "\n".join(current_value).strip()
- # Начинаем новый ключ-значение
- key, value = line.split("=", 1)
- current_key = key.strip().replace("-", "_")
- current_value = [value.strip()]
- elif current_key:
- # Продолжение многострочного значения (может быть с отступом или без)
- current_value.append(line.strip())
- # Сохраняем последний ключ-значение
- if current_key and current_value:
- key_values[current_key] = "\n".join(current_value).strip()
- return key_values
- def collect_all_translations(base_path: Path) -> dict[str, dict[str, str]]:
- """Собирает все переводы из всех .ftl файлов для всех языков."""
- all_translations = {}
- for lang in LANGUAGES:
- lang_path = base_path / lang
- if not lang_path.exists():
- continue
- lang_translations = {}
- for ftl_file in lang_path.rglob("*.ftl"):
- key_values = extract_key_value(ftl_file)
- lang_translations.update(key_values)
- if lang_translations:
- all_translations[lang] = lang_translations
- return all_translations
- def clean_text_for_docstring(text: str) -> str:
- """Очищает текст для использования в docstring."""
- # Убираем HTML теги
- # text = re.sub(r"<[^>]+>", "", text)
- # Заменяем переменные в фигурных скобках на более читаемый вид
- # text = re.sub(r"\{[^}]+\}", "{var}", text)
- # Заменяем переменные в долларах на более читаемый вид
- # text = re.sub(r"\$[a-zA-Z_]+", "{var}", text)
- # Убираем лишние пробелы и переносы строк
- # text = re.sub(r"\s+", " ", text).strip()
- # Ограничиваем длину
- if len(text) > 200:
- text = text[:200] + "..."
- return text
- def generate_stub():
- """Генерирует i18n.pyi для автодополнения методов и объекта i18n с docstring."""
- all_translations = collect_all_translations(LOCALES_PATH)
- # Получаем все уникальные ключи
- all_keys = set()
- for lang_translations in all_translations.values():
- all_keys.update(lang_translations.keys())
- all_keys = sorted(all_keys)
- with open(STUB_FILE, "w", encoding="utf-8") as f:
- f.write("# presentation/bot/i18n.pyi\n\n")
- f.write("from typing import Literal\n\n")
- f.write("class I18n:\n")
- f.write(
- " def __init__(self, locale: Literal['ru', 'en'] = 'ru') -> None: ...\n\n"
- )
- for key in all_keys:
- # Собираем docstring из всех доступных переводов
- docstring_parts = []
- for lang in LANGUAGES:
- if lang in all_translations and key in all_translations[lang]:
- text = all_translations[lang][key]
- clean_text = clean_text_for_docstring(text)
- if clean_text:
- docstring_parts.append(f"{lang}: {clean_text}")
- if docstring_parts:
- docstring = "\n".join(docstring_parts)
- f.write(f" def {key}(self, **kwargs) -> str:\n")
- f.write(f' """{docstring}"""\n')
- f.write(f" ...\n\n")
- else:
- f.write(f" def {key}(self, **kwargs) -> str: ...\n\n")
- f.write("\n")
- f.write("i18n: I18n\n")
- if __name__ == "__main__":
- generate_stub()
- print(f"Stub i18n.pyi сгенерирован для всех ключей в {LOCALES_PATH}")
- print(
- "Теперь при наведении на методы i18n будут отображаться переводы из .ftl файлов!"
- )
Advertisement
Add Comment
Please, Sign In to add comment