Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions .github/scripts/update_language_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#!/usr/bin/env python3
"""
Script to automatically update language names in the English translation file.
Scans for locale files and ensures all languages are present in en.json.
"""
import json
import logging
import sys
from pathlib import Path
from typing import Dict, List

from babel import Locale, UnknownLocaleError

LOCALES_DIR = Path('frontend/locales')
EN_JSON_PATH = LOCALES_DIR / 'en.json'

# Mapping for special/custom locale codes that don't follow standard BCP 47
CUSTOM_LOCALE_MAPPINGS = {
'ar-AA': ('ar', 'Arabic'), # Generic Arabic
'en': ('en', 'English'),
}


def setup_logging():
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(levelname)s: %(message)s'
)


def get_locale_files() -> List[str]:
"""Get all locale codes from JSON files in the locales directory."""
if not LOCALES_DIR.exists():
logging.error("Locales directory not found: %s", LOCALES_DIR)
return []

locale_codes = []
for file in sorted(LOCALES_DIR.glob('*.json')):
# Extract locale code from filename (e.g., "en.json" -> "en")
locale_code = file.stem
locale_codes.append(locale_code)

logging.info("Found %d locale files", len(locale_codes))
return sorted(locale_codes)


def get_language_name(locale_code: str) -> str:
"""
Get the English display name for a locale code.

Args:
locale_code: Language/locale code (e.g., 'en', 'pt-BR', 'zh-CN')

Returns:
English display name for the language
"""
# Check custom mappings first
if locale_code in CUSTOM_LOCALE_MAPPINGS:
_, name = CUSTOM_LOCALE_MAPPINGS[locale_code]
return name

try:
# Parse locale code using Babel
locale = Locale.parse(locale_code.replace('-', '_'))

# Get English display name
display_name = locale.get_display_name('en')

if not display_name:
# Fallback to language name if full display name not available
display_name = locale.english_name

return display_name

except (UnknownLocaleError, ValueError) as e:
logging.warning("Could not parse locale '%s': %s", locale_code, e)
# Fallback: capitalize the locale code
return locale_code.replace('-', ' ').replace('_', ' ').title()


def load_en_json() -> dict:
"""Load the English translation JSON file."""
if not EN_JSON_PATH.exists():
logging.error("English translation file not found: %s", EN_JSON_PATH)
return {}

try:
with EN_JSON_PATH.open('r', encoding='utf-8') as f:
return json.load(f)
except (IOError, json.JSONDecodeError) as e:
logging.error("Failed to load %s: %s", EN_JSON_PATH, e)
return {}


def save_en_json(data: dict):
"""Save the English translation JSON file."""
try:
with EN_JSON_PATH.open('w', encoding='utf-8') as f:
# Use 4-space indentation to match existing file format
json.dump(data, f, ensure_ascii=False, indent=4)
# Add newline at end of file
f.write('\n')
logging.info("Saved updated en.json")
except IOError as e:
logging.error("Failed to save %s: %s", EN_JSON_PATH, e)
sys.exit(1)


def update_language_names(en_data: dict, locale_codes: List[str]) -> bool:
"""
Update the languages section in en.json with all locale codes.

Args:
en_data: The parsed en.json data
locale_codes: List of all locale codes from files

Returns:
True if changes were made, False otherwise
"""
# Ensure languages section exists
if 'languages' not in en_data:
en_data['languages'] = {}
logging.info("Created 'languages' section in en.json")

languages = en_data['languages']
original_languages = languages.copy()

# Add any missing languages
added_count = 0
for locale_code in locale_codes:
if locale_code not in languages:
language_name = get_language_name(locale_code)
languages[locale_code] = language_name
logging.info("Added language: %s = %s", locale_code, language_name)
added_count += 1

# Sort languages alphabetically by key
en_data['languages'] = dict(sorted(languages.items()))

# Check if anything changed
changed = (original_languages != en_data['languages'])

if changed:
logging.info("Updated %d language names", added_count)
else:
logging.info("All languages already present, no changes needed")

return changed


def main():
setup_logging()
logging.info("🔄 Starting language names update")

# Get all locale files
locale_codes = get_locale_files()
if not locale_codes:
logging.error("No locale files found")
sys.exit(1)

# Load English translation file
en_data = load_en_json()
if not en_data:
logging.error("Failed to load English translation file")
sys.exit(1)

# Update language names
changed = update_language_names(en_data, locale_codes)

if changed:
save_en_json(en_data)
logging.info("✅ Language names updated successfully")
else:
logging.info("✅ No updates needed, en.json is already up-to-date")

sys.exit(0)


if __name__ == "__main__":
main()
70 changes: 70 additions & 0 deletions .github/workflows/update-language-names.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Update Language Names

on:
push:
branches: [ main ]
paths:
- 'frontend/locales/*.json'
- '.github/scripts/update_language_names.py'
- '.github/workflows/update-language-names.yml'
workflow_dispatch:

permissions:
contents: write
pull-requests: write

jobs:
update-language-names:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
with:
python-version: '3.8'
cache: 'pip'
cache-dependency-path: .github/workflows/update-languages/requirements.txt

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r .github/workflows/update-languages/requirements.txt

- name: Run language names update script
run: python .github/scripts/update_language_names.py

- name: Check for en.json changes
run: |
if git diff --quiet -- frontend/locales/en.json; then
echo "changed=false" >> $GITHUB_ENV
else
echo "changed=true" >> $GITHUB_ENV
fi

- name: Create Pull Request
if: env.changed == 'true'
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: automation/update-language-file
base: main
title: "Update language names in en.json"
commit-message: "chore: update language names in en.json"
body: |
This PR automatically updates the language names in `frontend/locales/en.json` based on the available locale files.

New languages have been added to ensure all locale files have corresponding language names in the English translation file.

🤖 This PR was automatically created by the update-language-names workflow.
path: .
add-paths: |
frontend/locales/en.json

- name: No updates needed
if: env.changed == 'false'
run: echo "✅ en.json language names are already up-to-date"
1 change: 1 addition & 0 deletions .github/workflows/update-languages/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
babel
3 changes: 3 additions & 0 deletions frontend/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,13 @@
"update_label": "Update Label"
},
"languages": {
"ar-AA": "Arabic",
"bs-BA": "Bosnian (Bosnia and Herzegovina)",
"ca": "Catalan",
"cs-CZ": "Czech",
"da-DK": "Danish",
"de": "German",
"el-GR": "Greek (Greece)",
"en": "English",
"es": "Spanish",
"fi-FI": "Finnish",
Expand All @@ -549,6 +551,7 @@
"sq-AL": "Albanian",
"sv": "Swedish",
"ta-IN": "Tamil",
"te-IN": "Telugu (India)",
"th-TH": "Thai",
"tr": "Turkish",
"uk-UA": "Ukrainian",
Expand Down
Loading