Skip to content

Commit fb27bb0

Browse files
committed
Add script for handling translations
1 parent f1ba0f8 commit fb27bb0

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

babel.cfg

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[jinja2: **.html]

babel_runner.py

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/venv python3
2+
"""Script for handling translations with Babel"""
3+
4+
import argparse
5+
import os
6+
import subprocess
7+
import tomllib
8+
9+
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
10+
11+
# Global variables used by pybabel below
12+
DOMAIN = "messages"
13+
LOCALES_DIR = os.path.relpath(os.path.join(PROJECT_DIR, "locales"))
14+
POT_FILE = os.path.relpath(os.path.join(LOCALES_DIR, f"{DOMAIN}.pot"), PROJECT_DIR)
15+
SOURCE_DIR = os.path.relpath(
16+
os.path.join(PROJECT_DIR, "python_docs_theme"), PROJECT_DIR
17+
)
18+
MAPPING_FILE = os.path.relpath(os.path.join(PROJECT_DIR, "babel.cfg"), PROJECT_DIR)
19+
20+
21+
def get_project_info() -> dict:
22+
"""Retrieve project's info to populate the message catalog template"""
23+
with open(os.path.join(PROJECT_DIR, "pyproject.toml"), "rb") as f:
24+
data = tomllib.load(f)
25+
return data["project"]
26+
27+
28+
def extract_messages():
29+
"""Extract messages from all source files into template file"""
30+
os.makedirs(LOCALES_DIR, exist_ok=True)
31+
project_data = get_project_info()
32+
subprocess.run(
33+
[
34+
"pybabel",
35+
"extract",
36+
"-F",
37+
MAPPING_FILE,
38+
"--copyright-holder",
39+
COPYRIGHT_HOLDER,
40+
"--project",
41+
project_data["name"],
42+
"--version",
43+
project_data["version"],
44+
"--msgid-bugs-address",
45+
project_data["urls"]["Issue tracker"],
46+
"-o",
47+
POT_FILE,
48+
SOURCE_DIR,
49+
],
50+
check=True,
51+
)
52+
53+
54+
def init_locale(locale: str):
55+
"""Initialize a new locale based on existing"""
56+
cmd = ["pybabel", "init", "-i", POT_FILE, "-d", LOCALES_DIR, "-l", locale]
57+
subprocess.run(cmd, check=True)
58+
59+
60+
def update_catalogs(locale: str):
61+
"""Update translations from existing message catalogs"""
62+
cmd = ["pybabel", "update", "-i", POT_FILE, "-d", LOCALES_DIR]
63+
if locale != "":
64+
cmd.append(["-l", locale])
65+
subprocess.run(cmd, check=True)
66+
67+
68+
def compile_catalogs(locale: str):
69+
"""Compile existing message catalogs"""
70+
cmd = ["pybabel", "compile", "-d", LOCALES_DIR]
71+
if locale != "":
72+
cmd.append(["-l", locale])
73+
subprocess.run(cmd, check=True)
74+
75+
76+
def main():
77+
parser = argparse.ArgumentParser(description=__doc__)
78+
parser.add_argument(
79+
"command",
80+
choices=["init", "extract", "update", "compile"],
81+
help="command to be executed",
82+
)
83+
parser.add_argument(
84+
"-l",
85+
"--locale",
86+
help="language code (needed for init, optional for update and compile)",
87+
)
88+
89+
args = parser.parse_args()
90+
locale = args.locale if args.locale else ""
91+
92+
os.chdir(PROJECT_DIR)
93+
94+
if args.command == "extract":
95+
extract_messages()
96+
elif args.command == "init":
97+
if locale == "":
98+
parser.error("init requires passing the --locale option")
99+
init_locale(locale)
100+
elif args.command == "update":
101+
update_catalogs(locale)
102+
elif args.command == "compile":
103+
compile_catalogs(locale)
104+
105+
106+
if __name__ == "__main__":
107+
main()

0 commit comments

Comments
 (0)