Skip to content

Commit b8e255c

Browse files
authored
Create transifex-util.py
1 parent 068d9cd commit b8e255c

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python
2+
#
3+
# This python file contains utility functions to manage a Python docs translation
4+
# with Transifex.
5+
#
6+
# This file is maintained at: https://github.com/python-docs-translations/transifex-automations/blob/main/sample-workflows/transifex-util.py
7+
8+
import configparser
9+
from argparse import ArgumentParser
10+
import os
11+
from contextlib import chdir
12+
from pathlib import Path
13+
from subprocess import call
14+
import sys
15+
from tempfile import TemporaryDirectory
16+
17+
18+
def fetch():
19+
"""
20+
Fetch translations from Transifex, remove source lines.
21+
"""
22+
if (code := call("tx --version", shell=True)) != 0:
23+
sys.stderr.write("The Transifex client app is required.\n")
24+
exit(code)
25+
lang = LANGUAGE
26+
_call(f"tx pull -l {lang} --force") # XXX Do we pull everything?
27+
for file in Path().rglob("*.po"):
28+
_call(f"msgcat --no-location -o {file} {file}")
29+
30+
31+
def _call(command: str):
32+
if (return_code := call(command, shell=True)) != 0:
33+
exit(return_code)
34+
35+
36+
def recreate_tx_config():
37+
"""
38+
Regenerate Transifex client config for all resources.
39+
"""
40+
with TemporaryDirectory() as directory:
41+
with chdir(directory):
42+
_clone_cpython_repo(VERSION)
43+
_build_gettext()
44+
with chdir(Path(directory) / "cpython/Doc/build"):
45+
_create_txconfig()
46+
_update_txconfig_resources()
47+
with open(".tx/config", "r") as file:
48+
contents = file.read()
49+
contents = contents.replace("./<lang>/LC_MESSAGES/", "")
50+
with open(".tx/config", "w") as file:
51+
file.write(contents)
52+
53+
54+
def delete_obsolete_files():
55+
files_to_delete = list(_get_files_to_delete())
56+
if not files_to_delete:
57+
return
58+
else:
59+
for file in files_to_delete:
60+
print(f"Removing {file}")
61+
os.remove(file)
62+
_call(f'git rm --quiet "{file}"')
63+
64+
65+
def _get_files_to_delete():
66+
with open(".tx/config") as config_file:
67+
config = config_file.read()
68+
for file in Path().rglob("*.po"):
69+
if os.fsdecode(file) not in config:
70+
yield os.fsdecode(file)
71+
72+
73+
def _clone_cpython_repo(version: str):
74+
_call(
75+
f"git clone -b {version} --single-branch https://github.com/python/cpython.git --depth 1"
76+
)
77+
78+
79+
def _build_gettext():
80+
_call("make -C cpython/Doc/ gettext")
81+
82+
83+
def _create_txconfig():
84+
_call("sphinx-intl create-txconfig")
85+
86+
87+
def _update_txconfig_resources():
88+
_call(
89+
f"sphinx-intl update-txconfig-resources --transifex-organization-name python-doc "
90+
f"--transifex-project-name {PROJECT_SLUG} --locale-dir . --pot-dir gettext"
91+
)
92+
93+
94+
def _get_tx_token() -> str:
95+
if os.path.exists(".tx/api-key"):
96+
with open(".tx/api-key") as f:
97+
return f.read()
98+
99+
config = configparser.ConfigParser()
100+
config.read(os.path.expanduser("~/.transifexrc"))
101+
try:
102+
return config["https://www.transifex.com"]["token"]
103+
except KeyError:
104+
pass
105+
106+
return os.getenv("TX_TOKEN", "")
107+
108+
109+
if __name__ == "__main__":
110+
RUNNABLE_SCRIPTS = ("fetch", "recreate_tx_config", "delete_obsolete_files")
111+
112+
parser = ArgumentParser()
113+
parser.add_argument("cmd", choices=RUNNABLE_SCRIPTS)
114+
parser.add_argument("--language", required=True)
115+
parser.add_argument("--project-slug", required=True)
116+
parser.add_argument("--version", required=True)
117+
118+
options = parser.parse_args()
119+
120+
LANGUAGE = options.language
121+
PROJECT_SLUG = options.project_slug
122+
VERSION = options.version
123+
124+
globals()[options.cmd]()

0 commit comments

Comments
 (0)