This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/main by this push:
new 81b13d6 Update check results when polling for tasks remaining
81b13d6 is described below
commit 81b13d68ad60c9fa7b6e83ef7cc3434200ad46ed
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Dec 29 16:07:52 2025 +0000
Update check results when polling for tasks remaining
---
atr/get/checks.py | 75 +++++++++++++++++++++++++++++++++
atr/static/js/src/ongoing-tasks-poll.js | 30 +++++++++++--
atr/templates/check-selected.html | 23 +++++-----
3 files changed, 115 insertions(+), 13 deletions(-)
diff --git a/atr/get/checks.py b/atr/get/checks.py
index 35b5585..6363b25 100644
--- a/atr/get/checks.py
+++ b/atr/get/checks.py
@@ -21,9 +21,12 @@ from typing import NamedTuple
import asfquart.base as base
import htpy
+import quart
import atr.blueprints.get as get
import atr.db as db
+import atr.db.interaction as interaction
+import atr.form as form
import atr.get.download as download
import atr.get.ignores as ignores
import atr.get.report as report
@@ -31,7 +34,9 @@ import atr.get.sbom as sbom
import atr.get.vote as vote
import atr.htm as htm
import atr.models.sql as sql
+import atr.post as post
import atr.shared as shared
+import atr.shared.draft as draft
import atr.storage as storage
import atr.template as template
import atr.util as util
@@ -130,6 +135,76 @@ async def selected(session: web.Committer | None,
project_name: str, version_nam
)
[email protected]("/checks/<project_name>/<version_name>/<revision_number>")
+async def selected_revision(
+ session: web.Committer,
+ project_name: str,
+ version_name: str,
+ revision_number: str,
+) -> web.QuartResponse:
+ """Return JSON with ongoing count and HTML fragments for dynamic
updates."""
+ async with db.session() as data:
+ release = await data.release(
+ project_name=project_name,
+ version=version_name,
+ _committee=True,
+ _project=True,
+ ).demand(base.ASFQuartException("Release does not exist",
errorcode=404))
+
+ base_path = util.release_directory(release)
+ paths = [path async for path in util.paths_recursive(base_path)]
+ paths.sort()
+
+ async with storage.read(session) as read:
+ ragp = read.as_general_public()
+ info = await ragp.releases.path_info(release, paths)
+
+ ongoing_count = await interaction.tasks_ongoing(project_name,
version_name, revision_number)
+
+ checks_summary_elem = shared._render_checks_summary(info, project_name,
version_name)
+ checks_summary_html = str(checks_summary_elem) if checks_summary_elem else
""
+
+ delete_file_forms: dict[str, str] = {}
+ if release.phase == sql.ReleasePhase.RELEASE_CANDIDATE_DRAFT:
+ for path in paths:
+ delete_file_forms[str(path)] = str(
+ form.render(
+ model_cls=draft.DeleteFileForm,
+ action=util.as_url(post.draft.delete_file,
project_name=project_name, version_name=version_name),
+ form_classes=".d-inline-block.m-0",
+ submit_classes="btn-sm btn-outline-danger",
+ submit_label="Delete",
+ empty=True,
+ defaults={"file_path": str(path)},
+ confirm=(
+ "Are you sure you want to delete this file? "
+ "This will also delete any associated metadata files. "
+ "This cannot be undone."
+ ),
+ )
+ )
+
+ files_table_html = await quart.render_template(
+ "check-selected-path-table.html",
+ paths=paths,
+ info=info,
+ project_name=project_name,
+ version_name=version_name,
+ release=release,
+ phase=release.phase.value,
+ delete_file_forms=delete_file_forms,
+ csrf_input=str(form.csrf_input()),
+ )
+
+ return quart.jsonify(
+ {
+ "ongoing": ongoing_count,
+ "checks_summary_html": checks_summary_html,
+ "files_table_html": files_table_html,
+ }
+ )
+
+
async def _compute_stats( # noqa: C901
release: sql.Release,
paths: list[pathlib.Path],
diff --git a/atr/static/js/src/ongoing-tasks-poll.js
b/atr/static/js/src/ongoing-tasks-poll.js
index ea86e65..f0b8f35 100644
--- a/atr/static/js/src/ongoing-tasks-poll.js
+++ b/atr/static/js/src/ongoing-tasks-poll.js
@@ -18,11 +18,13 @@
*/
(() => {
+ function handleCollapseToggle() {
+ this.textContent = this.textContent.trim() === "More" ? "Less"
: "More";
+ }
+
// Handle More and Less toggle buttons for collapse sections
document.querySelectorAll(".page-collapse-toggle").forEach((button) => {
- button.addEventListener("click", function () {
- this.textContent = this.textContent.trim() === "More" ?
"Less" : "More";
- });
+ button.addEventListener("click", handleCollapseToggle);
});
const banner = document.getElementById("ongoing-tasks-banner");
@@ -35,6 +37,10 @@
const textSpan = document.getElementById("ongoing-tasks-text");
const voteButton = document.getElementById("start-vote-button");
const progress = document.getElementById("poll-progress");
+ const checksSummaryContainer = document.getElementById(
+ "checks-summary-container",
+ );
+ const filesTableContainer =
document.getElementById("files-table-container");
const pollInterval = 3000;
let currentCount = parseInt(countSpan?.textContent || "0", 10);
@@ -110,6 +116,23 @@
voteButton.setAttribute("title", "Start a vote on this draft");
}
+ function updatePageContent(data) {
+ if (checksSummaryContainer && data.checks_summary_html !==
undefined) {
+ checksSummaryContainer.innerHTML =
data.checks_summary_html;
+ }
+ if (filesTableContainer && data.files_table_html !== undefined)
{
+ filesTableContainer.innerHTML = data.files_table_html;
+ reattachCollapseToggleListeners();
+ }
+ }
+
+ function reattachCollapseToggleListeners() {
+
document.querySelectorAll(".page-collapse-toggle").forEach((button) => {
+ button.removeEventListener("click",
handleCollapseToggle);
+ button.addEventListener("click", handleCollapseToggle);
+ });
+ }
+
function pollOngoingTasks() {
if (currentCount === 0) return;
@@ -125,6 +148,7 @@
if (newCount !== currentCount) {
updateBanner(newCount);
}
+ updatePageContent(data);
if (newCount > 0) {
restartProgress();
setTimeout(pollOngoingTasks,
pollInterval);
diff --git a/atr/templates/check-selected.html
b/atr/templates/check-selected.html
index a435da7..c8164f6 100644
--- a/atr/templates/check-selected.html
+++ b/atr/templates/check-selected.html
@@ -89,7 +89,7 @@
<div id="ongoing-tasks-banner"
class="alert alert-warning{% if ongoing_tasks_count == 0 %} d-none{%
endif %}"
role="alert"
- {% if revision_number %}data-api-url="/api/checks/ongoing/{{
release.project.name }}/{{ release.version }}/{{ revision_number }}"{% endif %}>
+ {% if revision_number %}data-api-url="/checks/{{ release.project.name
}}/{{ release.version }}/{{ revision_number }}"{% endif %}>
<i class="bi bi-exclamation-triangle me-2"></i>
<span id="ongoing-tasks-text">There {{ 'is' if ongoing_tasks_count == 1
else 'are' }} currently <strong id="ongoing-tasks-count">{{ ongoing_tasks_count
}}</strong> background verification {{ 'task' if ongoing_tasks_count == 1 else
'tasks' }} running for the latest revision. Results shown below may be
incomplete or outdated until the tasks finish.</span>
<div id="poll-progress-container" class="progress mt-2">
@@ -97,9 +97,11 @@
</div>
</div>
- {% if checks_summary_html %}
- {{ checks_summary_html|safe }}
- {% endif %}
+ <div id="checks-summary-container">
+ {% if checks_summary_html %}
+ {{ checks_summary_html|safe }}
+ {% endif %}
+ </div>
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
@@ -113,12 +115,13 @@
</h5>
</div>
<div class="card-body">
- {% if paths|length > 0 %}
- {% include "check-selected-path-table.html" %}
-
- {% else %}
- <div class="alert alert-info">This draft does not have any files
yet.</div>
- {% endif %}
+ <div id="files-table-container">
+ {% if paths|length > 0 %}
+ {% include "check-selected-path-table.html" %}
+ {% else %}
+ <div class="alert alert-info">This draft does not have any files
yet.</div>
+ {% endif %}
+ </div>
</div>
</div>
{% if phase == "release_candidate_draft" %}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]