Skip to content

Commit 930e0af

Browse files
authored
Core tracking (#162)
Closes #140. Presenting both core and overall progress. Order by core first, overall second. (React translations page has the same behaviour.) Updated jQuery to 4.0.0 Updated Bootstrap to 5.3.8
1 parent 50a6867 commit 930e0af

File tree

7 files changed

+148
-41
lines changed

7 files changed

+148
-41
lines changed

completion.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import git
77
import urllib3
88
from potodo import potodo
9+
from potodo.arguments_handling import Filters
910

1011

1112
@cache
@@ -19,7 +20,9 @@ def branches_from_peps() -> list[str]:
1920
]
2021

2122

22-
def get_completion(clones_dir: str, repo: str) -> tuple[float, str, float]:
23+
def get_completion(
24+
clones_dir: str, repo: str
25+
) -> tuple[float, float, str, float, float]:
2326
clone_path = Path(clones_dir, 'translations', repo)
2427
for branch in branches_from_peps() + ['master', 'main']:
2528
try:
@@ -39,12 +42,18 @@ def get_completion(clones_dir: str, repo: str) -> tuple[float, str, float]:
3942
print(f'success: {branch} {repo}: clone or switch')
4043
break
4144
path_for_merge = Path(clones_dir, 'rebased_translations', repo)
42-
completion = potodo.merge_and_scan_paths(
45+
project = potodo.merge_and_scan_paths(
4346
[clone_path],
4447
pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'),
45-
merge_path=path_for_merge,
48+
merge_path=path_for_merge.absolute(),
4649
api_url='',
47-
).completion
50+
)
51+
completion = project.completion
52+
core_excludes = ['**/*', '!bugs.po', '!tutorial/*', '!library/functions.po']
53+
project.filter(
54+
filters=Filters(False, True, 0, 100, False, False), exclude=core_excludes
55+
)
56+
core_completion = project.completion
4857

4958
if completion:
5059
# Fetch commit from before 30 days ago and checkout
@@ -54,19 +63,28 @@ def get_completion(clones_dir: str, repo: str) -> tuple[float, str, float]:
5463
)
5564
except StopIteration:
5665
month_ago_completion = 0.0
66+
month_ago_core_completion = 0.0
5767
else:
5868
clone_repo.git.checkout(commit.hexsha)
5969
with TemporaryDirectory() as tmpdir:
60-
month_ago_completion = potodo.merge_and_scan_paths(
70+
project = potodo.merge_and_scan_paths(
6171
[clone_path],
6272
pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'),
6373
merge_path=Path(tmpdir),
6474
api_url='',
65-
).completion
75+
)
76+
month_ago_completion = project.completion
77+
project.filter(
78+
filters=Filters(False, True, 0, 100, False, False),
79+
exclude=core_excludes,
80+
)
81+
month_ago_core_completion = project.completion
6682
clone_repo.git.checkout(branch) # restore the original state
6783
else:
6884
month_ago_completion = 0.0
85+
month_ago_core_completion = 0.0
6986

7087
change = completion - month_ago_completion
88+
core_change = core_completion - month_ago_core_completion
7189

72-
return completion, branch, change
90+
return core_completion, completion, branch, core_change, change

generate.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,21 @@ def get_project_data(
6767
) -> LanguageProjectData:
6868
built = language.code in languages_built
6969
if repo:
70-
completion, branch, change = get_completion(clones_dir, repo)
70+
core_complation, completion, branch, core_change, change = get_completion(
71+
clones_dir, repo
72+
)
7173
else:
72-
completion = 0.0
73-
change = 0.0
74+
core_complation = completion = 0.0
75+
core_change = change = 0.0
7476
branch = ''
7577

7678
return LanguageProjectData(
7779
language,
7880
repo,
7981
branch,
82+
core_complation,
8083
completion,
84+
core_change,
8185
change,
8286
built,
8387
translated_name=languages_built.get(language.code, ''),
@@ -90,7 +94,9 @@ class LanguageProjectData:
9094
language: Language
9195
repository: str | None
9296
branch: str
97+
core_completion: float
9398
completion: float
99+
core_change: float
94100
change: float
95101
built: bool
96102
translated_name: str

src/style.css

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,21 +105,25 @@ ul.links-row li:not(:first-child)::before {
105105

106106
/* ------------------------------ Index ------------------------------------- */
107107

108-
.progress-bar-container {
109-
border-radius: 4px;
110-
border: 1px solid rgba(0, 0, 0, 0.2);
108+
.progress {
109+
font-size: 1rem;
111110
height: 20px;
112-
overflow: hidden;
113-
position: relative;
114111
}
115112

116-
.progress-bar {
117-
display: inline-block;
118-
color: white;
119-
height: 100%;
120-
line-height: 20px;
121-
border-top-left-radius: 3px;
122-
border-bottom-left-radius: 3px;
113+
.outer-label {
114+
display: none;
115+
padding-left: .5em;
116+
color: var(--text-color);
117+
background-color: transparent;
118+
}
119+
120+
.progress-bar.low {
121+
color: transparent;
122+
user-select: none;
123+
}
124+
125+
.progress-bar.low + .outer-label {
126+
display: flex;
123127
}
124128

125129
/* ------------------------------ Metadata ---------------------------------- */

templates/base.html.jinja

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88

99
<title>Python Docs Translation Dashboard</title>
1010

11-
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.0/css/bootstrap.min.css" rel="stylesheet">
11+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
12+
rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
13+
crossorigin="anonymous">
1214
<link href="style.css" rel="stylesheet">
1315
</head>
1416

1517
<body>
1618
<header>
1719
<nav class="navbar navbar-expand-md fixed-top">
18-
20+
<div class="container-fluid">
1921
<div class="navbar-brand">
2022
<a href="./">
2123
<img src="logo.png" style="height: 2rem;" alt="Python logo">
@@ -24,7 +26,7 @@
2426
</div>
2527

2628
<div class="navbar-light bg-light">
27-
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
29+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
2830
<span class="navbar-toggler-icon"></span>
2931
</button>
3032
</div>
@@ -51,6 +53,7 @@
5153
</li>
5254
</ul>
5355
</div>
56+
</div>
5457
</nav>
5558
</header>
5659

@@ -72,10 +75,14 @@
7275
window.addEventListener('resize', padnavbar);
7376
</script>
7477

75-
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
76-
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
78+
<script src="https://code.jquery.com/jquery-4.0.0.slim.min.js"
79+
integrity="sha256-8DGpv13HIm+5iDNWw1XqxgFB4mj+yOKFNb+tHBZOowc="
7780
crossorigin="anonymous">
7881
</script>
79-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
80-
82+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
83+
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
84+
crossorigin="anonymous">
85+
</script>
86+
{% block extrascript %}
87+
{% endblock %}
8188
</html>

templates/index.html.jinja

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
{% block main %}
44
<div>
55
<div class="row">
6-
{% for project in completion_progress | sort(attribute='completion') | reverse %}
6+
{% for project in completion_progress | sort(attribute='core_completion,completion') | reverse %}
77
<div class="col-12 col-sm-6 col-md-4 d-flex">
88
<div id="{{ project.language.code }}" class="card shadow mb-3 w-100">
99
<div class="card-body">
1010
<h3 class="card-title"><a href="#{{ project.language.code }}">{{ project.language.name }}</a></h3>
1111
<h5 class="card-subtitle mb-2 text-muted">{{ project.translated_name }}</h5>
12-
<p class="text-muted">Completion: <strong>{{ '{:.2f}%'.format(project.completion) }}</strong></p>
13-
<p class="text-muted">30-day progress: {{ '{:.2f}%'.format(project.change) }}</p>
1412

1513
<ul class="links-row">
1614
{% if project.built %}
@@ -25,15 +23,14 @@
2523
</a>
2624
</li>
2725
</ul>
28-
<div class="progress-bar-container">
29-
<div class="progress-bar" style="width: {{ project.completion }}%;
30-
{% if project.change %}
31-
background: linear-gradient(to left, #94cf96 {{ project.change * 100 / project.completion }}%, #4caf50 {{ project.change * 100 / project.completion }}%);
32-
{% else %}
33-
background-color: #4caf50;
34-
{% endif %}">
35-
</div>
36-
</div>
26+
{# core progress bar #}
27+
{% with width=project.core_completion, change=project.core_change, kind='core' %}
28+
{% include 'progress_bar.html.jinja' %}
29+
{% endwith %}
30+
{# overall progress bar #}
31+
{% with width=project.completion, change=project.change, kind='overall', extra_container_class='mt-1' %}
32+
{% include 'progress_bar.html.jinja' %}
33+
{% endwith %}
3734
</div>
3835
</div>
3936
</div>
@@ -47,3 +44,23 @@
4744
You can download the data on this page in <a href="https://raw.githubusercontent.com/python-docs-translations/dashboard/refs/heads/gh-pages/index.json">JSON format</a>.
4845
</p>
4946
{% endblock %}
47+
{% block extrascript %}
48+
<script>
49+
function updateProgressBarVisibility() {
50+
document.querySelectorAll('.main-bar').forEach(progressBar => {
51+
const barWithOverflowWidth = progressBar.scrollWidth;
52+
const barWidth = progressBar.clientWidth;
53+
54+
if (barWidth < barWithOverflowWidth) {
55+
progressBar.classList.add('low');
56+
} else {
57+
progressBar.classList.remove('low');
58+
}
59+
});
60+
}
61+
62+
updateProgressBarVisibility();
63+
64+
window.addEventListener('resize', updateProgressBarVisibility);
65+
</script>
66+
{% endblock %}

templates/progress_bar.html.jinja

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{# Reusable progress bar partial
2+
Expects variables in the include call:
3+
- width: numeric width percentage (0-100)
4+
- change: numeric change value (same units as width) or falsy
5+
#}
6+
<div class="progress {{ extra_container_class }}">
7+
<div class="progress-bar main-bar" style="width: {{ width }}%;
8+
{% if change and width %}
9+
{# compute the relative change percentage safely #}
10+
{% set rel = (change * 100 / width) %}
11+
background: linear-gradient(to left, #94cf96 {{ rel }}%, #4caf50 {{ rel }}%);
12+
{% else %}
13+
background-color: #4caf50;
14+
{% endif %}">
15+
{{ kind }}: {{ '{:.2f}%'.format(width) }} {% if change >= 0.01 %}({{ '{:+.2f}%'.format(change) }}){% endif %}
16+
</div>
17+
<div class="progress-bar outer-label">
18+
{{ kind }}: {{ '{:.2f}%'.format(width) }} {% if change >= 0.01 %}({{ '{:+.2f}%'.format(change) }}){% endif %}
19+
</div>
20+
</div>

tests/test_index.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import unittest
2+
from datetime import datetime
3+
import support
4+
5+
from jinja2 import Environment, FileSystemLoader
6+
7+
with support.import_scripts():
8+
import generate
9+
import repositories
10+
11+
12+
class testIndex(unittest.TestCase):
13+
def test_renders(self):
14+
env = Environment(loader=FileSystemLoader('templates'))
15+
language_project_data = generate.LanguageProjectData(
16+
language=repositories.Language('pl', 'Polish'),
17+
repository='python-docs-pl',
18+
branch='3.14',
19+
core_completion=100,
20+
completion=50,
21+
core_change=1,
22+
change=2,
23+
built=True,
24+
translated_name='Polish',
25+
contribution_link='https://example.com',
26+
)
27+
env.get_template('index.html.jinja').render(
28+
completion_progress=[language_project_data],
29+
generation_time=datetime.now(),
30+
duration=100,
31+
)
32+
33+
34+
if __name__ == '__main__':
35+
unittest.main()

0 commit comments

Comments
 (0)