diff options
Diffstat (limited to 'app/backends/audiocpp/status.py')
| -rw-r--r-- | app/backends/audiocpp/status.py | 90 |
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, {} + + |
