This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch sbp
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/sbp by this push:
new 473002ea Show how long is left in a vote and when it ends
473002ea is described below
commit 473002ea8579b4119d6516fec6a93fc6d6e5f8b5
Author: Sean B. Palmer <[email protected]>
AuthorDate: Thu Mar 26 15:07:59 2026 +0000
Show how long is left in a vote and when it ends
---
atr/get/vote.py | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/atr/get/vote.py b/atr/get/vote.py
index d527c239..de70497e 100644
--- a/atr/get/vote.py
+++ b/atr/get/vote.py
@@ -17,6 +17,7 @@
from __future__ import annotations
+import datetime
import enum
import urllib.parse
from typing import TYPE_CHECKING, Literal
@@ -116,7 +117,7 @@ async def render_options_page(
archive_url = await _get_archive_url(release, session, latest_vote_task)
page = htm.Block()
- _render_header(page, release, show_resolve_section)
+ _render_header(page, release, show_resolve_section, latest_vote_task)
_render_section_download(page, release, session, user_category)
_render_section_checks(page, release, file_totals)
await _render_section_vote(page, release, session, user_category,
archive_url)
@@ -277,6 +278,29 @@ def _download_zip(release: sql.Release) -> htm.Element:
]
+def _format_vote_end(vote_end: datetime.datetime) -> str:
+ now = datetime.datetime.now(datetime.UTC)
+ timestamp = vote_end.strftime("%a %Y-%m-%d at %H:%M UTC")
+
+ remaining = vote_end - now
+ total_seconds = int(remaining.total_seconds())
+ if total_seconds <= 0:
+ return f"The vote ended on {timestamp}."
+
+ days = total_seconds // 86400
+ hours = (total_seconds % 86400) // 3600
+ minutes = (total_seconds % 3600) // 60
+
+ parts: list[str] = []
+ if days > 0:
+ parts.append(f"{days}d")
+ if (days > 0) or (hours > 0):
+ parts.append(f"{hours}h")
+ parts.append(f"{minutes}m")
+
+ return f"The vote ends in {' '.join(parts)}, on {timestamp}."
+
+
async def _get_archive_url(
release: sql.Release, session: web.Committer | None, latest_vote_task:
sql.Task | None
) -> str | None:
@@ -314,7 +338,9 @@ def _render_checklist_card(page: htm.Block, release:
sql.Release) -> None:
page.append(card.collect())
-def _render_header(page: htm.Block, release: sql.Release,
show_resolve_section: bool) -> None:
+def _render_header(
+ page: htm.Block, release: sql.Release, show_resolve_section: bool,
latest_vote_task: sql.Task | None
+) -> None:
render.html_nav(
page,
back_url=util.as_url(root.index),
@@ -339,6 +365,10 @@ def _render_header(page: htm.Block, release: sql.Release,
show_resolve_section:
f" {release.project.display_name} {release.version}.",
]
+ vote_end = interaction.vote_end_get(latest_vote_task)
+ if vote_end is not None:
+ page.p[_format_vote_end(vote_end)]
+
page.p["To participate in this vote, please select your next step:"]
steps = htm.Block(htpy.ol, classes=".atr-steps")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]