diff options
| author | historia <historiavg@proton.me> | 2026-08-28 14:57:48 -0400 |
|---|---|---|
| committer | historia <historiavg@proton.me> | 2026-08-28 14:57:48 -0400 |
| commit | db38085d07ce75f8961eecdc1919e98748254c53 (patch) | |
| tree | beaea2ba84de05bfc2fa90e9b92a24568d3b4cb9 /app/ui | |
| parent | afb2c2d5b297c5aa28bcced0e3f90e207d799c2a (diff) | |
| download | tts-audiobook-generator-db38085d07ce75f8961eecdc1919e98748254c53.tar.gz | |
refactor: overhaul config.py, remove cli default options
Diffstat (limited to 'app/ui')
| -rw-r--r-- | app/ui/hub.py | 72 |
1 files changed, 29 insertions, 43 deletions
diff --git a/app/ui/hub.py b/app/ui/hub.py index 8a6fda7..f63ff99 100644 --- a/app/ui/hub.py +++ b/app/ui/hub.py @@ -390,9 +390,9 @@ class _Hub: cmd = mapper(result) if cmd is None: return tui.Wizard.BACK - # The mapper may have persisted settings (qwen model/speaker), - # making the form-time statuses stale — the autostart plan - # must read the freshly-configured server argv/model. + # Nothing is persisted anymore, but server state may have + # changed since the form opened — the autostart plan must + # read fresh statuses. invalidate_detect_cache() statuses = detect_all(refresh=True) autostart_error = _add_autostart(cmd, statuses) @@ -500,7 +500,8 @@ class _Hub: without an extra action menu. The state lives in the table, not on the entries, because the menu's selection bar would cover inline colors. Each server is labelled by its backend's name; qwen hosts - one model at a time (config.QWEN_MODEL decides which). + one model at a time (its default start runs CustomVoice — a + Generate-audiobooks run needing another model restarts it). """ statuses = detect_all() candidates = [st for st in statuses if st.installed] @@ -915,11 +916,9 @@ def _convert_form(stdscr) -> Optional[tuple]: return None choices = [(label, key) for key, label, _st, _remote in entries if key in builders] - default = config.BACKEND if config.BACKEND in builders \ - else choices[0][1] fields = [{ "key": "backend", "label": "Backend", "kind": "choice", - "value": default, "choices": choices, + "value": choices[0][1], "choices": choices, }] for key, _label, _st, _remote in entries: if key not in builders: @@ -1174,9 +1173,7 @@ def _audiocpp_fields(stdscr, api_url: Optional[str] = None, if capability == AUDIOCPP_VOICE_DESIGN: voice_field["value"] = None elif capability == AUDIOCPP_VOICE_SPEAKER: - voice_field["value"] = (config.SPEAKER - if config.SPEAKER in QWEN3_TTS_SPEAKERS - else QWEN3_TTS_SPEAKERS[0]) + voice_field["value"] = QWEN3_TTS_SPEAKERS[0] else: # clone voices = voices_for(_field_value(fields, prefix + "model_id")) voice_field["value"] = voices[0] if voices else "" @@ -1223,8 +1220,7 @@ def _audiocpp_fields(stdscr, api_url: Optional[str] = None, else "This model needs a voice — pick one or switch models" model_ids = [m.get("id") for m in models] - default_model = config.AUDIOCPP_MODEL_ID \ - if config.AUDIOCPP_MODEL_ID in model_ids else model_ids[0] + default_model = model_ids[0] default_entry = next((m for m in models if m.get("id") == default_model), models[0]) default_capability = audiocpp_entry_voice_capability( @@ -1232,8 +1228,7 @@ def _audiocpp_fields(stdscr, api_url: Optional[str] = None, default_entry.get("id") or "") initial_voice = None if default_capability == AUDIOCPP_VOICE_SPEAKER: - initial_voice = (config.SPEAKER if config.SPEAKER in QWEN3_TTS_SPEAKERS - else QWEN3_TTS_SPEAKERS[0]) + initial_voice = QWEN3_TTS_SPEAKERS[0] elif default_capability == AUDIOCPP_VOICE_CLONE: initial = voices_for(default_model) initial_voice = initial[0] if initial else "" @@ -1295,7 +1290,7 @@ def _audiocpp_fields(stdscr, api_url: Optional[str] = None, # delivery instruction — or, on families without built-in speakers # that read instructions, the voice itself (instruction-voice mode). {"key": prefix + "instructions", "label": "Instructions", "kind": "text", - "value": config.AUDIOCPP_INSTRUCTIONS, + "value": "", "help": INSTRUCTIONS_HELP, "validate": lambda value: None if (model_capability(fields) != AUDIOCPP_VOICE_DESIGN or str(value).strip()) @@ -1356,12 +1351,11 @@ def _qwen_fields(remote_modes: Optional[list] = None, One demo server hosts one model at a time, so the picked model decides which server must be up. For the managed entry REMOTE_MODES/URLS are - None: the picker offers every model and the choice (plus any changed - speaker) is persisted to app/converter/config.py so the autostart boots - the same model again later. For a "[remote]" entry REMOTE_MODES names - which demos answered remotely ("Base", "CustomVoice" and/or - "VoiceDesign") and URLS maps "qwen" to its URL: the picker is limited to - the available models and the mapper passes the URL as ``api_url``. + None: the picker offers every model and the autostart/restart plan + boots exactly the picked model. For a "[remote]" entry REMOTE_MODES + names which demos answered remotely ("Base", "CustomVoice" and/or + "VoiceDesign") and URLS maps "qwen" to its URL: the picker is limited + to the available models and the mapper passes the URL as ``api_url``. """ remote_modes = list(remote_modes or []) urls = dict(urls or {}) @@ -1380,13 +1374,9 @@ def _qwen_fields(remote_modes: Optional[list] = None, model_choices = [(label, value) for (label, value) in model_choices if dict(mode_keys)[value] in available] by_value = {value: label for label, value in model_choices} - configured_mode = {model: mode for mode, model in mode_keys}.get( - qwen_backend.current_model(), model_choices[0][1]) - default_mode = configured_mode if configured_mode in by_value \ - else model_choices[0][1] + default_mode = "custom" if "custom" in by_value else model_choices[0][1] speakers = list(qwen_backend.QWEN_SPEAKERS) - default_speaker = config.SPEAKER if config.SPEAKER in speakers \ - else speakers[0] + default_speaker = speakers[0] # Voice cloning references: the directory the .wavs live in — browsed # with the directory widget, defaulting to the project's ./voices (the @@ -1437,7 +1427,7 @@ def _qwen_fields(remote_modes: Optional[list] = None, "validate": clone_wav_validate, "visible": lambda fs: _field_value(fs, prefix + "mode") == "clone"}, {"key": prefix + "qwen_instructions", "label": "Instructions", - "kind": "text", "value": config.INSTRUCT, + "kind": "text", "value": "", "help": ["Describe the voice to design, e.g.", '"A warm adult female narrator with a British accent".'], "validate": lambda s: None if s.strip() else @@ -1451,19 +1441,10 @@ def _qwen_fields(remote_modes: Optional[list] = None, if mode == "clone": clone = str(result[prefix + "clone"] or "").strip() or None kwargs = {"clone": clone, **_common_kwargs(result)} + if mode == "custom": + kwargs["voice"] = result[prefix + "speaker"] if mode == "design": kwargs["instructions"] = result[prefix + "qwen_instructions"] - if not urls: - # Managed entry: persist the choices for this and future runs, - # so the server autostart boots the same model again - # (update_config_value keeps both the file and the imported - # module in sync). - model = dict(mode_keys)[mode] - if model != qwen_backend.current_model(): - common.update_config_value("QWEN_MODEL", model) - speaker = result.get(prefix + "speaker", config.SPEAKER) - if mode == "custom" and speaker != config.SPEAKER: - common.update_config_value("SPEAKER", speaker) if urls: api_url = urls.get("qwen") if api_url: @@ -1510,12 +1491,11 @@ def _faster_fields(stdscr, api_url: Optional[str] = None, fields = [ {"key": prefix + "faster_voice", "label": "Voice to clone", "kind": "text", - "value": config.FASTER_VOICE, + "value": "", "validate": lambda s: None if s.strip() else "Enter a voice name"}, ] else: - default = config.FASTER_VOICE if config.FASTER_VOICE in voices else \ - next(iter(voices)) + default = next(iter(voices)) fields = [ {"key": prefix + "faster_voice", "label": "Voice to clone", "kind": "choice", @@ -1847,7 +1827,7 @@ def _prepare_run_config(backend: str, kwargs: dict log_path=log_path, stop_and_exit=stop_and_exit) status = next((s for s in detect_all(refresh=True) - if s.key == backend), None) + if s.key == backend), None) notice = "" spec: Optional[ServerSpec] = None if autostart: @@ -1867,6 +1847,12 @@ def _prepare_run_config(backend: str, kwargs: dict if spec is None: notice = (f"no server named '{restart_name}' — the model " "switch restart was skipped") + if spec is not None and backend == BACKEND_QWEN: + # One demo server hosts one model: aim the spec at the model this + # run selected (same URL/port, matching probe identity), so an + # autostart or model-switch restart boots exactly what the run + # needs instead of the Start/Stop menu's default model. + spec = qwen_backend._build_spec(_qwen_wanted_model(kwargs)) return runview.RunConfig( backend=backend, backend_label=label, kwargs=kwargs, book_files=book_files, planned=planned, |
