From 0a14a6baec87883bfb129220f0fec631acc3bc18 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Mon, 10 Nov 2025 21:39:16 +0100 Subject: [PATCH 01/20] try to filter --- completion.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/completion.py b/completion.py index e8484e34e..95a481dc5 100644 --- a/completion.py +++ b/completion.py @@ -33,12 +33,14 @@ def get_completion(clones_dir: str, repo: str) -> tuple[float, str, float]: else: break path_for_merge = Path(clones_dir, 'rebased_translations', repo) - completion = potodo.merge_and_scan_paths( + project = potodo.merge_and_scan_paths( [clone_path], pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'), merge_path=path_for_merge, api_url='', - ).completion + ) + completion = project.completion + project.filter(lambda file: file.path in (Path('bugs.po'), Path('tutorial'))) if completion: # Fetch commit from before 30 days ago and checkout From 74eda6b4398bd99e72fc67d8177593635116dbee Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Sun, 30 Nov 2025 05:04:01 +0100 Subject: [PATCH 02/20] Add core completion data in the backend script --- completion.py | 25 ++++++++++++++++++++----- generate.py | 12 +++++++++--- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/completion.py b/completion.py index 95a481dc5..53c5af845 100644 --- a/completion.py +++ b/completion.py @@ -6,6 +6,7 @@ import git import urllib3 from potodo import potodo +from potodo.arguments_handling import Filters @cache @@ -19,7 +20,9 @@ def branches_from_peps() -> list[str]: ] -def get_completion(clones_dir: str, repo: str) -> tuple[float, str, float]: +def get_completion( + clones_dir: str, repo: str +) -> tuple[float, float, str, float, float]: clone_path = Path(clones_dir, 'translations', repo) for branch in branches_from_peps() + ['master', 'main']: try: @@ -40,7 +43,11 @@ def get_completion(clones_dir: str, repo: str) -> tuple[float, str, float]: api_url='', ) completion = project.completion - project.filter(lambda file: file.path in (Path('bugs.po'), Path('tutorial'))) + project.filter( + filters=Filters(False, True, 0, 100, False, False), + exclude=['**/*', '!bugs.po', '!tutorial/', '!library/functions.po'], + ) + core_completion = project.completion if completion: # Fetch commit from before 30 days ago and checkout @@ -53,16 +60,24 @@ def get_completion(clones_dir: str, repo: str) -> tuple[float, str, float]: else: clone_repo.git.checkout(commit.hexsha) with TemporaryDirectory() as tmpdir: - month_ago_completion = potodo.merge_and_scan_paths( + project = potodo.merge_and_scan_paths( [clone_path], pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'), merge_path=Path(tmpdir), api_url='', - ).completion + ) + month_ago_completion = project.completion + project.filter( + filters=Filters(False, True, 0, 100, False, False), + exclude=['**/*', '!bugs.po', '!tutorial/', '!library/functions.po'], + ) + month_ago_core_completion = project.completion clone_repo.git.checkout(branch) # restore the original state else: month_ago_completion = 0.0 + month_ago_core_completion = 0.0 change = completion - month_ago_completion + core_change = core_completion - month_ago_core_completion - return completion, branch, change + return core_completion, completion, branch, core_change, change diff --git a/generate.py b/generate.py index 2a8292b56..5f345013a 100644 --- a/generate.py +++ b/generate.py @@ -59,17 +59,21 @@ def get_project_data( ) -> 'LanguageProjectData': built = language.code in languages_built if repo: - completion, branch, change = get_completion(clones_dir, repo) + core_complation, completion, branch, core_change, change = get_completion( + clones_dir, repo + ) else: - completion = 0.0 - change = 0.0 + core_complation = completion = 0.0 + core_change = change = 0.0 branch = '' return LanguageProjectData( language, repo, branch, + core_complation, completion, + core_change, change, built, translated_name=languages_built.get(language.code, ''), @@ -83,7 +87,9 @@ class LanguageProjectData: language: Language repository: str | None branch: str + core_completion: float completion: float + core_change: float change: float built: bool translated_name: str From c4e89fa66fc106b1b3f22b8c3742a111ef004e66 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Tue, 10 Feb 2026 23:41:59 +0100 Subject: [PATCH 03/20] Resolve clone path to absolute to avoid ValueError https://git.afpy.org/AFPy/potodo/issues/35 --- completion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completion.py b/completion.py index 53c5af845..aef4da589 100644 --- a/completion.py +++ b/completion.py @@ -37,7 +37,7 @@ def get_completion( break path_for_merge = Path(clones_dir, 'rebased_translations', repo) project = potodo.merge_and_scan_paths( - [clone_path], + [clone_path.resolve()], pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'), merge_path=path_for_merge, api_url='', From 2e441441985f8f1ad4263f3ed7bba9a8563a4c74 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Wed, 11 Feb 2026 00:02:55 +0100 Subject: [PATCH 04/20] Resolve merge path to absolute to avoid ValueError https://git.afpy.org/AFPy/potodo/issues/35 --- completion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/completion.py b/completion.py index 2702e3651..577254148 100644 --- a/completion.py +++ b/completion.py @@ -43,9 +43,9 @@ def get_completion( break path_for_merge = Path(clones_dir, 'rebased_translations', repo) project = potodo.merge_and_scan_paths( - [clone_path.resolve()], + [clone_path], pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'), - merge_path=path_for_merge, + merge_path=path_for_merge.resolve(), api_url='', ) completion = project.completion From e253a66469fc4010f6cc2f11965c730d1a9c5df5 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Wed, 11 Feb 2026 00:26:59 +0100 Subject: [PATCH 05/20] Replace resolve with absolute --- completion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completion.py b/completion.py index 577254148..2cb5e50ec 100644 --- a/completion.py +++ b/completion.py @@ -45,7 +45,7 @@ def get_completion( project = potodo.merge_and_scan_paths( [clone_path], pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'), - merge_path=path_for_merge.resolve(), + merge_path=path_for_merge.absolute(), api_url='', ) completion = project.completion From 0e4722389781734550de43771e0999f7d354b586 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Wed, 11 Feb 2026 00:27:26 +0100 Subject: [PATCH 06/20] Add rudimentary core tracker --- templates/index.html.jinja | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/templates/index.html.jinja b/templates/index.html.jinja index 3ce7b55a9..be3a455c2 100644 --- a/templates/index.html.jinja +++ b/templates/index.html.jinja @@ -25,6 +25,15 @@ +
+
+
+
- {% for project in completion_progress | sort(attribute='completion') | reverse %} + {% for project in completion_progress | sort(attribute='core_completion,completion') | reverse %}
From 1d13c81121f0dcf88654ff75812e97099e7b5b60 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Wed, 11 Feb 2026 17:05:35 +0100 Subject: [PATCH 08/20] Add top margin for second progress bar --- templates/index.html.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/index.html.jinja b/templates/index.html.jinja index 40772dd48..eeeb581c5 100644 --- a/templates/index.html.jinja +++ b/templates/index.html.jinja @@ -34,7 +34,7 @@ {% endif %}">
-
+
-
-
-
-
-
-
-
+ {# core progress bar #} + {% set width, change = project.core_completion, project.core_change %} + {% include 'progress_bar.html.jinja' %} + {# overall progress bar #} + {% set width, change = project.completion, project.change %} + {% set extra_container_class = 'mt-1' %} + {% include 'progress_bar.html.jinja' %}
diff --git a/templates/progress_bar.html.jinja b/templates/progress_bar.html.jinja new file mode 100644 index 000000000..272708f2d --- /dev/null +++ b/templates/progress_bar.html.jinja @@ -0,0 +1,16 @@ +{# Reusable progress bar partial + Expects variables in the include call: + - width: numeric width percentage (0-100) + - change: numeric change value (same units as width) or falsy +#} +
+
+
+
diff --git a/tests/test_index.py b/tests/test_index.py new file mode 100644 index 000000000..a1dbdcddb --- /dev/null +++ b/tests/test_index.py @@ -0,0 +1,35 @@ +import unittest +from datetime import datetime +import support + +from jinja2 import Environment, FileSystemLoader + +with support.import_scripts(): + import generate + import repositories + + +class testIndex(unittest.TestCase): + def test_renders(self): + env = Environment(loader=FileSystemLoader('templates')) + language_project_data = generate.LanguageProjectData( + language=repositories.Language('pl', 'Polish'), + repository='python-docs-pl', + branch='3.14', + core_completion=100, + completion=50, + core_change=1, + change=2, + built=True, + translated_name='Polish', + contribution_link='https://example.com', + ) + env.get_template('index.html.jinja').render( + completion_progress=[language_project_data], + generation_time=datetime.now(), + duration=100, + ) + + +if __name__ == '__main__': + unittest.main() From e50d599c31c0783da7a6b2398675009843ea9807 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Wed, 11 Feb 2026 22:50:14 +0100 Subject: [PATCH 11/20] Display label on the progress bar --- templates/index.html.jinja | 6 ++---- templates/progress_bar.html.jinja | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/templates/index.html.jinja b/templates/index.html.jinja index 7bb1f185d..2771c6389 100644 --- a/templates/index.html.jinja +++ b/templates/index.html.jinja @@ -9,8 +9,6 @@

{{ project.language.name }}

{{ project.translated_name }}
-

Completion: {{ '{:.2f}%'.format(project.completion) }}

-

30-day progress: {{ '{:.2f}%'.format(project.change) }}

{# core progress bar #} - {% set width, change = project.core_completion, project.core_change %} + {% set width, change, kind = project.core_completion, project.core_change, 'core' %} {% include 'progress_bar.html.jinja' %} {# overall progress bar #} - {% set width, change = project.completion, project.change %} + {% set width, change, kind = project.completion, project.change, 'overall' %} {% set extra_container_class = 'mt-1' %} {% include 'progress_bar.html.jinja' %}
diff --git a/templates/progress_bar.html.jinja b/templates/progress_bar.html.jinja index 272708f2d..78e78e333 100644 --- a/templates/progress_bar.html.jinja +++ b/templates/progress_bar.html.jinja @@ -12,5 +12,6 @@ {% else %} background-color: #4caf50; {% endif %}"> + {{ kind }}: {{ '{:.2f}%'.format(project.completion) }} {% if project.change >= 0.01 %}({{ '{:+.2f}%'.format(project.change) }}){% endif %}
From dce1f8d334261e189b7eacfab798bd7eb311b67a Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Wed, 11 Feb 2026 23:14:26 +0100 Subject: [PATCH 12/20] Use Bootstrap's progress bar styling --- src/style.css | 19 ------------------- templates/progress_bar.html.jinja | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/style.css b/src/style.css index 2c38d6e1e..ad8f06fa0 100644 --- a/src/style.css +++ b/src/style.css @@ -103,25 +103,6 @@ ul.links-row li:not(:first-child)::before { margin-right: 0.5ch; } -/* ------------------------------ Index ------------------------------------- */ - -.progress-bar-container { - border-radius: 4px; - border: 1px solid rgba(0, 0, 0, 0.2); - height: 20px; - overflow: hidden; - position: relative; -} - -.progress-bar { - display: inline-block; - color: white; - height: 100%; - line-height: 20px; - border-top-left-radius: 3px; - border-bottom-left-radius: 3px; -} - /* ------------------------------ Metadata ---------------------------------- */ table { diff --git a/templates/progress_bar.html.jinja b/templates/progress_bar.html.jinja index 78e78e333..cb08d24bd 100644 --- a/templates/progress_bar.html.jinja +++ b/templates/progress_bar.html.jinja @@ -3,7 +3,7 @@ - width: numeric width percentage (0-100) - change: numeric change value (same units as width) or falsy #} -
+
- {{ kind }}: {{ '{:.2f}%'.format(project.completion) }} {% if project.change >= 0.01 %}({{ '{:+.2f}%'.format(project.change) }}){% endif %} + {{ kind }}: {{ '{:.2f}%'.format(width) }} {% if change >= 0.01 %}({{ '{:+.2f}%'.format(change) }}){% endif %}
From 3c6750bbcb41d243b9911cca07e95be047753433 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Thu, 12 Feb 2026 21:43:53 +0100 Subject: [PATCH 16/20] Upgrade jQuery and Bootstrap --- templates/base.html.jinja | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/templates/base.html.jinja b/templates/base.html.jinja index 7f271c110..7b72722ad 100644 --- a/templates/base.html.jinja +++ b/templates/base.html.jinja @@ -8,7 +8,9 @@ Python Docs Translation Dashboard - + @@ -72,10 +74,12 @@ window.addEventListener('resize', padnavbar); - + - - From 2ed1f09fe354678ae6799aa4a4e05dd05f6d7a6a Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Thu, 12 Feb 2026 21:44:14 +0100 Subject: [PATCH 17/20] Add outer label and styling --- src/style.css | 16 ++++++++++++++++ templates/progress_bar.html.jinja | 3 +++ 2 files changed, 19 insertions(+) diff --git a/src/style.css b/src/style.css index 0cdd52974..14bd515f5 100644 --- a/src/style.css +++ b/src/style.css @@ -110,6 +110,22 @@ ul.links-row li:not(:first-child)::before { height: 20px; } +.outer-label { + display: none; + padding-left: .5em; + color: var(--text-color); + background-color: transparent; +} + +.progress-bar.low { + color: transparent; + user-select: none; +} + +.progress-bar.low + .outer-label { + display: flex; +} + /* ------------------------------ Metadata ---------------------------------- */ table { diff --git a/templates/progress_bar.html.jinja b/templates/progress_bar.html.jinja index 5b320045a..a6ff45d4a 100644 --- a/templates/progress_bar.html.jinja +++ b/templates/progress_bar.html.jinja @@ -14,4 +14,7 @@ {% endif %}"> {{ kind }}: {{ '{:.2f}%'.format(width) }} {% if change >= 0.01 %}({{ '{:+.2f}%'.format(change) }}){% endif %}
+
+ {{ kind }}: {{ '{:.2f}%'.format(width) }} {% if change >= 0.01 %}({{ '{:+.2f}%'.format(change) }}){% endif %} +
From 5511b60216561de04b10a369ae8b38b9be2d6673 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Thu, 12 Feb 2026 21:48:43 +0100 Subject: [PATCH 18/20] Add script for calculating width --- templates/base.html.jinja | 2 ++ templates/index.html.jinja | 20 ++++++++++++++++++++ templates/progress_bar.html.jinja | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/templates/base.html.jinja b/templates/base.html.jinja index 7b72722ad..718c99365 100644 --- a/templates/base.html.jinja +++ b/templates/base.html.jinja @@ -82,4 +82,6 @@ integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"> +{% block extrascript %} +{% endblock %} diff --git a/templates/index.html.jinja b/templates/index.html.jinja index 84cf0b483..790318006 100644 --- a/templates/index.html.jinja +++ b/templates/index.html.jinja @@ -44,3 +44,23 @@ You can download the data on this page in JSON format.

{% endblock %} +{% block extrascript %} + +{% endblock %} diff --git a/templates/progress_bar.html.jinja b/templates/progress_bar.html.jinja index a6ff45d4a..a24a2e96d 100644 --- a/templates/progress_bar.html.jinja +++ b/templates/progress_bar.html.jinja @@ -4,7 +4,7 @@ - change: numeric change value (same units as width) or falsy #}