fix: silent pipeline log and server indexing progress

Three issues caused the Logs view to appear blank during a real pipeline run:

1. `from run import step_fetch, step_link` was outside the worker's
   try/except/finally. An import failure silently killed the thread,
   leaving _pipeline_done uncalled and the Run button stuck disabled
   forever. Now wrapped in its own try/except that posts the error to
   the log and resets the UI.

2. `build_server_index` makes N sequential HTTP requests (one per mod
   folder's meta.cpp) with no output during the scan. Added an optional
   `progress_fn(current, total, name)` callback; step_fetch wires it to
   print progress every 25 folders so the log never goes silent.

3. No immediate feedback after clicking Start — the log was blank until
   the worker thread started printing. Now posts a "Pipeline started"
   banner from the main thread before the worker launches.
This commit is contained in:
Tran G. (Revernomad) Khoa
2026-04-08 23:35:26 +07:00
parent e0c2dfb32a
commit 3276f4b63f
5 changed files with 38 additions and 5 deletions

View File

@@ -81,7 +81,11 @@ def make_session(auth: tuple[str, str]) -> requests.Session:
return s
def build_server_index(base_url: str, auth: tuple[str, str]) -> dict:
def build_server_index(
base_url: str,
auth: tuple[str, str],
progress_fn: "Callable[[int, int, str], None] | None" = None,
) -> dict:
"""
Scan the root of the file server and build mod lookup maps.
@@ -90,6 +94,9 @@ def build_server_index(base_url: str, auth: tuple[str, str]) -> dict:
:param base_url: Root URL of the Caddy file server (trailing slash optional).
:param auth: ``(username, password)`` tuple for HTTP Basic Auth.
:param progress_fn: Optional callback called as ``progress_fn(current, total, name)``
after each folder is processed. Use it to report progress without
coupling the library to ``print`` or any specific I/O sink.
:returns: Dict with keys:
- ``by_steam_id`` — ``{steam_id: folder_url}``
@@ -100,11 +107,12 @@ def build_server_index(base_url: str, auth: tuple[str, str]) -> dict:
root = base_url.rstrip("/") + "/"
items = _list_dir(root, session)
folders = [it for it in items if it.get("is_dir")]
total = len(folders)
by_steam_id: dict[str, str] = {}
by_name: dict[str, str] = {}
for folder in folders:
for i, folder in enumerate(folders, 1):
name = folder["name"].strip("/")
url = _folder_url(root, name)
by_name[_normalize_name(name)] = url
@@ -118,6 +126,9 @@ def build_server_index(base_url: str, auth: tuple[str, str]) -> dict:
except requests.RequestException:
pass # meta.cpp missing or unreachable — name-based fallback still works
if progress_fn is not None:
progress_fn(i, total, name)
return {"by_steam_id": by_steam_id, "by_name": by_name, "folders": folders}