diff options
| author | historia <historiavg@proton.me> | 2026-08-28 18:44:32 -0400 |
|---|---|---|
| committer | historia <historiavg@proton.me> | 2026-08-28 18:44:32 -0400 |
| commit | 03ed68bafec56ef8bb690440d796c1a742042907 (patch) | |
| tree | 9f80e1848ca8c141f49875ffdbe462527ab0a9c3 /app/backends/audiocpp/wizard.py | |
| parent | 3c9b7e12029f6accdaabb6f60e01bce88156db98 (diff) | |
| download | tts-audiobook-generator-03ed68bafec56ef8bb690440d796c1a742042907.tar.gz | |
feat(audio.cpp): if github binary download fails, automatically start building from source
Diffstat (limited to 'app/backends/audiocpp/wizard.py')
| -rw-r--r-- | app/backends/audiocpp/wizard.py | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/app/backends/audiocpp/wizard.py b/app/backends/audiocpp/wizard.py index 5b237c4..f35aac1 100644 --- a/app/backends/audiocpp/wizard.py +++ b/app/backends/audiocpp/wizard.py @@ -303,6 +303,7 @@ def _wizard(stdscr, args: argparse.Namespace, parser: argparse.ArgumentParser "backend": backend, "build": build, "build_mode": s.get("build_mode"), + "prebuilt_forced": False, "lazy_load": True, "sync_port": None, "wav_dir": s["wav_dir"], @@ -621,39 +622,44 @@ def _execute_lanes(settings: dict, if build: mode = settings.get("build_mode") or "source" + forced = bool(settings.get("prebuilt_forced")) + + def source_build_step(emit, cancel) -> int: + """Build from source, warning-and-continue like the setup.""" + rc = _build.build_audiocpp(audiocpp_dir, settings["backend"], + emit=emit, cancel=cancel) + if rc == 124: + print("[WARNING] build went silent and was stopped; the " + "server.json was still written — build " + "audiocpp_server manually before starting it") + elif rc != 0: + print(f"[WARNING] build exited with code {rc}; the " + "server.json was still written — build " + "audiocpp_server manually before starting it") + else: + print("[OK] build complete") + return rc + if mode == "prebuilt": def build_step(emit, cancel): rc = _prebuilt.install_prebuilt( audiocpp_dir, settings["backend"], emit=emit, cancel=cancel) - if rc == 130: - return rc - if rc != 0: - print(f"[WARNING] prebuilt download failed (exit {rc}); " - "the server.json was still written — build " - "audiocpp_server from source ('Build audio.cpp " - "Server', or re-run with --prebuilt no) before " - "starting it") - else: + if rc == 0: print("[OK] prebuilt audiocpp_server installed") - return rc - build_title = (f"Download prebuilt audiocpp_server " - f"({settings['backend']})") + return 0 + if rc == 130 or forced: + # A cancelled download, or one the user explicitly + # forced with --prebuilt yes: fail fast. + return rc + # The usual failure is GitHub's API rate limit — recover + # in place instead of leaving the setup half-installed. + print(f"[WARNING] prebuilt download failed (exit {rc}); " + "falling back to a source build...") + return source_build_step(emit, cancel) + build_title = f"Install audiocpp_server ({settings['backend']})" else: - def build_step(emit, cancel): - rc = _build.build_audiocpp(audiocpp_dir, settings["backend"], - emit=emit, cancel=cancel) - if rc == 124: - print("[WARNING] build went silent and was stopped; the " - "server.json was still written — build " - "audiocpp_server manually before starting it") - elif rc != 0: - print(f"[WARNING] build exited with code {rc}; the " - "server.json was still written — build " - "audiocpp_server manually before starting it") - else: - print("[OK] build complete") - return rc + build_step = source_build_step build_title = f"Build audiocpp_server ({settings['backend']})" lanes.append(taskview.TaskLane( "Build", @@ -831,14 +837,25 @@ def build_screen(stdscr) -> int: if mode is _GO_BACK: return 1 + outcome: dict = {"prebuilt": False} + def build_step(emit, cancel): if mode == "prebuilt": - return _prebuilt.install_prebuilt(checkout, backend, - emit=emit, cancel=cancel) + rc = _prebuilt.install_prebuilt(checkout, backend, + emit=emit, cancel=cancel) + if rc == 0: + outcome["prebuilt"] = True + return 0 + if rc == 130: + return rc + # The usual failure is GitHub's API rate limit — recover in + # place instead of sending the user back to the menus. + print(f"[WARNING] prebuilt download failed (exit {rc}); " + "falling back to a source build...") return _build.build_audiocpp(checkout, backend, emit=emit, cancel=cancel) - action = "Download prebuilt audiocpp_server" if mode == "prebuilt" \ + action = f"Install audiocpp_server ({backend})" if mode == "prebuilt" \ else f"Build audiocpp_server ({backend})" lanes = [taskview.TaskLane("Build", [taskview.TaskStep(action, build_step)])] @@ -858,15 +875,15 @@ def build_screen(stdscr) -> int: "Download models", [taskview.TaskStep("Download missing models", download_step)])) - install_title = ("Download prebuilt audiocpp_server" - if mode == "prebuilt" else "Build audiocpp_server") + install_title = ("Install audiocpp_server" if mode == "prebuilt" + else "Build audiocpp_server") title = f"{install_title} & download models" if len(lanes) == 2 \ else install_title rc = taskview.run_lanes(stdscr, title, lanes) if rc != 0: return rc if not _configsync.update_server_backend(backend): - verb = "installed" if mode == "prebuilt" else "built" + verb = "installed" if outcome["prebuilt"] else "built" tui.flash(stdscr, f"audiocpp_server {verb} for {backend}. (Could not " "update server.json's backend field — reconfigure audio.cpp " "if it was already configured.)", "warn") @@ -995,8 +1012,12 @@ def _collect_from_flags(args: argparse.Namespace, build = False # How a pending install happens: the prebuilt release by default on # macOS/Windows (``--prebuilt no`` forces the source build), always - # the source build elsewhere. + # the source build elsewhere. A ``--prebuilt yes`` download that + # fails stays a failure (no source-build fallback) — the flag's + # whole point is "do not build". build_mode = _flag_build_mode(args, backend) if build else None + prebuilt_forced = bool(build) and getattr(args, "prebuilt", "auto") \ + == "yes" port = _configsync.config_port() lazy_load = True @@ -1039,6 +1060,7 @@ def _collect_from_flags(args: argparse.Namespace, "backend": backend, "build": build, "build_mode": build_mode, + "prebuilt_forced": prebuilt_forced, "lazy_load": lazy_load, "sync_port": None, "wav_dir": wav_dir, @@ -1088,9 +1110,11 @@ def build_parser() -> argparse.ArgumentParser: default="auto", help="How to install audiocpp_server when it is " "missing: auto downloads the prebuilt release " - "on macOS/Windows and builds from source " - "elsewhere; yes forces the prebuilt download; " - "no forces a source build") + "on macOS/Windows (falling back to a source " + "build if the download fails) and builds from " + "source elsewhere; yes forces the prebuilt " + "download and fails if it cannot; no forces a " + "source build") parser.add_argument("--whisper-model", type=str, default="base", help="Whisper model size for transcription " "(default: base)") |
