diff --git a/dikte/i18n.py b/dikte/i18n.py index fc7476e..7233c74 100644 --- a/dikte/i18n.py +++ b/dikte/i18n.py @@ -779,6 +779,7 @@ TR = { "Local model": "Yerel model", "Not installed.": "Kurulu değil.", "Installed on the system: {path}": "Sistemde kurulu: {path}", + "Download again": "Yeniden indir", "Downloaded, version {version}.": "İndirildi, sürüm {version}.", "Downloaded, version {version}. There was no Vulkan build, " "so this one runs on the processor.": diff --git a/dikte/settings_ui.py b/dikte/settings_ui.py index c3155da..978df52 100644 --- a/dikte/settings_ui.py +++ b/dikte/settings_ui.py @@ -349,10 +349,18 @@ class LocalModelBox(QGroupBox): path = ggml.program_path(self.program) if not path: self.program_label.setText(t("Not installed.")) + self.install_button.setText(t("Download")) self.install_button.setVisible(True) return - self.install_button.setVisible(not ggml.installed_program(self.program) - and not ggml.system_program(self.program)) + # A copy that is here is not a copy that is right. whisper.cpp releases + # every few weeks, and a graphics card installed after Dikte was + # changes which build this machine should be running; the button was + # hidden the moment anything landed, and nothing else on this window + # asks for the download again. + self.install_button.setText(t("Download again") + if ggml.installed_program(self.program) + else t("Download")) + self.install_button.setVisible(not ggml.system_program(self.program)) if ggml.system_program(self.program): # Worth saying which one is running: a distribution package is built # for this machine and may reach the graphics card, while the diff --git a/tests/test_ui.py b/tests/test_ui.py index e147068..ed86910 100644 --- a/tests/test_ui.py +++ b/tests/test_ui.py @@ -22,6 +22,7 @@ from dikte import cleanup from dikte import config as cfg from dikte import ggml from dikte import hotkey +from dikte.i18n import t from dikte import ipc from dikte import overlay as overlay_module from dikte import paste @@ -1243,6 +1244,27 @@ class LocalModels(DikteTest): self.assertIn("v1.9.3", label) self.assertNotIn("Vulkan", label) + def test_a_downloaded_program_can_still_be_asked_for_again(self): + # The button used to disappear the moment anything landed, which left + # no way to pick up a newer whisper.cpp, or the Vulkan build on a + # machine whose driver was installed after Dikte was. + binary = self.path("bin/whisper/v1.9.3/whisper-server") + binary.parent.mkdir(parents=True) + binary.write_text("") + binary.chmod(0o755) + self.path("bin/whisper/installed.json").write_text(json.dumps( + {"tag": "v1.9.3", "binary": str(binary)})) + self.patch_attr(ggml.shutil, "which", lambda name: None) + box = self.window(cfg.Config()).local_whisper + self.assertTrue(box.install_button.isVisibleTo(box)) + self.assertEqual(box.install_button.text(), t("Download again")) + + def test_a_system_copy_is_not_offered_for_download(self): + # Nothing Dikte downloads would be run while one is on the PATH. + self.patch_attr(ggml.shutil, "which", lambda name: "/usr/bin/" + name) + box = self.window(cfg.Config()).local_whisper + self.assertFalse(box.install_button.isVisibleTo(box)) + def test_only_the_chosen_transcriber_is_on_screen(self): window = self.window(self.config(transcribe_provider="openai")) self.assertTrue(window.stt_form.isRowVisible(window.transcribe_model_row))