diff --git a/stt_voice_messages/stt_voice_messages.py b/stt_voice_messages/stt_voice_messages.py index ff82093..ad33ee2 100644 --- a/stt_voice_messages/stt_voice_messages.py +++ b/stt_voice_messages/stt_voice_messages.py @@ -20,7 +20,7 @@ from functools import partial from pathlib import Path import whisper -from gi.repository import Gtk +from gi.repository import Gio, GObject, Gtk from stt_voice_messages.config_dialog import STTVoiceMessagesConfigDialog from gajim.plugins import GajimPlugin @@ -69,12 +69,12 @@ class STTBox(Gtk.Box): audio_file: Path, ) -> None: - print('FOO') Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL, spacing=12) self._config = config self._preview_audio = preview_audio_widget self._audio_file = audio_file + self._text = '' self._transcribe_button = Gtk.Button(label=_('Transcribe')) @@ -89,20 +89,69 @@ class STTBox(Gtk.Box): self.show_all() - def _on_transcribe_clicked(self, _button: Gtk.Button): - text = self._trascribe_by_whisper() - if text.strip() != '': - self._transcription_label.set_text(text.strip()) + transcription_task = BackgroundTask( + self._trascribe_by_whisper, + self._show_result + ) + transcription_task.start() + + def _show_result(self): + if self._text.strip() != '': + self._transcription_label.set_text(self._text.strip()) else: self._transcription_label.set_text(_('_Have not heard any word!_')) def _trascribe_by_whisper(self) -> str: model = whisper.load_model(self._config['model_size']) result = model.transcribe(self._audio_file) - text = result["text"] + self._text = result["text"] return text +''' +https://discourse.gnome.org/t/gtk-threading-problem-with-glib-idle-add/13597/5 +https://github.com/gdm-settings/gdm-settings/blob/f245d3000200fa6be2a35c7f6ac45b131dadb5d6/src/utils.py#L116..L162 +''' +class BackgroundTask (GObject.Object): + __gtype_name__ = 'BackgroundTask' + def __init__ (self, function, finish_callback, **kwargs): + super().__init__(**kwargs) + self.function = function + self.finish_callback = finish_callback + self._current = None + + def start(self): + if self._current: + AlreadyRunningError('Task is already running') + + finish_callback = lambda self, task, nothing: self.finish_callback() + + task = Gio.Task.new(self, None, finish_callback, None) + task.run_in_thread(self._thread_cb) + + self._current = task + + @staticmethod + def _thread_cb (task, self, task_data, cancellable): + try: + retval = self.function() + task.return_value(retval) + except Exception as e: + task.return_value(e) + + def finish (self): + task = self._current + self._current = None + + if not Gio.Task.is_valid(task, self): + raise InvalidGioTaskError() + + value = task.propagate_value().value + + if isinstance(value, Exception): + raise value + + return value