Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 337b0de

Browse files
committed
Set up workflow
1 parent c5a6280 commit 337b0de

File tree

6 files changed

+547
-2
lines changed

6 files changed

+547
-2
lines changed

.github/scripts/manage_translation.py

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
#!/usr/bin/env python
2+
#
3+
# This python file contains utility scripts to manage Python docs Polish translation.
4+
# It has to be run inside the python-docs-uk git root directory.
5+
#
6+
# Inspired by django-docs-translations script by claudep.
7+
#
8+
# The following commands are available:
9+
#
10+
# * fetch: fetch translations from transifex.com and strip source lines from the
11+
# files.
12+
# * recreate_readme: recreate readme to update translation progress.
13+
# * regenerate_tx_config: recreate configuration for all resources.
14+
15+
from argparse import ArgumentParser
16+
from collections import Counter
17+
import os
18+
from re import match
19+
from subprocess import call, run
20+
import sys
21+
22+
LANGUAGE = 'uk'
23+
24+
25+
def fetch():
26+
"""
27+
Fetch translations from Transifex, remove source lines.
28+
"""
29+
if call("tx --version", shell=True) != 0:
30+
sys.stderr.write("The Transifex client app is required (pip install transifex-client).\n")
31+
exit(1)
32+
lang = LANGUAGE
33+
pull_returncode = call(f'tx pull -l {lang} --minimum-perc=1 --force --skip', shell=True)
34+
if pull_returncode != 0:
35+
exit(pull_returncode)
36+
for root, _, po_files in os.walk('../..'):
37+
for po_file in po_files:
38+
if not po_file.endswith(".po"):
39+
continue
40+
po_path = os.path.join(root, po_file)
41+
call(f'msgcat --no-location -o {po_path} {po_path}', shell=True)
42+
43+
44+
RESOURCE_NAME_MAP = {'glossary_': 'glossary'}
45+
TX_ORGANISATION = 'python-doc'
46+
TX_PROJECT = 'python-newest'
47+
GH_ORGANISATION = 'python'
48+
49+
def recreate_tx_config():
50+
"""
51+
Regenerate Transifex client config for all resources.
52+
"""
53+
resources = _get_resources()
54+
with open('.tx/config', 'w') as config:
55+
config.writelines(('[main]\n', 'host = https://www.transifex.com\n',))
56+
for resource in resources:
57+
slug = resource['slug']
58+
name = RESOURCE_NAME_MAP.get(slug, slug)
59+
if slug == '0':
60+
continue
61+
elif '--' in slug:
62+
directory, file_name = name.split('--')
63+
if match(r'\d+_\d+', file_name):
64+
file_name = file_name.replace('_', '.')
65+
config.writelines(
66+
(
67+
'\n',
68+
f'[{TX_PROJECT}.{slug}]\n',
69+
f'trans.{LANGUAGE} = {directory}/{file_name}.po\n',
70+
'type = PO\n',
71+
'source_lang = en\n',
72+
)
73+
)
74+
else:
75+
config.writelines(
76+
(
77+
'\n',
78+
f'[{TX_PROJECT}.{slug}]\n',
79+
f'trans.{LANGUAGE} = {name}.po\n',
80+
'type = PO\n',
81+
'source_lang = en\n',
82+
)
83+
)
84+
85+
86+
def _get_resources():
87+
from requests import get
88+
89+
resources = []
90+
offset = 0
91+
if os.path.exists('.tx/api-key'):
92+
with open('.tx/api-key') as f:
93+
transifex_api_key = f.read()
94+
else:
95+
transifex_api_key = os.getenv('TX_TOKEN')
96+
while True:
97+
response = get(
98+
f'https://api.transifex.com/organizations/{TX_ORGANISATION}/projects/{TX_PROJECT}/resources/',
99+
params={'language_code': LANGUAGE, 'offset': offset},
100+
auth=('api', transifex_api_key),
101+
)
102+
response.raise_for_status()
103+
response_list = response.json()
104+
resources.extend(response_list)
105+
if len(response_list) < 100:
106+
break
107+
offset += len(response_list)
108+
return resources
109+
110+
111+
def _get_unique_translators():
112+
process = run(
113+
['grep', '-ohP', r'(?<=^# )(.+)(?=, \d+$)', '-r', '.'],
114+
capture_output=True,
115+
text=True,
116+
)
117+
translators = [match('(.*)( <.*>)?', t).group(1) for t in process.stdout.splitlines()]
118+
unique_translators = Counter(translators)
119+
return unique_translators
120+
121+
122+
def recreate_readme():
123+
def language_switcher(entry):
124+
return (
125+
entry['name'].startswith('bugs')
126+
or entry['name'].startswith('tutorial')
127+
or entry['name'].startswith('library--functions')
128+
)
129+
130+
def average(averages, weights):
131+
return sum([a * w for a, w in zip(averages, weights)]) / sum(weights)
132+
133+
resources = _get_resources()
134+
filtered = list(filter(language_switcher, resources))
135+
average_list = [e['stats']['translated']['percentage'] for e in filtered]
136+
weights_list = [e['wordcount'] for e in filtered]
137+
138+
language_switcher_status = average(average_list, weights=weights_list) * 100
139+
unique_translators = _get_unique_translators()
140+
number_of_translators = len(unique_translators)
141+
142+
with open('README.md', 'w') as file:
143+
file.write(
144+
f'''\
145+
Український переклад документації Python
146+
========================================
147+
![build](https://github.com/{GH_ORGANISATION}/python-docs-uk/workflows/.github/workflows/update-and-build.yml/badge.svg)
148+
![{language_switcher_status:.2f}% прогрес перекладу](https://img.shields.io/badge/прогрес_перекладу-{language_switcher_status:.2f}%25-0.svg)
149+
![хід перекладу всієї документації](https://img.shields.io/badge/dynamic/json.svg?label=всього&query=$.{LANGUAGE}&url=http://gce.zhsj.me/python/newest)
150+
![{number_of_translators} перекладачів](https://img.shields.io/badge/перекладачів-{number_of_translators}-0.svg)
151+
152+
Якщо ви знайшли помилку або маєте пропозицію,
153+
[додати issue](https://github.com/{GH_ORGANISATION}/python-docs-uk/issues) у цьому проекті або запропонуйте зміни:
154+
155+
* Зареєструйтесь на платформі [Transifex](https://www.transifex.com/)
156+
* Перейдіть на сторінку [документації Python](https://www.transifex.com/{TX_ORGANISATION}/{TX_PROJECT}/).
157+
* Натисніть кнопку „Join Team”, оберіть українську (uk) мову та натисніть „Join” щоб приєднатися до команди.
158+
* Приєднавшись до команди, виберіть ресурс, що хочете виправити/оновити.
159+
160+
Додаткову інформацію про використання Transifex дивіться [в документації](https://docs.transifex.com/getting-started-1/translators).
161+
162+
**Прогрес перекладу**
163+
164+
![прогрес перекладу](language-switcher-progress.svg)
165+
166+
Українська мова з’явиться в меню вибору мови docs.python.org, [коли будуть повністю перекладені](https://www.python.org/dev/peps/pep-0545/#add-translation-to-the-language-switcher):
167+
* `bugs`,
168+
* всі ресурси в каталозі `tutorial`,
169+
* `library/functions`.
170+
171+
**Як переглянути останню збірку документації?**
172+
173+
Завантажте останню створену документацію зі списку артефактів в останній дії GitHub (вкладка Actions).
174+
Переклади завантажуються з Transifex до цього репозиторію приблизно кожні півгодини.
175+
Документація на python.org оновлюється приблизно раз на день.
176+
177+
**Канали зв'язку**
178+
179+
* [Telegram-чат перекладачів](https://t.me/+dXwqHZ0KPKYyNDc6)
180+
* [Python translations working group](https://mail.python.org/mailman3/lists/translation.python.org/)
181+
* [Python Documentation Special Interest Group](https://www.python.org/community/sigs/current/doc-sig/)
182+
183+
**Ліцензія**
184+
185+
Запрошуючи вас до спільного створення проекту на платформі Transifex, ми пропонуємо договір на передачу ваших перекладів
186+
Python Software Foundation [по ліцензії CC0](https://creativecommons.org/publicdomain/zero/1.0/deed.uk).
187+
Натомість ви побачите, що ви є перекладачем тієї частини, яку ви переклали.
188+
Ви висловлюєте свою згоду з цією угодою, надаючи свою роботу для включення в документацію.
189+
190+
**Оновлення локального перекладу**
191+
192+
* `.github/scripts/manage_translation.py recreate_tx_config`
193+
* `.github/scripts/manage_translation.py fetch`
194+
* `.github/scripts/manage_translation.py recreate_readme`
195+
196+
**Подяка**
197+
* Maciej Olko - Polish team
198+
* Julien Palard - French team
199+
* Tomo Cocoa - Japanese team
200+
201+
**Внесок спільноти**
202+
203+
| Перекладач | Кількість документів |
204+
|:----------------|:--------------------:|
205+
'''
206+
)
207+
208+
file.writelines(
209+
(f'|{t}|{c}|\n' for (t, c) in unique_translators.most_common())
210+
)
211+
212+
213+
if __name__ == "__main__":
214+
RUNNABLE_SCRIPTS = ('fetch', 'recreate_tx_config', 'recreate_readme')
215+
216+
parser = ArgumentParser()
217+
parser.add_argument('cmd', nargs=1, choices=RUNNABLE_SCRIPTS)
218+
options = parser.parse_args()
219+
220+
eval(options.cmd[0])()
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
on:
2+
schedule:
3+
- cron: '0 0 * * *'
4+
push:
5+
branches: ['main']
6+
7+
jobs:
8+
update-translation:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
matrix:
12+
version: ['3.8', '3.9', '3.10', '3.11']
13+
steps:
14+
- uses: styfle/cancel-workflow-action@main
15+
with:
16+
access_token: ${{ secrets.GITHUB_TOKEN }}
17+
- uses: actions/setup-python@master
18+
with:
19+
python-version: '3.9'
20+
- run: sudo apt-get install -y gettext
21+
- run: pip install 'transifex-client>=0.14' requests
22+
- uses: actions/checkout@master
23+
with:
24+
ref: ${{ matrix.version }}
25+
- run: .github/scripts/manage_translation.py recreate_tx_config
26+
env:
27+
TX_TOKEN: ${{ secrets.TX_TOKEN }}
28+
- run: echo -e '[https://www.transifex.com]\napi_hostname = https://api.transifex.com\nhostname = https://www.transifex.com\nusername = api' > $HOME/.transifexrc
29+
- run: .github/scripts/manage_translation.py fetch
30+
env:
31+
TX_TOKEN: ${{ secrets.TX_TOKEN }}
32+
- run: .github/scripts/manage_translation.py recreate_readme
33+
env:
34+
TX_TOKEN: ${{ secrets.TX_TOKEN }}
35+
- run: git config --local user.email '[email protected]'
36+
name: Run git config --local user.email '…'
37+
- run: git config --local user.name "GitHub Action's update-translation job"
38+
- run: git add .
39+
- run: git commit -m 'Update translation from Transifex' || true
40+
- uses: ad-m/github-push-action@master
41+
with:
42+
branch: ${{ matrix.version }}
43+
github_token: ${{ secrets.GITHUB_TOKEN }}
44+
- uses: peter-evans/repository-dispatch@main
45+
with:
46+
token: ${{ secrets.GITHUB_TOKEN }}
47+
event-type: translation-updated
48+
build-translation:
49+
runs-on: ubuntu-latest
50+
strategy:
51+
matrix:
52+
version: ['3.8', '3.9', '3.10', '3.11']
53+
format: [html, latex]
54+
needs: ['update-translation']
55+
steps:
56+
- uses: actions/setup-python@master
57+
with:
58+
python-version: '3.10'
59+
- uses: actions/checkout@master
60+
with:
61+
repository: python/cpython
62+
ref: ${{ matrix.version }}
63+
- run: make venv
64+
working-directory: ./Doc
65+
- uses: actions/checkout@master
66+
with:
67+
ref: ${{ matrix.version }}
68+
path: Doc/locales/uk/LC_MESSAGES
69+
- run: git pull
70+
working-directory: ./Doc/locales/uk/LC_MESSAGES
71+
- run: make -e SPHINXOPTS="-D language='uk' -D gettext_compact=0 -W --keep-going" ${{ matrix.format }}
72+
working-directory: ./Doc
73+
- uses: actions/upload-artifact@master
74+
with:
75+
name: build-${{ matrix.version }}-${{ matrix.format }}
76+
path: Doc/build/${{ matrix.format }}
77+
output-pdf:
78+
runs-on: ubuntu-latest
79+
strategy:
80+
matrix:
81+
version: ['3.8', '3.9', '3.10', '3.11']
82+
needs: ['build-translation']
83+
steps:
84+
- uses: actions/download-artifact@master
85+
with:
86+
name: build-${{ matrix.version }}-latex
87+
- run: sudo apt-get update
88+
- run: sudo apt-get install -y latexmk texlive-xetex fonts-freefont-otf xindy
89+
- run: make
90+
- uses: actions/upload-artifact@master
91+
with:
92+
name: build-${{ matrix.version }}-pdf
93+
path: .

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea/
2+
3+
venv/

.tx/config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[main]
2+
host = https://www.transifex.com

0 commit comments

Comments
 (0)