aboutsummaryrefslogtreecommitdiff
path: root/app/backends/audiocpp/status.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-26 02:25:55 -0400
committerhistoria <historiavg@proton.me>2026-08-26 02:25:55 -0400
commit8b5c8697740ff415cf7f1d03c9fb5a8c8851d420 (patch)
tree28c0323c54c896af5f89fb34b89a62e0fe0df291 /app/backends/audiocpp/status.py
parentacbd9ff2c91182d96c57ffb57bee6e9b3fcbcbd4 (diff)
downloadtts-audiobook-generator-8b5c8697740ff415cf7f1d03c9fb5a8c8851d420.tar.gz
refactor: audiocpp.py setup flow
Diffstat (limited to 'app/backends/audiocpp/status.py')
-rw-r--r--app/backends/audiocpp/status.py90
1 files changed, 90 insertions, 0 deletions
diff --git a/app/backends/audiocpp/status.py b/app/backends/audiocpp/status.py
new file mode 100644
index 0000000..9ccf8cc
--- /dev/null
+++ b/app/backends/audiocpp/status.py
@@ -0,0 +1,90 @@
+"""detect() — the BackendStatus report for the hub's backend menu."""
+
+from typing import List, Tuple
+
+from backends import (BackendStatus, ServerSpec, format_launch_hint,
+ probe, servers)
+from converter import config
+from . import build as _build
+from . import models as _models
+
+def detect() -> BackendStatus:
+ """Detect how far audio.cpp is set up, plus the command to start it."""
+ checkout = _build.find_local_checkout()
+ details: List[str] = []
+ launch = ""
+ if checkout is None:
+ # No local checkout: only a remote server can make this usable.
+ remote = _detect_remote()
+ return BackendStatus("audiocpp", "audio.cpp", installed=False,
+ configured=False, running=remote[0],
+ remote=remote[0], remote_urls=remote[1],
+ details=["not cloned — run setup to clone "
+ "./app/audio.cpp"])
+ details.append(f"checkout: {checkout}")
+ binary = _build.find_audiocpp_server_bin(checkout)
+ built = binary is not None
+ if built:
+ details.append(f"built: {binary}")
+ else:
+ details.append("not built — run setup to build audiocpp_server")
+ server_json = checkout / "server.json"
+ configured = server_json.exists()
+ specs: List[ServerSpec] = []
+ missing = _models.missing_model_entries(server_json) if configured else []
+ if configured:
+ details.append(f"config: {server_json}")
+ if missing:
+ # The config references model files that are not on disk; a
+ # conversion would fail at model-load time, so say so now.
+ details.extend(_models.model_install_hints(checkout, missing))
+ if built:
+ # Spawned from the checkout: audiocpp_server discovers
+ # model_specs/<family>.json relative to its working directory.
+ specs = [ServerSpec(
+ "audiocpp", config.AUDIOCPP_API_URL,
+ [str(binary), "--config", str(server_json)],
+ cwd=checkout, identity=probe.IDENTITY_AUDIOCPP)]
+ else:
+ launch = (f"cd {checkout} && ./build/<platform>-<backend>-release"
+ f"/bin/audiocpp_server --config {server_json}")
+ else:
+ details.append("no server.json — run setup to configure models")
+ if specs:
+ launch = format_launch_hint(specs)
+ managed = servers.manages(specs)
+ remote_running, remote_urls = _detect_remote(managed)
+ # A more specific "part-way set up" label than unavailable/installed:
+ # cloned but never built, or built but not configured.
+ partial = ""
+ if not built:
+ partial = "downloaded (not built)"
+ elif not configured:
+ partial = "built (not configured)"
+ return BackendStatus("audiocpp", "audio.cpp", installed=built,
+ configured=configured,
+ running=managed or remote_running,
+ details=details, launch_hint=launch,
+ servers=specs, managed=managed,
+ remote=remote_running, remote_urls=remote_urls,
+ models_missing=bool(missing), partial=partial)
+
+
+def _detect_remote(managed: bool = False) -> Tuple[bool, dict]:
+ """Detect an externally-run audiocpp_server at the remote URL.
+
+ Returns ``(running, {spec_name: url})``. The remote URL is probed only
+ when configured (non-empty); a server answering there is ignored when it
+ is this tool's own managed server (remote URL == local URL and our pid is
+ still alive) — that instance is already reported as "[local]".
+ """
+ url = (config.AUDIOCPP_REMOTE_URL or "").strip()
+ if not url:
+ return False, {}
+ if managed and probe.same_endpoint(url, config.AUDIOCPP_API_URL):
+ return False, {}
+ if probe.identify_server(url) == probe.IDENTITY_AUDIOCPP:
+ return True, {"audiocpp": url}
+ return False, {}
+
+