aboutsummaryrefslogtreecommitdiff
path: root/app/ui
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-26 22:27:51 -0400
committerhistoria <historiavg@proton.me>2026-08-26 22:27:51 -0400
commitf18f421d9180ae0e3bff9496b1fdaf53d3624a75 (patch)
tree6f89ccbda3844bb74ebe239dbf15ed3441b13204 /app/ui
parent477ac3e827e3bdc9f14583fc3aa8db1fa2d27c52 (diff)
downloadtts-audiobook-generator-f18f421d9180ae0e3bff9496b1fdaf53d3624a75.tar.gz
feat: manage qwen-tts model installs manually, delete model(s) when uninstalled
Diffstat (limited to 'app/ui')
-rw-r--r--app/ui/hub.py43
1 files changed, 30 insertions, 13 deletions
diff --git a/app/ui/hub.py b/app/ui/hub.py
index 10484d2..230def3 100644
--- a/app/ui/hub.py
+++ b/app/ui/hub.py
@@ -150,10 +150,10 @@ class _Hub:
no binary) or download its missing models (only once built, so
build > configure > download — Build and Download never appear
together) — heads the menu with a yellow ``[recommended]`` tag,
- separated from the rest by a blank line. remaining actions are populated from the detected statuses:
- configure each configurable backend (qwen asks nothing to
- configure, so it has no entry), install (backends with nothing on
- disk), and uninstall.
+ separated from the rest by a blank line. The remaining actions are
+ populated from the detected statuses: configure each configurable
+ backend (qwen offers its per-model weight (un)installer there),
+ install (backends with nothing on disk), and uninstall.
Selecting one pushes the next screen; Esc pops back to the main
menu. The Build action downloads any missing models alongside the
build (a split view), so it heals a configured-but-unbuilt backend
@@ -232,18 +232,33 @@ class _Hub:
return self.screen_setup(info)
def screen_setup(self, info):
- """Run one backend's setup wizard as a leaf screen of the stack.
+ """Run one backend's setup/configure wizard as a leaf screen.
The wizard drives its own internal ``tui.Wizard`` on this screen;
Esc on its first screen (or Ctrl-C) returns here and the hub pops
back to the menu that launched it. A crash flashes and does the same.
"""
def screen():
- self._run_setup(info)
+ # A dedicated configure screen (qwen's per-model manager) takes
+ # precedence over the plain setup wizard here; Install Backend
+ # keeps running the setup wizard either way.
+ if info.configure_screen is not None:
+ self._run_configure(info)
+ else:
+ self._run_setup(info)
invalidate_detect_cache()
return tui.Wizard.BACK
return screen
+ def _run_configure(self, info) -> None:
+ """Run one backend's dedicated configure screen on this session."""
+ try:
+ info.configure_screen(self.stdscr)
+ except tui.WizardCancelled:
+ pass
+ except Exception as exc: # noqa: BLE001 - keep the hub alive
+ tui.flash(self.stdscr, str(exc), "err")
+
def _run_setup(self, info) -> None:
"""Run one backend's setup wizard on this session (no stack frame)."""
try:
@@ -586,14 +601,16 @@ def _server_action_step(spec, action: str):
def _configurable(info) -> bool:
- """True when INFO has a setup wizard worth running to reconfigure.
-
- qwen-tts is excluded: its wizard asks no questions (ports live in the
- Settings screen, the speaker is chosen per run on Generate audiobooks),
- so a "Configure" entry could only ever flash "already installed".
- Installing it stays possible via Install Backend.
+ """True when INFO has a configure screen worth running from the hub.
+
+ A backend with a dedicated ``configure_screen`` (qwen manages its three
+ model weight installs there) is always configurable; other backends
+ count via their non-trivial setup wizard. Bare qwen — whose wizard asks
+ no questions: ports live in Settings, the speaker is chosen per run on
+ Generate audiobooks — would only ever flash "already installed", so it
+ stays excluded until it ships a dedicated screen.
"""
- return info.key != "qwen"
+ return info.configure_screen is not None or info.key != "qwen"
def _installable(info, by_key: dict) -> bool: