diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 043d312a8..4e536439d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -38,7 +38,7 @@ repos:
rev: v1.14.1
hooks:
- id: mypy
- additional_dependencies: [types-docutils, types-polib, types-requests]
+ additional_dependencies: [types-docutils, types-polib>=1.2.0.20250114, types-requests]
ci:
autoupdate_schedule: quarterly
diff --git a/contribute.py b/contribute.py
new file mode 100644
index 000000000..cc6b6f260
--- /dev/null
+++ b/contribute.py
@@ -0,0 +1,33 @@
+pulling_from_transifex = ('zh-cn', 'pt-br', 'ja', 'uk', 'pl')
+
+custom_contributing_links = {
+ 'es': 'https://python-docs-es.readthedocs.io/page/CONTRIBUTING.html',
+ 'ko': 'https://www.flowdas.com/pages/python-docs-ko.html',
+ 'zh-tw': 'https://github.com/python/python-docs-zh-tw/blob/3.13/README.rst#%E5%8F%83%E8%88%87%E7%BF%BB%E8%AD%AF',
+ 'fr': 'https://git.afpy.org/AFPy/python-docs-fr/src/branch/3.13/CONTRIBUTING.rst',
+ 'id': 'https://github.com/python/python-docs-id/blob/master/README.md#berkontribusi-untuk-menerjemahkan',
+ 'tr': 'https://github.com/python/python-docs-tr/blob/3.12/README.md#%C3%A7eviriye-katk%C4%B1da-bulunmak',
+ 'gr': 'https://github.com/pygreece/python-docs-gr/blob/3.12/CONTRIBUTING.md',
+}
+
+
+def get_contrib_link(language: str, repo: str | None) -> str | None:
+ return (
+ custom_contributing_links.get(language)
+ or (
+ language in pulling_from_transifex
+ and 'https://explore.transifex.com/python-doc/python-newest/'
+ )
+ or (repo and f'https://github.com/{repo}')
+ )
+
+
+if __name__ == '__main__':
+ for code, repo in (
+ ('en', None),
+ ('pl', None),
+ ('ar', 'python/python-docs-ar'),
+ ('zh-cn', None),
+ ('id', None),
+ ):
+ print(f'{code}: {get_contrib_link(code, repo)}')
diff --git a/generate.py b/generate.py
index 730b9050b..94f470c69 100644
--- a/generate.py
+++ b/generate.py
@@ -13,11 +13,12 @@
from datetime import datetime, timezone
from pathlib import Path
from tempfile import TemporaryDirectory
-from typing import Literal, cast
+from typing import cast, Literal
from git import Repo
from jinja2 import Template
+import contribute
import repositories
import build_status
import visitors
@@ -27,7 +28,21 @@
def get_completion_progress() -> (
- Iterator[tuple[str, str, float, int, str | Literal[False], int, bool, bool | None]]
+ Iterator[
+ tuple[
+ str,
+ str,
+ str,
+ float,
+ int,
+ str | Literal[False],
+ int,
+ bool,
+ bool | None,
+ bool,
+ str | None,
+ ]
+ ]
):
with TemporaryDirectory() as clones_dir:
Repo.clone_from(
@@ -49,16 +64,31 @@ def get_completion_progress() -> (
['make', '-C', Path(clones_dir, 'cpython/Doc'), 'gettext'], check=True
)
languages_built = dict(build_status.get_languages())
- for lang, repo in repositories.get_languages_and_repos(devguide_dir):
+ for lang, lang_name, repo in repositories.get_languages_and_repos(devguide_dir):
built = lang in languages_built
in_switcher = languages_built.get(lang)
+ tx = lang in contribute.pulling_from_transifex
+ contrib_link = contribute.get_contrib_link(lang, repo)
if not repo:
- yield lang, cast(str, repo), 0.0, 0, False, 0, built, in_switcher
+ yield (
+ lang,
+ lang_name,
+ cast(str, repo),
+ 0.0,
+ 0,
+ False,
+ 0,
+ built,
+ in_switcher,
+ False,
+ None,
+ )
continue
completion, translators, translators_link = get_completion(clones_dir, repo)
visitors_num = visitors.get_number_of_visitors(lang) if built else 0
yield (
lang,
+ lang_name,
repo,
completion,
translators,
@@ -66,6 +96,8 @@ def get_completion_progress() -> (
visitors_num,
built,
in_switcher,
+ tx,
+ contrib_link,
)
diff --git a/repositories.py b/repositories.py
index 2ab70ec32..9ade1d2c7 100644
--- a/repositories.py
+++ b/repositories.py
@@ -1,12 +1,16 @@
import re
from collections.abc import Iterator
from pathlib import Path
+from tempfile import TemporaryDirectory
from docutils import core
from docutils.nodes import table, row
+from git import Repo
-def get_languages_and_repos(devguide_dir: Path) -> Iterator[tuple[str, str | None]]:
+def get_languages_and_repos(
+ devguide_dir: Path,
+) -> Iterator[tuple[str, str, str | None]]:
translating = devguide_dir.joinpath('documentation/translating.rst').read_text()
doctree = core.publish_doctree(translating)
@@ -14,11 +18,19 @@ def get_languages_and_repos(devguide_dir: Path) -> Iterator[tuple[str, str | Non
for row_node in node.traverse(row)[1:]:
language = row_node[0].astext()
repo = row_node[2].astext()
- language_match = re.match(r'.* \((.*)\)', language)
+ language_match = re.match(r'(.*) \((.*)\)', language)
if not language_match:
raise ValueError(
f'Expected a language code in brackets in devguide table, found {language}'
)
- language_code = language_match.group(1).lower().replace('_', '-')
+ language_name = language_match.group(1)
+ language_code = language_match.group(2).lower().replace('_', '-')
repo_match = re.match(':github:`GitHub <(.*)>`', repo)
- yield language_code, repo_match and repo_match.group(1)
+ yield language_code, language_name, repo_match and repo_match.group(1)
+
+
+if __name__ == '__main__':
+ with TemporaryDirectory() as directory:
+ Repo.clone_from('https://github.com/python/devguide.git', directory, depth=1)
+ for item in get_languages_and_repos(Path(directory)):
+ print(item)
diff --git a/template.html.jinja b/template.html.jinja
index 0ef469911..f88fe363f 100644
--- a/template.html.jinja
+++ b/template.html.jinja
@@ -9,6 +9,7 @@
language
+ contribute
build
visitors
translators
@@ -16,17 +17,14 @@