Compare commits

..

3 commits

Author SHA1 Message Date
Raivis Dejus 91b1775088
Merge 8939447d58 into 3d44a45476 2024-06-14 20:28:25 +00:00
Raivis Dejus 8939447d58 Adding test fixes 2024-06-14 23:28:05 +03:00
Raivis Dejus 99e8dd20a7 Adding translations to transcription view 2024-06-14 19:14:13 +03:00
12 changed files with 150 additions and 56 deletions

View file

@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-13 07:37+0300\n"
"PO-Revision-Date: 2024-06-13 07:38+0300\n"
"POT-Creation-Date: 2024-06-14 18:59+0300\n"
"PO-Revision-Date: 2024-06-14 19:01+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: lv_LV\n"
@ -39,51 +39,63 @@ msgid "View Transcript Text"
msgstr "Aplūkot atpazīto tekstu"
#: buzz/settings/shortcut.py:23
msgid "View Transcript Translation"
msgstr "Aplūkot tulkojumu"
#: buzz/settings/shortcut.py:24
msgid "View Transcript Timestamps"
msgstr "Aplūkot atpazīšanas laikus"
#: buzz/settings/shortcut.py:25 buzz/widgets/main_window_toolbar.py:60
#: buzz/settings/shortcut.py:26 buzz/widgets/main_window_toolbar.py:60
#: buzz/widgets/main_window.py:222
msgid "Clear History"
msgstr "Notīrīt vēsturi"
#: buzz/settings/shortcut.py:26 buzz/widgets/main_window_toolbar.py:52
#: buzz/settings/shortcut.py:27 buzz/widgets/main_window_toolbar.py:52
msgid "Cancel Transcription"
msgstr "Atcelt atpazīšanu"
#: buzz/widgets/transcription_tasks_table_widget.py:64
#: buzz/widgets/transcription_tasks_table_widget.py:62
msgid "In Progress"
msgstr "Apstrādā"
#: buzz/widgets/transcription_tasks_table_widget.py:65
msgid "Completed"
msgstr "Pabeigts"
#: buzz/widgets/transcription_tasks_table_widget.py:73
#: buzz/widgets/transcription_tasks_table_widget.py:72
msgid "Failed"
msgstr "Neizdevās"
#: buzz/widgets/transcription_tasks_table_widget.py:75
msgid "Canceled"
msgstr "Atcelts"
#: buzz/widgets/transcription_tasks_table_widget.py:75
#: buzz/widgets/transcription_tasks_table_widget.py:77
msgid "Queued"
msgstr "Ierindots"
#: buzz/widgets/transcription_tasks_table_widget.py:83
#: buzz/widgets/transcription_tasks_table_widget.py:85
msgid "File Name / URL"
msgstr "Fails / URL"
#: buzz/widgets/transcription_tasks_table_widget.py:95
#: buzz/widgets/transcription_tasks_table_widget.py:97
msgid "Model"
msgstr "Modelis"
#: buzz/widgets/transcription_tasks_table_widget.py:104
#: buzz/widgets/transcription_tasks_table_widget.py:106
msgid "Task"
msgstr "Uzdevums"
#: buzz/widgets/transcription_tasks_table_widget.py:113
#: buzz/widgets/transcription_tasks_table_widget.py:115
msgid "Status"
msgstr "Statuss"
#: buzz/widgets/transcription_tasks_table_widget.py:121
#: buzz/widgets/transcription_tasks_table_widget.py:123
msgid "Date Added"
msgstr "Pievienots"
#: buzz/widgets/transcription_tasks_table_widget.py:132
#: buzz/widgets/transcription_tasks_table_widget.py:134
msgid "Date Completed"
msgstr "Pabeigts"
@ -215,23 +227,31 @@ msgid "Unable to save OpenAI API key to keyring"
msgstr "Neizdevās saglabāt OpenAI API atslēgu atslēgu saišķī"
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:42
msgid "Save File"
msgstr "Saglabāt failu"
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:44
msgid "Text files"
msgstr "Teksta faili"
#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:19
msgid "View"
msgstr "Skats"
#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:27
#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:34
#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:95
msgid "Text"
msgstr "Teksts"
#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:33
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:43
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:65
#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:40
#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:96
msgid "Translation"
msgstr "Tulkojums"
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:79
msgid "Save File"
msgstr "Saglabāt failu"
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:81
msgid "Text files"
msgstr "Teksta faili"
#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:26
msgid "View"
msgstr "Skats"
#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:46
msgid "Timestamps"
msgstr "Laiks"
@ -243,23 +263,19 @@ msgstr "Sākums"
msgid "End"
msgstr "Beigas"
#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:96
msgid "Translation"
msgstr "Tulkojums"
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:148
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:146
msgid "Export"
msgstr "Eksportēt"
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:162
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:160
msgid "Translate"
msgstr "Tulkot"
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:242
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:250
msgid "API Key Required"
msgstr "API atslēgas kļūda"
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:243
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:251
msgid "Please enter OpenAI API Key in preferences"
msgstr "Lūdzu ievadiet OpenAI API atslēgu iestatījumos"
@ -267,37 +283,45 @@ msgstr "Lūdzu ievadiet OpenAI API atslēgu iestatījumos"
msgid "Stop"
msgstr "Apturēt"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:32
#: buzz/widgets/transcriber/advanced_settings_dialog.py:33
msgid "Advanced Settings"
msgstr "Papildu iestatījumi"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:41
#: buzz/widgets/transcriber/advanced_settings_dialog.py:37
msgid "Speech recognition settings"
msgstr "Runas atpazīšanas iestatījumi"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:46
msgid "Comma-separated, e.g. \"0.0, 0.2, 0.4, 0.6, 0.8, 1.0\""
msgstr "Atdalīti ar komatu, piemēram, \"0.0, 0.2, 0.4, 0.6, 0.8, 1.0\""
#: buzz/widgets/transcriber/advanced_settings_dialog.py:50
#: buzz/widgets/transcriber/advanced_settings_dialog.py:55
msgid "Temperature:"
msgstr "Temperatūra:"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:61
#: buzz/widgets/transcriber/advanced_settings_dialog.py:66
msgid "Initial Prompt:"
msgstr ""
"Sākotnējais\n"
"vaicājums:"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:63
#: buzz/widgets/transcriber/advanced_settings_dialog.py:68
msgid "Translation settings"
msgstr "Tulkojuma iestatījumi"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:72
msgid "Enable AI translation"
msgstr "Tulkot ar MI"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:75
#: buzz/widgets/transcriber/advanced_settings_dialog.py:84
msgid "AI model:"
msgstr "AI modelis:"
#: buzz/widgets/transcriber/advanced_settings_dialog.py:79
#: buzz/widgets/transcriber/advanced_settings_dialog.py:88
msgid "Enter instructions for AI on how to translate..."
msgstr "Ievadiet tulkošanas norādes mākslīgajam intelektam..."
#: buzz/widgets/transcriber/advanced_settings_dialog.py:83
#: buzz/widgets/transcriber/advanced_settings_dialog.py:92
msgid "Instructions for AI:"
msgstr "Norādes MI:"

View file

@ -125,7 +125,7 @@ class RecordingTranscriber(QObject):
whisper_segments, info = model.transcribe(
audio=samples,
language=self.transcription_options.language
if self.transcription_options.language is not ""
if self.transcription_options.language != ""
else None,
task=self.transcription_options.task.value,
temperature=self.transcription_options.temperature,

View file

@ -121,6 +121,7 @@ class WhisperFileTranscriber(FileTranscriber):
start=int(segment.get("start") * 1000),
end=int(segment.get("end") * 1000),
text=segment.get("text"),
translation=""
)
for segment in result.get("segments")
]
@ -149,6 +150,7 @@ class WhisperFileTranscriber(FileTranscriber):
start=int(word.start * 1000),
end=int(word.end * 1000),
text=word.word,
translation=""
)
)
else:
@ -157,6 +159,7 @@ class WhisperFileTranscriber(FileTranscriber):
start=int(segment.start * 1000),
end=int(segment.end * 1000),
text=segment.text,
translation=""
)
)
@ -181,6 +184,7 @@ class WhisperFileTranscriber(FileTranscriber):
start=int(word.start * 1000),
end=int(word.end * 1000),
text=word.word.strip(),
translation=""
)
for segment in result.segments
for word in segment.words
@ -200,6 +204,7 @@ class WhisperFileTranscriber(FileTranscriber):
start=int(segment.get("start") * 1000),
end=int(segment.get("end") * 1000),
text=segment.get("text"),
translation=""
)
for segment in segments
]
@ -226,6 +231,7 @@ class WhisperFileTranscriber(FileTranscriber):
start=segment.get("start"),
end=segment.get("end"),
text=segment.get("text"),
translation=""
)
for segment in segments_dict
]

View file

@ -141,6 +141,8 @@ class MainWindow(QMainWindow):
self.folder_watcher.task_found.connect(self.add_task)
self.folder_watcher.find_tasks()
self.transcription_viewer_widget = None
if os.environ.get('SNAP_NAME', '') == 'buzz':
logging.debug("Running in a snap environment")
self.check_linux_permissions()
@ -349,14 +351,14 @@ class MainWindow(QMainWindow):
self.open_transcription_viewer(transcription)
def open_transcription_viewer(self, transcription: Transcription):
transcription_viewer_widget = TranscriptionViewerWidget(
self.transcription_viewer_widget = TranscriptionViewerWidget(
transcription=transcription,
transcription_service=self.transcription_service,
shortcuts=self.shortcuts,
parent=self,
flags=Qt.WindowType.Window,
)
transcription_viewer_widget.show()
self.transcription_viewer_widget.show()
def add_task(self, task: FileTranscriptionTask):
self.transcription_service.create_transcription(task)
@ -398,6 +400,10 @@ class MainWindow(QMainWindow):
self.transcriber_worker.stop()
self.transcriber_thread.quit()
self.transcriber_thread.wait()
if self.transcription_viewer_widget is not None:
self.transcription_viewer_widget.close()
super().closeEvent(event)
def save_geometry(self):

View file

@ -59,7 +59,8 @@ def format_record_status_text(record: QSqlRecord) -> str:
status = FileTranscriptionTask.Status(record.value("status"))
match status:
case FileTranscriptionTask.Status.IN_PROGRESS:
return f'{_("In Progress")} ({record.value("progress") :.0%})'
in_progress_label = _("In Progress")
return f'{in_progress_label} ({record.value("progress") :.0%})'
case FileTranscriptionTask.Status.COMPLETED:
status = _("Completed")
started_at = record.value("time_started")
@ -68,7 +69,8 @@ def format_record_status_text(record: QSqlRecord) -> str:
status += f" ({TranscriptionTasksTableWidget.format_timedelta(datetime.fromisoformat(completed_at) - datetime.fromisoformat(started_at))})"
return status
case FileTranscriptionTask.Status.FAILED:
return f'{_("Failed")} ({record.value("error_message")})'
failed_label = _("Failed")
return f'{failed_label} ({record.value("error_message")})'
case FileTranscriptionTask.Status.CANCELED:
return _("Canceled")
case FileTranscriptionTask.Status.QUEUED:

View file

@ -35,7 +35,7 @@ class ExportTranscriptionMenu(QMenu):
)
]
if len(self.segments[0].translation) > 0:
if self.segments and len(self.segments[0].translation) > 0:
text_label = _("Text")
translation_label = _("Translation")
actions = [

View file

@ -262,9 +262,12 @@ class TranscriptionViewerWidget(QWidget):
self.translator.enqueue(segment.value("text"), segment.value("id"))
def closeEvent(self, event):
self.hide()
self.translator.stop()
if self.translation_thread.isRunning():
self.translation_thread.quit()
self.translation_thread.wait()
super().closeEvent(event)

View file

@ -111,7 +111,11 @@ class TestAdvancedSettingsDialog:
def test_should_update_advanced_settings(self, qtbot: QtBot):
dialog = AdvancedSettingsDialog(
transcription_options=TranscriptionOptions(
temperature=(0.0, 0.8), initial_prompt="prompt"
temperature=(0.0, 0.8),
initial_prompt="prompt",
enable_llm_translation=False,
llm_model="",
llm_prompt=""
)
)
qtbot.add_widget(dialog)
@ -122,12 +126,21 @@ class TestAdvancedSettingsDialog:
assert dialog.windowTitle() == _("Advanced Settings")
assert dialog.temperature_line_edit.text() == "0.0, 0.8"
assert dialog.initial_prompt_text_edit.toPlainText() == "prompt"
assert dialog.enable_llm_translation_checkbox.isChecked() is False
assert dialog.llm_model_line_edit.text() == ""
assert dialog.llm_prompt_text_edit.toPlainText() == ""
dialog.temperature_line_edit.setText("0.0, 0.8, 1.0")
dialog.initial_prompt_text_edit.setPlainText("new prompt")
dialog.enable_llm_translation_checkbox.setChecked(True)
dialog.llm_model_line_edit.setText("model")
dialog.llm_prompt_text_edit.setPlainText("Please translate this text")
assert transcription_options_mock.call_args[0][0].temperature == (0.0, 0.8, 1.0)
assert transcription_options_mock.call_args[0][0].initial_prompt == "new prompt"
assert transcription_options_mock.call_args[0][0].enable_llm_translation is True
assert transcription_options_mock.call_args[0][0].llm_model == "model"
assert transcription_options_mock.call_args[0][0].llm_prompt == "Please translate this text"
class TestTemperatureValidator:

View file

@ -22,7 +22,7 @@ class TestTranslator:
if side_effect.call_count < 3:
raise Empty
return 'Hello, how are you?'
return "Hello, how are you?", None
side_effect.call_count = 0
@ -32,11 +32,18 @@ class TestTranslator:
mock_chat.completions.create.return_value = Mock(
choices=[Mock(message=Mock(content="AI Translated: Hello, how are you?"))]
)
translator = Translator(TranscriptionOptions(
transcription_options = TranscriptionOptions(
enable_llm_translation=False,
llm_model="llama3",
llm_prompt="Please translate this text:",
))
)
translator = Translator(
transcription_options,
AdvancedSettingsDialog(
transcription_options=transcription_options, parent=None
)
)
translator.queue = mock_queue
translator.start()

View file

@ -30,9 +30,9 @@ class TestExportTranscriptionMenu:
whisper_model_size=WhisperModelSize.SMALL.value,
)
)
transcription_segment_dao.insert(TranscriptionSegment(40, 299, "Bien", str(id)))
transcription_segment_dao.insert(TranscriptionSegment(40, 299, "Bien", "", str(id)))
transcription_segment_dao.insert(
TranscriptionSegment(299, 329, "venue dans", str(id))
TranscriptionSegment(299, 329, "venue dans", "", str(id))
)
return transcription_dao.find_by_id(str(id))

View file

@ -35,6 +35,7 @@ class TestShortcutsEditorWidget:
(_("Import URL"), "Ctrl+U"),
(_("Open Preferences Window"), "Ctrl+,"),
(_("View Transcript Text"), "Ctrl+E"),
(_("View Transcript Translation"), "Ctrl+L"),
(_("View Transcript Timestamps"), "Ctrl+T"),
(_("Clear History"), "Ctrl+S"),
(_("Cancel Transcription"), "Ctrl+X"),

View file

@ -1,12 +1,18 @@
import uuid
import time
import pytest
from pytestqt.qtbot import QtBot
from buzz.locale import _
from buzz.db.entity.transcription import Transcription
from buzz.db.entity.transcription_segment import TranscriptionSegment
from buzz.model_loader import ModelType, WhisperModelSize
from buzz.transcriber.transcriber import Task
from buzz.widgets.transcription_viewer.transcription_view_mode_tool_button import (
TranscriptionViewModeToolButton,
ViewMode
)
from buzz.widgets.transcription_viewer.transcription_segments_editor_widget import (
TranscriptionSegmentsEditorWidget,
)
@ -32,9 +38,9 @@ class TestTranscriptionViewerWidget:
whisper_model_size=WhisperModelSize.SMALL.value,
)
)
transcription_segment_dao.insert(TranscriptionSegment(40, 299, "Bien", str(id)))
transcription_segment_dao.insert(TranscriptionSegment(40, 299, "Bien", "", str(id)))
transcription_segment_dao.insert(
TranscriptionSegment(299, 329, "venue dans", str(id))
TranscriptionSegment(299, 329, "venue dans", "", str(id))
)
return transcription_dao.find_by_id(str(id))
@ -55,6 +61,8 @@ class TestTranscriptionViewerWidget:
assert editor.model().index(0, 1).data() == 299
assert editor.model().index(0, 2).data() == 40
assert editor.model().index(0, 3).data() == "Bien"
widget.close()
time.sleep(3)
def test_should_update_segment_text(
self, qtbot, transcription, transcription_service, shortcuts
@ -68,3 +76,27 @@ class TestTranscriptionViewerWidget:
assert isinstance(editor, TranscriptionSegmentsEditorWidget)
editor.model().setData(editor.model().index(0, 3), "Biens")
widget.close()
time.sleep(3)
def test_text_button_changes_view_mode(
self, qtbot, transcription, transcription_service, shortcuts
):
widget = TranscriptionViewerWidget(
transcription, transcription_service, shortcuts
)
qtbot.add_widget(widget)
view_mode_tool_button = widget.findChild(TranscriptionViewModeToolButton)
menu = view_mode_tool_button.menu()
text_action = next(action for action in menu.actions() if action.text() == _("Text"))
text_action.trigger()
assert widget.view_mode == ViewMode.TEXT
text_action = next(action for action in menu.actions() if action.text() == _("Translation"))
text_action.trigger()
assert widget.view_mode == ViewMode.TRANSLATION
widget.close()
time.sleep(3)