diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 993aced3..5f04cb80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,7 @@ jobs: - os: windows-latest - os: ubuntu-20.04 - os: ubuntu-22.04 + - os: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: @@ -31,7 +32,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: "3.10.11" + python-version: "3.11.9" - name: Install Poetry Action uses: snok/install-poetry@v1.3.1 @@ -70,7 +71,10 @@ jobs: - name: Install apt dependencies run: | sudo apt-get update - sudo apt-get install --no-install-recommends libyaml-dev libegl1-mesa libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libportaudio2 gettext libpulse0 + if [ "$(lsb_release -rs)" != "24.04" ]; then + sudo apt-get install --no-install-recommends libegl1-mesa + fi + sudo apt-get install --no-install-recommends libyaml-dev libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libportaudio2 gettext libpulse0 if: "startsWith(matrix.os, 'ubuntu-')" - name: Test @@ -100,7 +104,7 @@ jobs: submodules: recursive - uses: actions/setup-python@v5 with: - python-version: "3.10.11" + python-version: "3.11.9" - name: Install Poetry Action uses: snok/install-poetry@v1.3.1 @@ -134,7 +138,10 @@ jobs: - name: Install apt dependencies run: | sudo apt-get update - sudo apt-get install --no-install-recommends libyaml-dev libegl1-mesa libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libportaudio2 gettext libpulse0 + if [ "$(lsb_release -rs)" != "24.04" ]; then + sudo apt-get install --no-install-recommends libegl1-mesa + fi + sudo apt-get install --no-install-recommends libyaml-dev libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libportaudio2 gettext libpulse0 if: "startsWith(matrix.os, 'ubuntu-')" - name: Install FPM @@ -209,7 +216,7 @@ jobs: submodules: recursive - uses: actions/setup-python@v5 with: - python-version: "3.10.11" + python-version: "3.11.9" - name: Install Poetry Action uses: snok/install-poetry@v1.3.1 with: diff --git a/.github/workflows/manual-build.yml b/.github/workflows/manual-build.yml index 6cdcf021..f1ea1c04 100644 --- a/.github/workflows/manual-build.yml +++ b/.github/workflows/manual-build.yml @@ -21,7 +21,7 @@ jobs: submodules: recursive - uses: actions/setup-python@v5 with: - python-version: "3.10.11" + python-version: "3.11.9" - name: Install Poetry Action uses: snok/install-poetry@v1.3.1 diff --git a/.gitignore b/.gitignore index f3f8ae69..39bd402a 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ benchmarks.json .eggs *.egg-info +/coverage/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 91eaa593..2342e7a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,19 +43,19 @@ Linux versions get also pushed to the snap. To install latest development versio 1. Clone the repository `git clone --recursive https://github.com/chidiwilliams/buzz.git` 2. Enter repo folder `cd buzz` -3. Install Poetry `apt-get install python3-poetry` +3. Install Poetry `sudo apt-get install python3-poetry` 4. Activate the virtual environment `poetry shell` 5. Install the dependencies `poetry install` 6. Install system dependencies you may be missing ``` -sudo apt-get install --no-install-recommends libyaml-dev libegl1-mesa libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libportaudio2 gettext libpulse0 ffmpeg +sudo apt-get install --no-install-recommends libyaml-dev libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libportaudio2 gettext libpulse0 ffmpeg ``` 7. Build Buzz `poetry build` 8. Run Buzz `python -m buzz` ### Windows -Assumes you have [Git](https://git-scm.com/downloads) and [python <3.11](https://www.python.org/downloads) installed and added to PATH. +Assumes you have [Git](https://git-scm.com/downloads) and [python](https://www.python.org/downloads) installed and added to PATH. 1. Install the chocolatey package manager for Windows. [More info](https://docs.chocolatey.org/en-us/choco/setup) ``` diff --git a/buzz/locale/lv_LV/LC_MESSAGES/buzz.po b/buzz/locale/lv_LV/LC_MESSAGES/buzz.po index 6702ae06..bc9bf0e9 100644 --- a/buzz/locale/lv_LV/LC_MESSAGES/buzz.po +++ b/buzz/locale/lv_LV/LC_MESSAGES/buzz.po @@ -8,118 +8,20 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-14 18:59+0300\n" -"PO-Revision-Date: 2024-06-14 19:01+0300\n" +"POT-Creation-Date: 2024-06-15 17:36+0300\n" +"PO-Revision-Date: 2024-06-15 17:37+0300\n" "Last-Translator: \n" "Language-Team: \n" "Language: lv_LV\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.4.3\n" +"X-Generator: Poedit 3.4.2\n" -#: buzz/settings/shortcut.py:17 -msgid "Open Record Window" -msgstr "Atvērt ieraksta logu" - -#: buzz/settings/shortcut.py:18 -msgid "Import File" -msgstr "Importēt failu" - -#: buzz/settings/shortcut.py:19 buzz/widgets/import_url_dialog.py:19 +#: buzz/widgets/import_url_dialog.py:19 buzz/settings/shortcut.py:19 msgid "Import URL" msgstr "Importēt URL" -#: buzz/settings/shortcut.py:20 -msgid "Open Preferences Window" -msgstr "Atvērt iestatījumu logu" - -#: buzz/settings/shortcut.py:22 -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: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:27 buzz/widgets/main_window_toolbar.py:52 -msgid "Cancel Transcription" -msgstr "Atcelt atpazīšanu" - -#: 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: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:77 -msgid "Queued" -msgstr "Ierindots" - -#: buzz/widgets/transcription_tasks_table_widget.py:85 -msgid "File Name / URL" -msgstr "Fails / URL" - -#: buzz/widgets/transcription_tasks_table_widget.py:97 -msgid "Model" -msgstr "Modelis" - -#: buzz/widgets/transcription_tasks_table_widget.py:106 -msgid "Task" -msgstr "Uzdevums" - -#: buzz/widgets/transcription_tasks_table_widget.py:115 -msgid "Status" -msgstr "Statuss" - -#: buzz/widgets/transcription_tasks_table_widget.py:123 -msgid "Date Added" -msgstr "Pievienots" - -#: buzz/widgets/transcription_tasks_table_widget.py:134 -msgid "Date Completed" -msgstr "Pabeigts" - -#: buzz/widgets/main_window_toolbar.py:35 buzz/widgets/record_button.py:10 -#: buzz/widgets/record_button.py:17 -msgid "Record" -msgstr "Ierakstīt" - -#: buzz/widgets/main_window_toolbar.py:39 -msgid "New Transcription" -msgstr "Jauna atpazīšanas" - -#: buzz/widgets/main_window_toolbar.py:46 -msgid "Open Transcript" -msgstr "Atvērt transkriptu" - -#: buzz/widgets/about_dialog.py:80 -msgid "Check for updates" -msgstr "Pārbaudīt atjauninājumus" - -#: buzz/widgets/about_dialog.py:109 -msgid "You're up to date!" -msgstr "Jums ir jaunākā versija!" - #: buzz/widgets/import_url_dialog.py:22 msgid "https://example.com/audio.mp3" msgstr "https://example.com/audio.mp3" @@ -136,153 +38,168 @@ msgstr "Adrese nav derīga" msgid "The URL you entered is invalid." msgstr "Jūsu ievadītā URL adrese nav derīga." -#: buzz/widgets/recording_transcriber_widget.py:66 -msgid "Live Recording" -msgstr "Dzīvā ierakstīšana" +#: buzz/widgets/preferences_dialog/shortcuts_editor_preferences_widget.py:29 +msgid "Reset to Defaults" +msgstr "Atjaunot noklusētos" -#: buzz/widgets/recording_transcriber_widget.py:125 -msgid "Click Record to begin..." -msgstr "Klikšķiniet Ierakstīt, lai sāktu..." +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:44 +msgid "Test" +msgstr "Pārbaudīt" -#: buzz/widgets/recording_transcriber_widget.py:128 -msgid "Waiting for AI translation..." -msgstr "Gaida MI tulkojumu..." +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:50 +msgid "OpenAI API key" +msgstr "OpenAI API atslēga" -#: buzz/widgets/recording_transcriber_widget.py:140 -msgid "Microphone:" -msgstr "Mikrofons:" +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:63 +msgid "OpenAI base url" +msgstr "OpenAI adrese" -#: buzz/widgets/recording_transcriber_widget.py:391 -msgid "An error occurred while starting a new recording:" -msgstr "Sākot jaunu ierakstu notikusi kļūda:" +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:72 +msgid "Default export file name" +msgstr "Eksporta fails" -#: buzz/widgets/recording_transcriber_widget.py:395 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:78 +msgid "Enable live recording transcription export" +msgstr "Eksportēt dzīvā ieraksta transkriptus" + +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:84 +#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 +#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 +msgid "Browse" +msgstr "Izvēlēties" + +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:103 +msgid "Export folder" +msgstr "Eksportēt mapē" + +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:128 +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:134 +msgid "OpenAI API Key Test" +msgstr "OpenAI API atslēgas pārbaude" + +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:129 msgid "" -"Please check your audio devices or check the application logs for more " -"information." +"Your API key is valid. Buzz will use this key to perform Whisper API " +"transcriptions and AI translations with ChatGPT." msgstr "" -"Lūdzu pārbaudiet savas audio ierīces vai pārbaudiet lietotnes ziņojumu " -"žurnālus, lai iegūtu papildu informāciju." +"Jūsu API atslēga ir derīga. Buzz izmantos to runas atpazīšanai ar Whisper " +"API un tulkošanai ar ChatGPT." -#: buzz/widgets/snap_notice.py:9 -msgid "Snap permission notice" -msgstr "Snap atļauju piezīme" +#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 +msgid "Select Export Folder" +msgstr "Izvēlieties mapi kurā eksportēt" -#: buzz/widgets/snap_notice.py:13 -msgid "" -"Detected missing permissions, please check that snap permissions have been " -"granted" -msgstr "" -"Ne visi nepieciešamie moduļi darbojas korekti, iespējams nav piešķirtas snap " -"atļaujas" +#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:42 +msgid "Enable folder watch" +msgstr "Ieslēgt mapes vērošanu" -#: buzz/widgets/snap_notice.py:16 -msgid "" -"To enable necessary permissions run the following commands in the terminal" -msgstr "Lai piešķirtu nepieciešamās atļaujas izpildiet šīs komandas" +#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:94 +msgid "Input folder" +msgstr "Vērojamā mape" -#: buzz/widgets/snap_notice.py:30 -msgid "Close" -msgstr "Aizvērt" +#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:95 +msgid "Output folder" +msgstr "Rezultātu mape" -#: buzz/widgets/menu_bar.py:38 -msgid "Import File..." -msgstr "Importēt failu..." +#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:105 +msgid "Select Input Folder" +msgstr "Izvēlieties vērojamo mapi" -#: buzz/widgets/menu_bar.py:41 -msgid "Import URL..." -msgstr "Importēt URL..." +#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:114 +msgid "Select Output Folder" +msgstr "Izvēlieties rezultātu mapi" -#: buzz/widgets/menu_bar.py:47 -msgid "Preferences..." -msgstr "Iestatījumi..." +#: buzz/widgets/preferences_dialog/preferences_dialog.py:43 +msgid "Preferences" +msgstr "Iestatījumi" -#: buzz/widgets/menu_bar.py:55 -msgid "File" -msgstr "Fails" +#: buzz/widgets/preferences_dialog/preferences_dialog.py:50 +msgid "General" +msgstr "Vispārīgi" -#: buzz/widgets/menu_bar.py:59 -msgid "Help" -msgstr "Palīdzība" +#: buzz/widgets/preferences_dialog/preferences_dialog.py:53 +msgid "Models" +msgstr "Modeļi" -#: buzz/widgets/main_window.py:224 -msgid "" -"Are you sure you want to delete the selected transcription(s)? This action " -"cannot be undone." -msgstr "" -"Vai tiešām vēlaties dzēst izvēlētos transkriptus? Šī ir neatgriezeniska " -"darbība." +#: buzz/widgets/preferences_dialog/preferences_dialog.py:57 +msgid "Shortcuts" +msgstr "Īsinājumi" -#: buzz/widgets/main_window.py:244 -msgid "Select audio file" -msgstr "Izvēlieties audio failu" +#: buzz/widgets/preferences_dialog/preferences_dialog.py:63 +msgid "Folder Watch" +msgstr "Mapes vērošana" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:61 +msgid "Group" +msgstr "Veids" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:70 +msgid "Download" +msgstr "Lejupielādēt" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:75 +msgid "Show file location" +msgstr "Pādīt faila atrašanās vietu" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:83 +msgid "Delete" +msgstr "Dzēst" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:120 +msgid "Downloaded" +msgstr "Lejupielādēts" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:125 +msgid "Available for Download" +msgstr "Pieejams lejupielādei" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:171 +msgid "Delete Model" +msgstr "Dzēst modeli" + +#: buzz/widgets/preferences_dialog/models_preferences_widget.py:172 +msgid "Are you sure you want to delete the selected model?" +msgstr "Vai tiešām dzēst izvēlēto modeli?" -#: buzz/widgets/main_window.py:280 #: buzz/widgets/preferences_dialog/models_preferences_widget.py:191 +#: buzz/widgets/main_window.py:282 msgid "Error" msgstr "Kļūda" -#: buzz/widgets/main_window.py:280 -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 -#: 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/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" - -#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:93 -msgid "Start" -msgstr "Sākums" - -#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:94 -msgid "End" -msgstr "Beigas" - -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:146 -msgid "Export" -msgstr "Eksportēt" - -#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:160 -msgid "Translate" -msgstr "Tulkot" - -#: 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:251 -msgid "Please enter OpenAI API Key in preferences" -msgstr "Lūdzu ievadiet OpenAI API atslēgu iestatījumos" +#: buzz/widgets/record_button.py:10 buzz/widgets/record_button.py:17 +#: buzz/widgets/main_window_toolbar.py:35 +msgid "Record" +msgstr "Ierakstīt" #: buzz/widgets/record_button.py:21 msgid "Stop" msgstr "Apturēt" +#: buzz/widgets/transcriber/languages_combo_box.py:25 +#: buzz/transcriber/transcriber.py:153 +msgid "Detect Language" +msgstr "Noteikt valodu" + +#: buzz/widgets/transcriber/file_transcriber_widget.py:79 +msgid "Run" +msgstr "Apstrādāt" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:86 +msgid "Model:" +msgstr "Modelis:" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:90 +msgid "Task:" +msgstr "Uzdevums:" + +#: buzz/widgets/transcriber/transcription_options_group_box.py:91 +msgid "Language:" +msgstr "Valoda:" + +#: buzz/widgets/transcriber/initial_prompt_text_edit.py:10 +msgid "Enter prompt..." +msgstr "Ievadiet vaicājumu..." + #: buzz/widgets/transcriber/advanced_settings_dialog.py:33 msgid "Advanced Settings" msgstr "Papildu iestatījumi" @@ -337,150 +254,238 @@ msgstr "Eksportēt:" msgid "Advanced..." msgstr "Papildu iestatījumi..." -#: buzz/widgets/transcriber/initial_prompt_text_edit.py:10 -msgid "Enter prompt..." -msgstr "Ievadiet vaicājumu..." +#: buzz/widgets/main_window_toolbar.py:39 +msgid "New Transcription" +msgstr "Jauna atpazīšanas" -#: buzz/widgets/transcriber/transcription_options_group_box.py:86 -msgid "Model:" -msgstr "Modelis:" +#: buzz/widgets/main_window_toolbar.py:46 +msgid "Open Transcript" +msgstr "Atvērt transkriptu" -#: buzz/widgets/transcriber/transcription_options_group_box.py:90 -msgid "Task:" -msgstr "Uzdevums:" +#: buzz/widgets/main_window_toolbar.py:52 buzz/settings/shortcut.py:27 +msgid "Cancel Transcription" +msgstr "Atcelt atpazīšanu" -#: buzz/widgets/transcriber/transcription_options_group_box.py:91 -msgid "Language:" -msgstr "Valoda:" +#: buzz/widgets/main_window_toolbar.py:60 buzz/widgets/main_window.py:224 +#: buzz/settings/shortcut.py:26 +msgid "Clear History" +msgstr "Notīrīt vēsturi" -#: buzz/widgets/transcriber/languages_combo_box.py:25 -#: buzz/transcriber/transcriber.py:153 -msgid "Detect Language" -msgstr "Noteikt valodu" +#: buzz/widgets/transcription_tasks_table_widget.py:62 +msgid "In Progress" +msgstr "Apstrādā" -#: buzz/widgets/transcriber/file_transcriber_widget.py:79 -msgid "Run" -msgstr "Apstrādāt" +#: buzz/widgets/transcription_tasks_table_widget.py:65 +msgid "Completed" +msgstr "Pabeigts" -#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:42 -msgid "Enable folder watch" -msgstr "Ieslēgt mapes vērošanu" +#: buzz/widgets/transcription_tasks_table_widget.py:72 +msgid "Failed" +msgstr "Neizdevās" -#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:47 -#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:50 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:84 -msgid "Browse" -msgstr "Izvēlēties" +#: buzz/widgets/transcription_tasks_table_widget.py:75 +msgid "Canceled" +msgstr "Atcelts" -#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:94 -msgid "Input folder" -msgstr "Vērojamā mape" +#: buzz/widgets/transcription_tasks_table_widget.py:77 +msgid "Queued" +msgstr "Ierindots" -#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:95 -msgid "Output folder" -msgstr "Rezultātu mape" +#: buzz/widgets/transcription_tasks_table_widget.py:83 +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:154 +msgid "Translate" +msgstr "Tulkot" -#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:105 -msgid "Select Input Folder" -msgstr "Izvēlieties vērojamo mapi" +#: buzz/widgets/transcription_tasks_table_widget.py:84 +msgid "Tanscribe" +msgstr "Atpazīt" -#: buzz/widgets/preferences_dialog/folder_watch_preferences_widget.py:114 -msgid "Select Output Folder" -msgstr "Izvēlieties rezultātu mapi" +#: buzz/widgets/transcription_tasks_table_widget.py:90 +msgid "File Name / URL" +msgstr "Fails / URL" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:44 -msgid "Test" -msgstr "Pārbaudīt" +#: buzz/widgets/transcription_tasks_table_widget.py:102 +msgid "Model" +msgstr "Modelis" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:50 -msgid "OpenAI API key" -msgstr "OpenAI API atslēga" +#: buzz/widgets/transcription_tasks_table_widget.py:111 +msgid "Task" +msgstr "Uzdevums" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:63 -msgid "OpenAI base url" -msgstr "OpenAI adrese" +#: buzz/widgets/transcription_tasks_table_widget.py:120 +msgid "Status" +msgstr "Statuss" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:72 -msgid "Default export file name" -msgstr "Eksporta fails" +#: buzz/widgets/transcription_tasks_table_widget.py:128 +msgid "Date Added" +msgstr "Pievienots" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:78 -msgid "Enable live recording transcription export" -msgstr "Eksportēt dzīvā ieraksta transkriptus" +#: buzz/widgets/transcription_tasks_table_widget.py:139 +msgid "Date Completed" +msgstr "Pabeigts" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:103 -msgid "Export folder" -msgstr "Eksportēt mapē" +#: buzz/widgets/recording_transcriber_widget.py:66 +msgid "Live Recording" +msgstr "Dzīvā ierakstīšana" -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:128 -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:134 -msgid "OpenAI API Key Test" -msgstr "OpenAI API atslēgas pārbaude" +#: buzz/widgets/recording_transcriber_widget.py:125 +msgid "Click Record to begin..." +msgstr "Klikšķiniet Ierakstīt, lai sāktu..." -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:129 +#: buzz/widgets/recording_transcriber_widget.py:128 +msgid "Waiting for AI translation..." +msgstr "Gaida MI tulkojumu..." + +#: buzz/widgets/recording_transcriber_widget.py:140 +msgid "Microphone:" +msgstr "Mikrofons:" + +#: buzz/widgets/recording_transcriber_widget.py:391 +msgid "An error occurred while starting a new recording:" +msgstr "Sākot jaunu ierakstu notikusi kļūda:" + +#: buzz/widgets/recording_transcriber_widget.py:395 msgid "" -"Your API key is valid. Buzz will use this key to perform Whisper API " -"transcriptions and AI translations with ChatGPT." +"Please check your audio devices or check the application logs for more " +"information." msgstr "" -"Jūsu API atslēga ir derīga. Buzz izmantos to runas atpazīšanai ar Whisper " -"API un tulkošanai ar ChatGPT." +"Lūdzu pārbaudiet savas audio ierīces vai pārbaudiet lietotnes ziņojumu " +"žurnālus, lai iegūtu papildu informāciju." -#: buzz/widgets/preferences_dialog/general_preferences_widget.py:156 -msgid "Select Export Folder" -msgstr "Izvēlieties mapi kurā eksportēt" +#: buzz/widgets/about_dialog.py:80 +msgid "Check for updates" +msgstr "Pārbaudīt atjauninājumus" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:61 -msgid "Group" -msgstr "Veids" +#: buzz/widgets/about_dialog.py:109 +msgid "You're up to date!" +msgstr "Jums ir jaunākā versija!" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:70 -msgid "Download" -msgstr "Lejupielādēt" +#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:93 +msgid "Start" +msgstr "Sākums" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:75 -msgid "Show file location" -msgstr "Pādīt faila atrašanās vietu" +#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:94 +msgid "End" +msgstr "Beigas" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:83 -msgid "Delete" -msgstr "Dzēst" +#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:95 +#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:34 +#: buzz/widgets/transcription_viewer/export_transcription_menu.py:39 +msgid "Text" +msgstr "Teksts" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:120 -msgid "Downloaded" -msgstr "Lejupielādēts" +#: buzz/widgets/transcription_viewer/transcription_segments_editor_widget.py:96 +#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:40 +#: buzz/widgets/transcription_viewer/export_transcription_menu.py:40 +#: buzz/widgets/transcription_viewer/export_transcription_menu.py:62 +msgid "Translation" +msgstr "Tulkojums" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:125 -msgid "Available for Download" -msgstr "Pieejams lejupielādei" +#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:26 +msgid "View" +msgstr "Skats" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:171 -msgid "Delete Model" -msgstr "Dzēst modeli" +#: buzz/widgets/transcription_viewer/transcription_view_mode_tool_button.py:46 +msgid "Timestamps" +msgstr "Laiks" -#: buzz/widgets/preferences_dialog/models_preferences_widget.py:172 -msgid "Are you sure you want to delete the selected model?" -msgstr "Vai tiešām dzēst izvēlēto modeli?" +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:140 +msgid "Export" +msgstr "Eksportēt" -#: buzz/widgets/preferences_dialog/shortcuts_editor_preferences_widget.py:29 -msgid "Reset to Defaults" -msgstr "Atjaunot noklusētos" +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244 +msgid "API Key Required" +msgstr "API atslēgas kļūda" -#: buzz/widgets/preferences_dialog/preferences_dialog.py:43 -msgid "Preferences" -msgstr "Iestatījumi" +#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:245 +msgid "Please enter OpenAI API Key in preferences" +msgstr "Lūdzu ievadiet OpenAI API atslēgu iestatījumos" -#: buzz/widgets/preferences_dialog/preferences_dialog.py:50 -msgid "General" -msgstr "Vispārīgi" +#: buzz/widgets/transcription_viewer/export_transcription_menu.py:76 +msgid "Save File" +msgstr "Saglabāt failu" -#: buzz/widgets/preferences_dialog/preferences_dialog.py:53 -msgid "Models" -msgstr "Modeļi" +#: buzz/widgets/transcription_viewer/export_transcription_menu.py:78 +msgid "Text files" +msgstr "Teksta faili" -#: buzz/widgets/preferences_dialog/preferences_dialog.py:57 -msgid "Shortcuts" -msgstr "Īsinājumi" +#: buzz/widgets/snap_notice.py:9 +msgid "Snap permission notice" +msgstr "Snap atļauju piezīme" -#: buzz/widgets/preferences_dialog/preferences_dialog.py:63 -msgid "Folder Watch" -msgstr "Mapes vērošana" +#: buzz/widgets/snap_notice.py:13 +msgid "" +"Detected missing permissions, please check that snap permissions have been " +"granted" +msgstr "" +"Ne visi nepieciešamie moduļi darbojas korekti, iespējams nav piešķirtas snap " +"atļaujas" + +#: buzz/widgets/snap_notice.py:16 +msgid "" +"To enable necessary permissions run the following commands in the terminal" +msgstr "Lai piešķirtu nepieciešamās atļaujas izpildiet šīs komandas" + +#: buzz/widgets/snap_notice.py:30 +msgid "Close" +msgstr "Aizvērt" + +#: buzz/widgets/menu_bar.py:38 +msgid "Import File..." +msgstr "Importēt failu..." + +#: buzz/widgets/menu_bar.py:41 +msgid "Import URL..." +msgstr "Importēt URL..." + +#: buzz/widgets/menu_bar.py:47 +msgid "Preferences..." +msgstr "Iestatījumi..." + +#: buzz/widgets/menu_bar.py:55 +msgid "File" +msgstr "Fails" + +#: buzz/widgets/menu_bar.py:59 +msgid "Help" +msgstr "Palīdzība" + +#: buzz/widgets/main_window.py:226 +msgid "" +"Are you sure you want to delete the selected transcription(s)? This action " +"cannot be undone." +msgstr "" +"Vai tiešām vēlaties dzēst izvēlētos transkriptus? Šī ir neatgriezeniska " +"darbība." + +#: buzz/widgets/main_window.py:246 +msgid "Select audio file" +msgstr "Izvēlieties audio failu" + +#: buzz/widgets/main_window.py:282 +msgid "Unable to save OpenAI API key to keyring" +msgstr "Neizdevās saglabāt OpenAI API atslēgu atslēgu saišķī" + +#: buzz/settings/shortcut.py:17 +msgid "Open Record Window" +msgstr "Atvērt ieraksta logu" + +#: buzz/settings/shortcut.py:18 +msgid "Import File" +msgstr "Importēt failu" + +#: buzz/settings/shortcut.py:20 +msgid "Open Preferences Window" +msgstr "Atvērt iestatījumu logu" + +#: buzz/settings/shortcut.py:22 +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" diff --git a/buzz/transcriber/recording_transcriber.py b/buzz/transcriber/recording_transcriber.py index a827346f..13eed205 100644 --- a/buzz/transcriber/recording_transcriber.py +++ b/buzz/transcriber/recording_transcriber.py @@ -33,6 +33,7 @@ class RecordingTranscriber(QObject): input_device_index: Optional[int], sample_rate: int, model_path: str, + sounddevice: sounddevice, parent: Optional[QObject] = None, ) -> None: super().__init__(parent) @@ -46,6 +47,7 @@ class RecordingTranscriber(QObject): self.max_queue_size = 3 * self.n_batch_samples self.queue = np.ndarray([], dtype=np.float32) self.mutex = threading.Lock() + self.sounddevice = sounddevice def start(self): model_path = self.model_path @@ -72,7 +74,7 @@ class RecordingTranscriber(QObject): self.is_running = True try: - with sounddevice.InputStream( + with self.sounddevice.InputStream( samplerate=self.sample_rate, device=self.input_device_index, dtype="float32", diff --git a/buzz/widgets/recording_transcriber_widget.py b/buzz/widgets/recording_transcriber_widget.py index 3eada2fc..60140298 100644 --- a/buzz/widgets/recording_transcriber_widget.py +++ b/buzz/widgets/recording_transcriber_widget.py @@ -2,8 +2,9 @@ import os import enum import logging import datetime +import sounddevice from enum import auto -from typing import Optional, Tuple +from typing import Optional, Tuple, Any from PyQt6.QtCore import QThread, Qt, QThreadPool from PyQt6.QtGui import QTextCursor, QCloseEvent @@ -51,9 +52,13 @@ class RecordingTranscriberWidget(QWidget): RECORDING = auto() def __init__( - self, parent: Optional[QWidget] = None, flags: Optional[Qt.WindowType] = None + self, + parent: Optional[QWidget] = None, + flags: Optional[Qt.WindowType] = None, + custom_sounddevice: Optional[Any] = None, ) -> None: super().__init__(parent) + self.sounddevice = custom_sounddevice or sounddevice if flags is not None: self.setWindowFlags(flags) @@ -267,6 +272,7 @@ class RecordingTranscriberWidget(QWidget): sample_rate=self.device_sample_rate, transcription_options=self.transcription_options, model_path=model_path, + sounddevice=self.sounddevice, ) self.transcriber.moveToThread(self.transcription_thread) diff --git a/buzz/widgets/transcription_tasks_table_widget.py b/buzz/widgets/transcription_tasks_table_widget.py index b0ddb6b5..ed8f12bb 100644 --- a/buzz/widgets/transcription_tasks_table_widget.py +++ b/buzz/widgets/transcription_tasks_table_widget.py @@ -21,7 +21,7 @@ from PyQt6.QtWidgets import ( from buzz.db.entity.transcription import Transcription from buzz.locale import _ from buzz.settings.settings import Settings -from buzz.transcriber.transcriber import FileTranscriptionTask +from buzz.transcriber.transcriber import FileTranscriptionTask, Task from buzz.widgets.record_delegate import RecordDelegate from buzz.widgets.transcription_record import TranscriptionRecord @@ -79,6 +79,11 @@ def format_record_status_text(record: QSqlRecord) -> str: return "" +task_label_translations = { + Task.TRANSLATE: _("Translate"), + Task.TRANSCRIBE: _("Tanscribe"), +} + column_definitions = [ ColDef( id="file_name", @@ -107,7 +112,7 @@ column_definitions = [ column=Column.SOURCE, width=120, delegate=RecordDelegate( - text_getter=lambda record: record.value("task").capitalize() + text_getter=lambda record: task_label_translations[Task(record.value("task"))] ), ), ColDef( diff --git a/poetry.lock b/poetry.lock index d693f9cc..21ab108e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "altgraph" @@ -58,7 +58,10 @@ files = [ [package.dependencies] lazy-object-proxy = ">=1.4.0" typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} -wrapt = {version = ">=1.11,<2", markers = "python_version < \"3.11\""} +wrapt = [ + {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, +] [[package]] name = "autopep8" @@ -2046,7 +2049,10 @@ files = [ [package.dependencies] astroid = ">=2.15.8,<=2.17.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = {version = ">=0.2", markers = "python_version < \"3.11\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, +] isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" @@ -3393,5 +3399,5 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" -python-versions = ">=3.9.13,<3.11" -content-hash = "0b674818a94169f61efde66d2230f4e1869d34223589b755d4ad5f6aca99653f" +python-versions = ">=3.9.13,<3.13" +content-hash = "a1e13cfbdeb7cae31b3162939e246d45a60f9e67d54df9c9aa86d33ca9fb3d88" diff --git a/pyproject.toml b/pyproject.toml index e82bbf5c..49e327a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ packages = [ ] [tool.poetry.dependencies] -python = ">=3.9.13,<3.11" +python = ">=3.9.13,<3.13" sounddevice = "^0.4.5" humanize = "^4.4.0" PyQt6 = "^6.4.0" diff --git a/tests/mock_sounddevice.py b/tests/mock_sounddevice.py index b85eb3d6..85bf4a14 100644 --- a/tests/mock_sounddevice.py +++ b/tests/mock_sounddevice.py @@ -98,7 +98,7 @@ mock_query_devices = [ ] -class MockInputStream(MagicMock): +class MockInputStream: running = False thread: Thread @@ -108,7 +108,6 @@ class MockInputStream(MagicMock): *args, **kwargs, ): - super().__init__(spec=sounddevice.InputStream) self.thread = Thread(target=self.target) self.callback = callback @@ -143,10 +142,29 @@ class MockInputStream(MagicMock): self.thread.join() def close(self): - pass + self.stop() def __enter__(self): self.start() def __exit__(self, exc_type, exc_val, exc_tb): self.stop() + + +class MockSoundDevice: + def __init__(self): + self.devices = mock_query_devices + + def InputStream(self, *args, **kwargs): + return MockInputStream(*args, **kwargs) + + def query_devices(self, device=None): + if device is None: + return self.devices + else: + return next((d for d in self.devices if d['index'] == device), None) + + def check_input_settings(self, device=None, samplerate=None): + device_info = self.query_devices(device) + if device_info and samplerate and samplerate != device_info['default_samplerate']: + raise ValueError('Invalid sample rate for device') \ No newline at end of file diff --git a/tests/transcriber/recording_transcriber_test.py b/tests/transcriber/recording_transcriber_test.py index c8ec6a14..ed538103 100644 --- a/tests/transcriber/recording_transcriber_test.py +++ b/tests/transcriber/recording_transcriber_test.py @@ -5,46 +5,46 @@ from PyQt6.QtCore import QThread from buzz.model_loader import TranscriptionModel, ModelType, WhisperModelSize from buzz.transcriber.recording_transcriber import RecordingTranscriber from buzz.transcriber.transcriber import TranscriptionOptions, Task -from tests.mock_sounddevice import MockInputStream +from tests.mock_sounddevice import MockSoundDevice from tests.model_loader import get_model_path class TestRecordingTranscriber: + def test_should_transcribe(self, qtbot): - thread = QThread() + with (patch("sounddevice.check_input_settings")): + thread = QThread() - transcription_model = TranscriptionModel( - model_type=ModelType.WHISPER_CPP, whisper_model_size=WhisperModelSize.TINY - ) + transcription_model = TranscriptionModel( + model_type=ModelType.WHISPER_CPP, whisper_model_size=WhisperModelSize.TINY + ) - model_path = get_model_path(transcription_model) - transcriber = RecordingTranscriber( - transcription_options=TranscriptionOptions( - model=transcription_model, language="fr", task=Task.TRANSCRIBE - ), - input_device_index=0, - sample_rate=16_000, - model_path=model_path, - ) - transcriber.moveToThread(thread) + model_path = get_model_path(transcription_model) - thread.started.connect(transcriber.start) - thread.finished.connect(thread.deleteLater) + transcriber = RecordingTranscriber( + transcription_options=TranscriptionOptions( + model=transcription_model, language="fr", task=Task.TRANSCRIBE + ), + input_device_index=0, + sample_rate=16_000, + model_path=model_path, + sounddevice=MockSoundDevice(), + ) + transcriber.moveToThread(thread) - mock_transcription = Mock() - transcriber.transcription.connect(mock_transcription) + thread.started.connect(transcriber.start) - transcriber.finished.connect(thread.quit) - transcriber.finished.connect(transcriber.deleteLater) + mock_transcription = Mock() + transcriber.transcription.connect(mock_transcription) - with (patch("sounddevice.InputStream", side_effect=MockInputStream), - patch("sounddevice.check_input_settings"), - qtbot.wait_signal(transcriber.transcription, timeout=60 * 1000)): - thread.start() + with qtbot.wait_signal(transcriber.transcription, timeout=60 * 1000): + thread.start() - with qtbot.wait_signal(thread.finished, timeout=60 * 1000): - if transcriber is not None: - transcriber.stop_recording() + transcriber.stop_recording() - text = mock_transcription.call_args[0][0] - assert "Bienvenue dans Passe" in text + text = mock_transcription.call_args[0][0] + assert "Bienvenue dans Passe" in text + + # Wait for the thread to finish + thread.quit() + thread.wait() diff --git a/tests/widgets/recording_transcriber_widget_test.py b/tests/widgets/recording_transcriber_widget_test.py index b23a138a..6d09e432 100644 --- a/tests/widgets/recording_transcriber_widget_test.py +++ b/tests/widgets/recording_transcriber_widget_test.py @@ -1,27 +1,28 @@ import os import time -import tempfile +import pytest import platform +import tempfile -from unittest.mock import Mock, patch +from unittest.mock import patch from pytestqt.qtbot import QtBot from buzz.locale import _ from buzz.widgets.recording_transcriber_widget import RecordingTranscriberWidget from buzz.settings.settings import Settings -from tests.mock_sounddevice import MockInputStream -import pytest +from tests.mock_sounddevice import MockSoundDevice, MockInputStream class TestRecordingTranscriberWidget: def test_should_set_window_title(self, qtbot: QtBot): with (patch("sounddevice.InputStream", side_effect=MockInputStream), - patch( - "buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate", - return_value=16_000), + patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate", + return_value=16_000), patch("sounddevice.check_input_settings")): - widget = RecordingTranscriberWidget() + widget = RecordingTranscriberWidget( + custom_sounddevice=MockSoundDevice() + ) qtbot.add_widget(widget) assert widget.windowTitle() == _("Live Recording") @@ -30,18 +31,17 @@ class TestRecordingTranscriberWidget: widget.close() - # on CI transcribed output is garbage, so we check if there is anything @pytest.mark.skipif( - platform.system() == "Darwin", - reason="Seg faults on CI", - ) + platform.system() == "Darwin" and platform.mac_ver()[0].startswith('13.'), + reason="Does not pick up mock sound device") def test_should_transcribe(self, qtbot): - with (patch("sounddevice.InputStream", side_effect=MockInputStream), - patch( + with (patch( "buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate", - return_value=16_000), - patch("sounddevice.check_input_settings")): - widget = RecordingTranscriberWidget() + return_value=16_000)): + + widget = RecordingTranscriberWidget( + custom_sounddevice=MockSoundDevice() + ) widget.device_sample_rate = 16_000 qtbot.add_widget(widget) @@ -59,11 +59,9 @@ class TestRecordingTranscriberWidget: assert len(widget.transcription_text_box.toPlainText()) > 0 widget.close() - # on CI transcribed output is garbage, so we check if there is anything @pytest.mark.skipif( - platform.system() == "Darwin", - reason="Seg faults on CI", - ) + platform.system() == "Darwin" and platform.mac_ver()[0].startswith('13.'), + reason="Does not pick up mock sound device") def test_should_transcribe_and_export(self, qtbot): settings = Settings() settings.set_value( @@ -76,16 +74,16 @@ class TestRecordingTranscriberWidget: except FileNotFoundError: pass - with (patch("sounddevice.InputStream", side_effect=MockInputStream), - patch( + with (patch( "buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate", return_value=16_000), - patch("sounddevice.check_input_settings"), patch( 'buzz.settings.settings.Settings.get_default_export_file_template', return_value='mock-export-file')): - widget = RecordingTranscriberWidget() + widget = RecordingTranscriberWidget( + custom_sounddevice=MockSoundDevice() + ) widget.device_sample_rate = 16_000 widget.export_enabled = True qtbot.add_widget(widget)