diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index b83ec18..d36c47b 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -24,7 +24,7 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@v4 with: - version: 6.7.* + version: 6.7.2 - uses: actions/setup-python@v5 with: python-version: '3.12' diff --git a/.gitignore b/.gitignore index d7106b8..2f7d61b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,6 @@ /dist /scripts/tools /release.json +/accent.json /.idea diff --git a/CHANGELOG.md b/CHANGELOG.md index c276ea2..646d87f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,9 @@ - [HUAWEI FreeBuds 5i & other] Fix SQ preference switch; - [Device compatibility] Add HUAWEI FreeLace Pro 2 compatibility; - Custom equalizer preset configuration (should also work with Pro 3); -- [Linux] Flatpak installation option +- [Linux] Flatpak as installation option +- [i18n] Add Spanish translation, thanks to @Pedro-vk (GitHub) +- [i18n] Add partial Portuguese (Brazilian), thanks to @Lobo (Accent) # Older releases WIP diff --git a/README.md b/README.md index 9e5ccc2..88337e1 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,19 @@

Last release Last AUR release -Translation level +Translated Test build status

-💿 Download binaries | 🌍 Suggest translation +💿 Download binaries | ❓ FAQ | 🌍 Suggest translation +

+

+Tray menu preview

-![Tray menu preview](docs/preview_0.png) - This application allows to control HUAWEI FreeBuds earphone settings from PC. Check exact battery level, toggle noise cancellation, control built-in equalizer, change gestures, and all other in-device settings and features are now available without official mobile application. Features @@ -52,8 +53,17 @@ May also work with newer/older devices in same series. If you want to get better Download & install ----------------- -Will be available after release. For now, you can grab test -binaries from [GitHub Actions](https://github.com/melianmiko/OpenFreebuds/actions/workflows/on_push.yml). +- **Windows**: [Download here](https://mmk.pw/en/openfreebuds/). +- **Debian/Ubuntu**: + +```shell +curl -s https://deb.mmk.pw/setup | sudo bash - +sudo apt install openfreebuds +``` +- **Arch Linux**: `openfreebuds` [available in AUR](https://aur.archlinux.org/packages/openfreebuds). +- **Flatpak**: _Coming soon_ + +Most recent `dev`-binaries can be found in [GitHub Actions](https://github.com/melianmiko/OpenFreebuds/actions/workflows/on_push.yml) build artifacts. Build or start from sources ------------- @@ -63,10 +73,12 @@ Requirements: - Windows 10/11, or enough modern Linux; - Qt 6.0+ development tools, at least Linguist's `lrelease`; - [Python](https://www.python.org/downloads/) (3.11+), [Poetry](https://python-poetry.org/docs/#installation) (1.8+); -- (Windows, optiona) [NSIS](https://nsis.sourceforge.io/Download), [UPX](https://upx.github.io/); +- (Windows, optional) [NSIS](https://nsis.sourceforge.io/Download), [UPX](https://upx.github.io/); - (Linux, optional) Build essentials and some libraries. -Setup poetry before continue: +Also, some dev-scripts may have their own requirements, like `python3-polib` for +`./scripts/sync_translations.sh`. Setup poetry env and dependencies before +continue: ```shell poetry install @@ -75,7 +87,12 @@ poetry install ### Just launch without installation ```shell +# Compile Qt Designer & Linguist sources +./scripts/make_qt_parts.sh + +# Launch poetry run python -m openfreebuds_qt -vcs + # use --help for options description ``` @@ -89,7 +106,7 @@ If everything above is installed & added to `PATH`, just run: Output binaries will be located in `scripts\build_win32\dist` -### Debian, Ubuntu +### Debian/Ubuntu Install all packaging dependencies automated way: `apt install build-essentials && ./scripts/install_dpkg_dependencies.sh`. diff --git a/docs/accent.json b/docs/accent.json new file mode 100644 index 0000000..c585346 --- /dev/null +++ b/docs/accent.json @@ -0,0 +1,11 @@ +{ + "apiUrl": "https://translate.mmk.pw", + "apiKey": "", + "files": [ + { + "format": "gettext", + "source": "openfreebuds_qt/assets/i18n/en.po", + "target": "openfreebuds_qt/assets/i18n/%slug%.po" + } + ] +} diff --git a/openfreebuds/driver/generic/spp.py b/openfreebuds/driver/generic/spp.py index cd3761d..5b766f1 100644 --- a/openfreebuds/driver/generic/spp.py +++ b/openfreebuds/driver/generic/spp.py @@ -33,7 +33,6 @@ async def start(self): sock.connect((self.device_address, self._spp_service_port)) reader, writer = await asyncio.open_connection(sock=sock) except (ConnectionResetError, ConnectionRefusedError, ConnectionAbortedError, OSError, ValueError): - log.exception("Driver startup failed") raise FbStartupError("Driver startup failed") self.__task_recv = asyncio.create_task(self._loop_recv(reader)) diff --git a/openfreebuds/driver/huawei/driver/generic.py b/openfreebuds/driver/huawei/driver/generic.py index 7dc56fc..12e2dd0 100644 --- a/openfreebuds/driver/huawei/driver/generic.py +++ b/openfreebuds/driver/huawei/driver/generic.py @@ -90,7 +90,7 @@ async def _handle_raw_pkg(self, pkg): pkg = HuaweiSppPackage.from_bytes(pkg) log.debug(f"RX {pkg}") except (AssertionError, OfbPackageChecksumError): - log.exception(f"Got non-parsable package {pkg.hex()}, ignoring") + log.info(f"Got non-parsable package {pkg.hex()}, ignoring") return if pkg.command_id in self.__pending_responses: @@ -159,7 +159,7 @@ async def init(self): async with asyncio.timeout(self.init_timeout): await self.on_init() break - except TimeoutError: + except (TimeoutError, ConnectionResetError): self.init_attempt += 1 except Exception: log.exception(f"Unknown error on {self.handler_id} init") diff --git a/openfreebuds/driver/huawei/handler/anc.py b/openfreebuds/driver/huawei/handler/anc.py index 3d3401f..826b87a 100644 --- a/openfreebuds/driver/huawei/handler/anc.py +++ b/openfreebuds/driver/huawei/handler/anc.py @@ -73,11 +73,10 @@ async def on_package(self, pkg: HuaweiSppPackage): # If cancellation turned on and support levels, list them new_props["level"] = self.cancel_level_options.get(data[0], data[0]) new_props["level_options"] = ",".join(self.cancel_level_options.values()) - - if data[1] == 2 and self.w_voice_boost: + elif data[1] == 2 and self.w_voice_boost: # If awareness turned on and support voice boost - new_props["level"] = "voice_boost" if data[0] != 0 else "normal" - new_props["level_options"] = "normal,voice_boost" + new_props["level"] = self.awareness_level_options.get(data[0], data[0]) + new_props["level_options"] = ",".join(self.awareness_level_options.values()) await self.driver.put_property("anc", None, new_props) diff --git a/openfreebuds/driver/huawei/handler/config_equalizer.py b/openfreebuds/driver/huawei/handler/config_equalizer.py index b7608c8..0414619 100644 --- a/openfreebuds/driver/huawei/handler/config_equalizer.py +++ b/openfreebuds/driver/huawei/handler/config_equalizer.py @@ -44,6 +44,7 @@ def __init__( self.changes_saved: bool = True self.custom_preset_values: dict[int, bytes] = {} + self.current_rollback_data: bytes = b"" self.options: Optional[dict[int, str]] = None if w_presets: self.options = {i: f"equalizer_preset_{name}" for i, name in w_presets.items()} @@ -77,7 +78,7 @@ async def _toggle_save(self, save: bool): data = b"".join([x.to_bytes(1, byteorder="big", signed=True) for x in json.loads(data)]) log.info(f"Will save persistent preset data={data}, mode_id={mode_id}") else: - data = self.custom_preset_values[mode_id] + data = self.current_rollback_data log.info(f"Will restore saved data={data}, mode_id={mode_id}") pkg = HuaweiSppPackage.change_rq( @@ -88,14 +89,18 @@ async def _toggle_save(self, save: bool): await self.driver.put_property("sound", "equalizer_rows", json.dumps(_eq_bytes_to_array(data))) await self.driver.put_property("sound", "equalizer_saved", "true") + self.changes_saved = True async def _change_current_mode(self, value: str): mode_str = await self.driver.get_property("sound", "equalizer_preset", None) mode_id = reverse_dict(self.options).get(mode_str) if mode_id is None: + log.info(f"Skip unknown mode {mode_str}/{mode_id}") return data = b"".join([x.to_bytes(1, byteorder="big", signed=True) for x in json.loads(value)]) + if self.changes_saved: + self.current_rollback_data = self.custom_preset_values[mode_id] log.info(f"Will replace id={mode_id}, label={mode_str} with data={data}") pkg = HuaweiSppPackage.change_rq( @@ -105,6 +110,7 @@ async def _change_current_mode(self, value: str): await self.driver.send_package(pkg) await self.driver.put_property("sound", "equalizer_rows", value) await self.driver.put_property("sound", "equalizer_saved", "false") + self.changes_saved = False async def _delete_current_mode(self): mode_str = await self.driver.get_property("sound", "equalizer_preset", None) @@ -159,6 +165,8 @@ async def _set_current_mode(self, mode_str): [(1, mode_id)] ) + self.changes_saved = True + await self.driver.send_package(pkg) await self.on_init() @@ -166,7 +174,8 @@ async def on_package(self, package: HuaweiSppPackage): new_props = { "equalizer_rows": None, "equalizer_saved": json.dumps(self.changes_saved), - "equalizer_rows_count": self.w_custom_max_count, + "equalizer_rows_count": str(self.w_custom_max_count), + "equalizer_max_custom_modes": str(self.w_custom_max_count) if self.w_custom else "0" } available_modes = package.find_param(3) diff --git a/openfreebuds/shortcuts.py b/openfreebuds/shortcuts.py index 828d32b..df6ea17 100644 --- a/openfreebuds/shortcuts.py +++ b/openfreebuds/shortcuts.py @@ -50,7 +50,6 @@ async def execute(self, shortcut, *args, no_catch: bool = False): return await handler(*args) except Exception as e: - log.exception(f"While triggering shortcut {shortcut}") if no_catch: raise e diff --git a/openfreebuds_backend/linux/linux_misc.py b/openfreebuds_backend/linux/linux_misc.py index 8183f0d..5024e89 100644 --- a/openfreebuds_backend/linux/linux_misc.py +++ b/openfreebuds_backend/linux/linux_misc.py @@ -47,5 +47,5 @@ def set_run_at_boot(val): def _get_autostart_file_path(): autostart_dir = pathlib.Path.home() / ".config/autostart" if not autostart_dir.exists(): - autostart_dir.mkdir() + autostart_dir.mkdir(parents=True) return str(autostart_dir / "openfreebuds.desktop") diff --git a/openfreebuds_qt/app/dialog/first_run.py b/openfreebuds_qt/app/dialog/first_run.py new file mode 100644 index 0000000..c241492 --- /dev/null +++ b/openfreebuds_qt/app/dialog/first_run.py @@ -0,0 +1,50 @@ +import sys +import webbrowser + +from PyQt6.QtCore import pyqtSlot +from PyQt6.QtWidgets import QDialog +from qasync import asyncSlot + +import openfreebuds_backend +from openfreebuds_qt.config import OfbQtConfigParser +from openfreebuds_qt.constants import LINK_WEBSITE_HELP +from openfreebuds_qt.designer.first_run_dialog import Ui_OfbQtFirstRunDialog +from openfreebuds_qt.utils import get_img_colored, qt_error_handler +from openfreebuds_qt.constants import WIN32_BODY_STYLE + + +class OfbQtFirstRunDialog(Ui_OfbQtFirstRunDialog, QDialog): + def __init__(self, ctx): + super().__init__(ctx.main_window) + + self.ctx = ctx + self.config = OfbQtConfigParser.get_instance() + + self.setupUi(self) + if sys.platform == "win32": + self.setStyleSheet(WIN32_BODY_STYLE) + + self.autostart_checkbox.setChecked(not self.config.is_containerized_app) + self.autostart_checkbox.setEnabled(not self.config.is_containerized_app) + self.linux_notice.setVisible(sys.platform == 'linux') + + preview_fn = "ofb_linux_preview" if sys.platform == 'linux' else "ofb_win32_preview" + preview_image = get_img_colored(preview_fn, + color=self.palette().text().color().getRgb(), + base_dir="image") + self.preview_root.setPixmap(preview_image) + + @asyncSlot() + async def on_confirm(self): + async with qt_error_handler("OfbQtFirstRunDialog_Confirm", self.ctx): + self.hide() + + if self.autostart_checkbox.isChecked(): + openfreebuds_backend.set_run_at_boot(True) + + self.config.set("ui", "first_run_finished", True) + self.config.save() + + @pyqtSlot() + def on_faq_click(self): + webbrowser.open(LINK_WEBSITE_HELP) diff --git a/openfreebuds_qt/app/dialog/manual_connect.py b/openfreebuds_qt/app/dialog/manual_connect.py index d753d29..5188d8a 100644 --- a/openfreebuds_qt/app/dialog/manual_connect.py +++ b/openfreebuds_qt/app/dialog/manual_connect.py @@ -1,14 +1,18 @@ +import sys from PyQt6.QtWidgets import QWidget from openfreebuds.driver import DEVICE_TO_DRIVER_MAP +from openfreebuds_qt.constants import WIN32_BODY_STYLE from openfreebuds_qt.utils.async_dialog import OfbQtAsyncDialog -from openfreebuds_qt.designer.dialog_manual_connect import Ui_Dialog +from openfreebuds_qt.designer.dialog_manual_connect import Ui_OfbQtManualConnectDialog -class OfbQtManualConnectDialog(Ui_Dialog, OfbQtAsyncDialog): +class OfbQtManualConnectDialog(Ui_OfbQtManualConnectDialog, OfbQtAsyncDialog): def __init__(self, parent: QWidget): super().__init__(parent) self.setupUi(self) + if sys.platform == "win32": + self.setStyleSheet(WIN32_BODY_STYLE) self.names = list(DEVICE_TO_DRIVER_MAP.keys()) self.profile_picker.addItems(self.names) diff --git a/openfreebuds_qt/app/dialog/rpc_config.py b/openfreebuds_qt/app/dialog/rpc_config.py index c4e0cc2..d27d3c7 100644 --- a/openfreebuds_qt/app/dialog/rpc_config.py +++ b/openfreebuds_qt/app/dialog/rpc_config.py @@ -1,20 +1,24 @@ import json +import sys from contextlib import suppress from PyQt6.QtWidgets import QWidget from openfreebuds import STORAGE_PATH from openfreebuds.utils.logger import create_logger -from openfreebuds_qt.designer.stupid_rpc_setup import Ui_Dialog +from openfreebuds_qt.constants import WIN32_BODY_STYLE +from openfreebuds_qt.designer.stupid_rpc_setup import Ui_OfbQtRpcConfig from openfreebuds_qt.utils import OfbQtAsyncDialog log = create_logger("OfbQtRpcConfig") -class OfbQtRpcConfig(Ui_Dialog, OfbQtAsyncDialog): +class OfbQtRpcConfig(Ui_OfbQtRpcConfig, OfbQtAsyncDialog): def __init__(self, parent: QWidget): super().__init__(parent) self.setupUi(self) + if sys.platform == "win32": + self.setStyleSheet(WIN32_BODY_STYLE) self.current_config = {} with suppress(Exception): diff --git a/openfreebuds_qt/app/main.py b/openfreebuds_qt/app/main.py index 0f0b72c..f13ff1b 100644 --- a/openfreebuds_qt/app/main.py +++ b/openfreebuds_qt/app/main.py @@ -18,15 +18,13 @@ OfbQtHotkeysModule, OfbQtGesturesModule, OfbQtDualConnectModule, OfbQtDeviceOtherSettingsModule, \ OfbQtDeviceInfoModule, OfbQtCommonModule, OfbQtChooseDeviceModule, OfbQtUiSettingsModule from openfreebuds_qt.config import ConfigLock, OfbQtConfigParser -from openfreebuds_qt.constants import ASSETS_PATH, LINK_RPC_HELP, LINK_WEBSITE_HELP +from openfreebuds_qt.constants import ASSETS_PATH, LINK_RPC_HELP, LINK_WEBSITE_HELP, WIN32_BODY_STYLE from openfreebuds_qt.designer.main_window import Ui_OfbMainWindowDesign from openfreebuds_qt.generic import IOfbQtApplication, IOfbMainWindow -from openfreebuds_qt.utils import qt_error_handler, OfbCoreEvent, OfbQtReportTool, get_qt_icon_colored +from openfreebuds_qt.utils import qt_error_handler, OfbCoreEvent, OfbQtReportTool, get_img_colored log = create_logger("OfbQtMainWindow") -WIN32_BODY_STYLE = "QPushButton, QComboBox { padding: 6px 12px; }" - class OfbQtMainWindow(Ui_OfbMainWindowDesign, IOfbMainWindow): def __init__(self, ctx: IOfbQtApplication): @@ -45,7 +43,7 @@ def __init__(self, ctx: IOfbQtApplication): # Extras button self.extra_options_button.setIcon( - get_qt_icon_colored("settings", self.palette().text().color().getRgb()) + QIcon(get_img_colored("settings", self.palette().text().color().getRgb())) ) self.extra_menu = QMenu() @@ -81,7 +79,7 @@ def __init__(self, ctx: IOfbQtApplication): self._attach_module(self.tr("Keyboard shortcuts"), OfbQtHotkeysModule(self.tabs.root, self.ctx)) if sys.platform == "linux": self._attach_module(self.tr("Linux-related"), OfbQtLinuxExtrasModule(self.tabs.root, self.ctx)) - self._attach_module(self.tr("About..."), OfbQtAboutModule(self.tabs.root, self.ctx)) + self._attach_module(self.tr("About…"), OfbQtAboutModule(self.tabs.root, self.ctx)) # Finish self.default_tab = 2, 0 @@ -97,19 +95,19 @@ def _fill_extras_menu(self): # noinspection PyUnresolvedReferences help_rpc_action.triggered.connect(lambda: webbrowser.open(LINK_RPC_HELP)) - bugreport_action = self.extra_menu.addAction(self.tr("Bugreport...")) + bugreport_action = self.extra_menu.addAction(self.tr("Bugreport…")) bugreport_action.setShortcut("F2") # noinspection PyUnresolvedReferences bugreport_action.triggered.connect(self.on_bugreport) - self.check_updates_action = self.extra_menu.addAction(self.tr("Check for updates...")) + self.check_updates_action = self.extra_menu.addAction(self.tr("Check for updates…")) # noinspection PyUnresolvedReferences self.check_updates_action.triggered.connect(self.on_check_updates) self.extra_menu.addSeparator() if self.ofb.role == "standalone" and ConfigLock.owned: - rpc_config_action = self.extra_menu.addAction(self.tr("Remote access...")) + rpc_config_action = self.extra_menu.addAction(self.tr("Remote access…")) # noinspection PyUnresolvedReferences rpc_config_action.triggered.connect(self.on_rpc_config) diff --git a/openfreebuds_qt/app/module/dual_connect.py b/openfreebuds_qt/app/module/dual_connect.py index ff420e7..6428edd 100644 --- a/openfreebuds_qt/app/module/dual_connect.py +++ b/openfreebuds_qt/app/module/dual_connect.py @@ -83,7 +83,10 @@ def _update_current_device_view(self, addr: str, data: dict): with blocked_signals(self.current_device_auto_connect): self.current_device_auto_connect.setEnabled(data.get("auto_connect") is not None) self.current_device_auto_connect.setChecked(data.get("auto_connect") or False) - self.button_toggle_connect.setText(self.tr("Disconnect" if data["connected"] else "Connect")) + + self.button_toggle_connect.setText( + self.tr("Disconnect") if data["connected"] else self.tr("Connect") + ) @asyncSlot(bool) async def on_set_preferred(self, state: bool): diff --git a/openfreebuds_qt/app/module/hotkeys_module.py b/openfreebuds_qt/app/module/hotkeys_module.py index 2a7a519..9dd590d 100644 --- a/openfreebuds_qt/app/module/hotkeys_module.py +++ b/openfreebuds_qt/app/module/hotkeys_module.py @@ -60,7 +60,7 @@ async def on_edit_shortcut(self, index: int, column: int): async with qt_error_handler("OfbQtHotkeysModule_EditShortcut", self.ctx): shortcut = self.all_shortcuts[index] log.info(f"Editing {shortcut}") - self.table.setItem(index, column, QTableWidgetItem(self.tr("Press new shortcut..."))) + self.table.setItem(index, column, QTableWidgetItem(self.tr("Press new shortcut…"))) self.service.stop() r = await self.recorder.record() diff --git a/openfreebuds_qt/app/module/linux_related.py b/openfreebuds_qt/app/module/linux_related.py index ea38605..59d22b2 100644 --- a/openfreebuds_qt/app/module/linux_related.py +++ b/openfreebuds_qt/app/module/linux_related.py @@ -49,9 +49,9 @@ async def on_mpris_toggle(self, value: bool): QMessageBox( QMessageBox.Icon.Information, self.tr("Ensure bus access"), - self.tr("Looks like you're running under Flatpak. To use this feature, OpenFreebuds" - "need to have access to entire session bus, otherwise it won't find any" - "working media players. Ensure that you're granted this permission," + self.tr("Looks like you're running under Flatpak. To use this feature, OpenFreebuds " + "need to have access to entire session bus, otherwise it won't find any " + "working media players. Ensure that you're granted this permission, " "refer to FAQ for more details."), QMessageBox.StandardButton.Ok, self diff --git a/openfreebuds_qt/app/module/sound_quality.py b/openfreebuds_qt/app/module/sound_quality.py index 7040270..03fd504 100644 --- a/openfreebuds_qt/app/module/sound_quality.py +++ b/openfreebuds_qt/app/module/sound_quality.py @@ -2,6 +2,7 @@ import json from PyQt6.QtCore import Qt +from PyQt6.QtGui import QIcon from PyQt6.QtWidgets import QSlider, QMenu, QInputDialog, QMessageBox, QFileDialog from qasync import asyncSlot @@ -10,6 +11,7 @@ from openfreebuds_qt.app.module.common import OfbQtCommonModule from openfreebuds_qt.designer.sound_quality import Ui_OfbQtSoundQualityModule from openfreebuds_qt.qt_i18n import get_eq_preset_names +from openfreebuds_qt.utils import get_img_colored from openfreebuds_qt.utils.async_dialog import run_dialog_async from openfreebuds_qt.utils.core_event import OfbCoreEvent from openfreebuds_qt.utils.qt_utils import fill_combo_box, blocked_signals, qt_error_handler @@ -37,6 +39,10 @@ def __init__(self, *args, **kwargs): self.setupUi(self) + self.undo_btn.setIcon( + QIcon(get_img_colored("undo", self.palette().text().color().getRgb())) + ) + self.custom_menu = QMenu() self.custom_edit_button.setMenu(self.custom_menu) for name, action in self.menu_actions: @@ -78,7 +84,7 @@ async def update_ui(self, event: OfbCoreEvent): if sound is None: return - self.custom_edit_button.setVisible("equalizer_rows" in sound) + self.custom_edit_button.setVisible(int(sound.get("equalizer_max_custom_modes", "0")) > 0) self.save_panel.setVisible(not json.loads(sound.get("equalizer_saved", "true"))) if event.is_changed("sound", "quality_preference"): @@ -184,7 +190,7 @@ async def export_file(self): return async with qt_error_handler("OfbQtSoundQualityModule_ExportFile", self.ctx): - dialog = QFileDialog(self, self.tr("Save equalizer preset to file...")) + dialog = QFileDialog(self, self.tr("Save equalizer preset to file…")) dialog.setWindowModality(Qt.WindowModality.WindowModal) dialog.setAcceptMode(QFileDialog.AcceptMode.AcceptSave) if not await run_dialog_async(dialog): @@ -199,7 +205,7 @@ async def export_file(self): @asyncSlot() async def load_file(self): async with qt_error_handler("OfbQtSoundQualityModule_LoadFile", self.ctx): - dialog = QFileDialog(self, self.tr("Load equalizer preset from file...")) + dialog = QFileDialog(self, self.tr("Load equalizer preset from file…")) dialog.setWindowModality(Qt.WindowModality.WindowModal) dialog.setAcceptMode(QFileDialog.AcceptMode.AcceptOpen) if not await run_dialog_async(dialog): diff --git a/openfreebuds_qt/app/widget/list_header.py b/openfreebuds_qt/app/widget/list_header.py index 87741f8..89997ad 100644 --- a/openfreebuds_qt/app/widget/list_header.py +++ b/openfreebuds_qt/app/widget/list_header.py @@ -7,7 +7,7 @@ def __init__(self, parent: QWidget, text: str = ""): self.setStyleSheet("font-weight: bold;" "font-size: 14px;" "padding: 8px 12px;" - "color: palette(link)") + "color: palette(highlight)") self.setText(text) def setText(self, a0: str): diff --git a/openfreebuds_qt/assets/i18n/en.ts b/openfreebuds_qt/assets/i18n/en.ts index 3c13f8c..d4ecddb 100644 --- a/openfreebuds_qt/assets/i18n/en.ts +++ b/openfreebuds_qt/assets/i18n/en.ts @@ -15,27 +15,7 @@ - Notice that this may be dangerous for some kind of devices. Do it of your risk. You also can share information about your device and selected profile at GitHub, if you want get offical support. - - - - - Manual connect - - - - - Enter bluetooth address of your device and select their model from list. You can find bluetooth address in system settings. - - - - - Bluetooth address: - - - - - Device profile: + Notice that this may be dangerous for some kind of devices. Continue only if you know what you're doing. @@ -91,48 +71,51 @@ - Intensity... + Intensity… - OfbDeviceEqualizerTrayMenu + OfbDeviceDualConnectTrayMenu - - Equalizer preset... + + Dual-connect… - OfbMainWindowDesign + OfbDeviceEqualizerTrayMenu - - OpenFreebuds + + Equalizer preset… + + + OfbMainWindowDesign - Exit + New version available, click here to view - - - OfbQtAboutModule - - Supported devices + + Hide - - Libraries + + Update now - - About + + Exit + + + OfbQtAboutModule Client application for HUAWEI FreeBuds wireless earphone series. Free and open source. @@ -148,47 +131,27 @@ Source code - - - OfbQtCommonWithShortcutsModule - - - Connect device - - - - - Disconnect device - - - - - Connect/disconnect device - - - - - Next noise control mode - - - - Disable noise control + + Supported devices - - Enable noise cancellation + + Libraries + + + OfbQtApplication - - Enable awareness mode + + You're running under older version of Qt than expected. It's strongly recommended to switch to Flatpak release, because older Qt version may fail your experience of using OpenFreebuds. - - Enable low-latency mode + + This warning will be shown only once. Please, test Flatpak version before reporting bugs. @@ -204,7 +167,7 @@ OfbQtDeviceInfoModule - Deice information + Firmware version: @@ -219,32 +182,27 @@ - Device name + Property - Firmware version: + Value - Property + Battery last charged: - - Value + + Unknown OfbQtDeviceOtherSettingsModule - - - Other settings - - Interaction @@ -293,11 +251,6 @@ OfbQtDeviceSelectModule - - - Change device... - - Select device automatically @@ -326,21 +279,6 @@ OfbQtDualConnectModule - - - Unpair device - - - - - Do you really want to unpair %1 from your headphones? - - - - - Dual connect - - Refresh @@ -377,6 +315,7 @@ + Connect @@ -386,98 +325,80 @@ Unpair - - - OfbQtErrorDialog - - OpenFreebuds + + Disconnect - - OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clocking on "Close" button. + + Unpair device - - Application will be closed, restart it manually. + + Do you really want to unpair %1 from your headphones? - OfbQtGesturesModule - - - Answer to call - - - - - Adjust volume - - - - - Voice assistant - - - - - Next track - - + OfbQtErrorDialog - - - Disabled + + OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clicking on "Close" button. - - Play/pause + + Application will be closed, restart it manually. + + + OfbQtFirstRunDialog - - Prev track + + Welcome - - Switch device + + This application allows you to manage your HUAWEI Bluetooth earphones. To access them, look for headphones icon in system tray panel, near other icons. - - Switch noise control mode + + Left-click on this icon will cycle through noise cancellation modes (can be configured), right-click will provide access to full battery status and main options. Settings window provides access to all features. - - Off and cancellation + + If you're running under GNOME shell and can't find tray icon, please, check FAQ. - - Cycle all modes + + Launch OpenFreebuds at system boot - - Cancellation and awareness + + You could change this options anytime later in settings. - - Off and awareness + + FAQ - - Gestures + + Get started + + + OfbQtGesturesModule Long-tap @@ -528,19 +449,75 @@ Preferred modes - - - OfbQtHotkeysModule - - Press new shortcut... + + Answer to call - - Hotkeys... + + Adjust volume + + + + + Voice assistant + + + + + Next track + + + + + + Disabled + + + + + Play/pause + + + + + Prev track + + + + + Switch device + + + Switch noise control mode + + + + + Off and cancellation + + + + + Cycle all modes + + + + + Cancellation and awareness + + + + + Off and awareness + + + + + OfbQtHotkeysModule Enable global keyboard shortcuts @@ -566,27 +543,52 @@ Hint: to remove already assigned shortcut, press Esc while recording a new one. + + + Press new shortcut… + + OfbQtLinuxExtrasModule - Linux-specific + Compatibility - Media playback control + Enable MPRIS helper service - Enable MPRIS helper service + Try this option if auto-pause doesn't work with your desktop environment. Note that only MPRIS-compatible media players are supported (mostly all standalone player and browsers support this API). - Try this option if auto-pause doesn't work with your desktop environment. Note that only MPRIS-compatible media players are supported (mostly all standalone player and browsers support this API). + Force use X11 backend (may look better in GNOME-based desktop environments) + + + + + Restart application to apply. + + + + + Theme + + + + + Fresh versions of OpenFreebuds are written in Qt6, and uses system-wide Qt UI theme. So, if application color scheme didn't match with system, or it looks ugly, you should configure global Qt style settings. + + + + + In KDE, LxQT or other Qt-based desktop environments, use system appearance settings. Otherwise, configure qt manually or use any configuration tool like qt6ct. @@ -604,152 +606,168 @@ Documentation + + + Ensure bus access + + + + + Looks like you're running under Flatpak. To use this feature, OpenFreebuds need to have access to entire session bus, otherwise it won't find any working media players. Ensure that you're granted this permission, refer to FAQ for more details. + + OfbQtMainWindow - + Select device - + Device info - + Dual-connect - + Gestures - + Sound quality - + Other settings - + Application - + User interface - + Keyboard shortcuts - + Linux-related - - About... + + About… - - Bugreport... + + Help: FAQ - - Temporary replace device + + Help: Remote control - - Close this window + + Bugreport… - - Exit OpenFreebuds + + Check for updates… - - - OfbQtSoundQualityModule - - New preset… + + Remote access… - - Delete… + + Temporary replace device - - Export to file… + + Close this window - - Load file… + + Exit OpenFreebuds + + + OfbQtManualConnectDialog - - Create new equalizer preset + + Manual connect… - - Enter new preset name: + + Enter bluetooth address of your device and select their model from list. You can find bluetooth address in system settings. - - Failed + + Bluetooth address: - - Can't create: too many custom preset created in device. + + Device profile: + + + OfbQtRpcConfig - - Delete equalizer mode? + + Remote access… - - Will delete following mode: + + Change this settings only if you know what you're doing. Require restart of all OpenFreebuds instances and all clients. - - Save equalizer preset to file... + + Allow controlling OpenFreebuds through network - - Load equalizer preset from file... + + Require following secret to be present in X-Secret header - - Sound quality + + (enter new secret key) + + + OfbQtSoundQualityModule Configure sound-related device settings. @@ -790,11 +808,6 @@ Preset: - - - ... - - Customize preset @@ -810,66 +823,126 @@ Save + + + New preset… + + + + + Delete… + + + + + Export to file… + + + + + Load file… + + + + + Create new equalizer preset + + + + + Enter new preset name: + + + + + Failed + + + + + Can't create: too many custom preset created in device. + + + + + Delete equalizer mode? + + + + + Will delete following mode: + + + + + Save equalizer preset to file… + + + + + Load equalizer preset from file… + + OfbQtTrayMenu - + Left headphone: - + Right headphone: - + Battery case: - + Battery: - + Disable noise control - + Noise cancelling - + Awareness - + Disconnect - + Connect - - Settings... + + Settings… - - Bugreport... + + Bugreport… - + Leave application @@ -878,17 +951,27 @@ OfbQtUiSettingsModule - UI Settings + Looking for UI theme settings? Now it follows system-wide configuration. - Looking for UI theme settings? Now it follows system-wide configuration. + Main - Main + Launch at system startup + + + + + Language: + + + + + System @@ -898,12 +981,22 @@ - Language: + Update checker: - System + Notify about new versions + + + + + Check for new versions, but don't notify + + + + + Disabled @@ -951,7 +1044,50 @@ OfbTrayIcon - OpenFreebuds: Connecting to device... + OpenFreebuds: Connecting to device… + + + + + ShortcutName + + + Connect device + + + + + Disconnect device + + + + + Connect/disconnect device + + + + + Next noise control mode + + + + + Disable noise control + + + + + Enable noise cancellation + + + + + Enable awareness mode + + + + + Enable low-latency mode diff --git a/openfreebuds_qt/assets/i18n/es.ts b/openfreebuds_qt/assets/i18n/es.ts new file mode 100644 index 0000000..334871a --- /dev/null +++ b/openfreebuds_qt/assets/i18n/es.ts @@ -0,0 +1,1094 @@ + + + + + Dialog + + + Unsupported device + Dispositivo no soportado + + + + This device isn't supported, for yet. But if you want, you can force connect them. To do that, select an exiting profile. Then application will try to apply it to your device. You can change profile in any time. + Este dispositivo no es compatible por ahora. Pero si quieres puedes forzar su conexión. Para ello seleccione un perfil de salida. Entonces la aplicación intentará aplicarlo a tu dispositivo. Puedes cambiar de perfil en cualquier momento. + + + + Notice that this may be dangerous for some kind of devices. Continue only if you know what you're doing. + Ten en cuenta que esto puede ser peligroso para algunos tipos de dispositivos. Continua sólo si sabe lo que está haciendo. + + + + EqPresetName + + + Default + Por defecto + + + + Bass-boost + Refuerzo de graves + + + + Treble-boost + Refuerzo de agudos + + + + Voices + Voces + + + + OfbDeviceAncLevelTrayMenu + + + Comfortable + Cómodo + + + + Normal + Normal + + + + Ultra + Ultra + + + + Dynamic + Dinámico + + + + Voice boost + Potenciar voces + + + + Intensity… + Intensidad… + + + + OfbDeviceDualConnectTrayMenu + + + Dual-connect… + Conexión dual… + + + + OfbDeviceEqualizerTrayMenu + + + Equalizer preset… + Perfil del ecualizador… + + + + OfbMainWindowDesign + + + New version available, click here to view + Nueva versión disponible, pulsa aquí para verla + + + + Hide + Ocultar + + + + Update now + Actualizar ahora + + + + Exit + Salir + + + + OfbQtAboutModule + + + Client application for HUAWEI FreeBuds wireless earphone series. Free and open source. + Cliente para los auriculares inalámbricos HUAWEI FreeBuds. Libre y de código abierto. + + + + Website + Sitio web + + + + Source code + Código fuente + + + + Supported devices + Dispositivos soportados + + + + Libraries + Librerias + + + + OfbQtApplication + + + You're running under older version of Qt than expected. It's strongly recommended to switch to Flatpak release, because older Qt version may fail your experience of using OpenFreebuds. + Está ejecutando una versión de Qt antigua. Te recomendamos cambiar a la versión de Flatpak, ya que una versión anterior de Qt puede afectar negativamente a la experiencia de uso de OpenFreebuds. + + + + This warning will be shown only once. Please, test Flatpak version before reporting bugs. + Este aviso sólo se mostrará una vez. Por favor, prueba la versión de Flatpak antes de informar de errores. + + + + OfbQtDependencyMissingDialog + + + To use this feature, additional dependencies is required. Install it now? + Para utilizar esta función, se requieren dependencias adicionales. ¿Quieres instalarlas ahora? + + + + OfbQtDeviceInfoModule + + + Firmware version: + Versión del firmware: + + + + Bluetooth address: + Dirección Bluetooth: + + + + All available device information fields: + Detalles del dipositivo: + + + + Property + Propiedad + + + + Value + Valor + + + + Battery last charged: + Ultima carga: + + + + Unknown + Desconocido + + + + OfbQtDeviceOtherSettingsModule + + + Interaction + Manejo del dispositivo + + + + Wear detection + Detección de uso + + + + Pause audio or switch device when earphones are removed + Pausa el audio o cambia de dispositivo cuando se quitan los auriculares + + + + Networking + Conexiones + + + + Enable low-latency mode + Activar el modo de baja latencia + + + + Will try to reduce audio latency when using headphones in enviroments with high network load. This option is disabled when your earphones are disconnected. Applies only for current device. + Intentará reducir la latencia de audio cuando se utilicen auriculares en entornos con alta carga de red. Esta opción se desactiva cuando los auriculares están desconectados. Sólo se aplica al dispositivo actual. + + + + Service + Otros ajustes + + + + Device language: + Idioma del dispositivo: + + + + Due to technical restrictions, current language can't be readden from device and this field will be empty. + Debido a restricciones técnicas, el idioma actual no se puede leer desde el dispositivo y este campo estará vacío. + + + + OfbQtDeviceSelectModule + + + Select device automatically + Seleccionar dispositivo automáticamente + + + + OpenFreebuds will automatically detect currently connected headset and switch to them. + OpenFreebuds detectará automáticamente los auriculares conectados y se conectará a ellos. + + + + List bellow shows all Bluetooth devices paired with your device. Select appropriate device that you want to use with OpenFreebuds: + La siguiente lista muestra todos los dispositivos Bluetooth emparejados con su dispositivo. Selecciona el dispositivo que quieres usar con OpenFreebuds: + + + + Device isn't listed here + El dispositivo no aparece + + + + Refresh list + Actualizar lista + + + + OfbQtDualConnectModule + + + Refresh + Actualizar + + + + Allow connecting to multiple devices at once + Permitir conectarse a varios dispositivos a la vez + + + + This page allows you to manage devices that are paired with your headphones. + Esta página te permite gestionar los dispositivos emparejados con tus auriculares. + + + + Bluetooth address: + Dirección Bluetooth: + + + + Device name: + Nombre: + + + + Preferred device + Dipositivo preferido + + + + Auto connect this device + Autoconectar este dispositivo + + + + + Connect + Conectar + + + + Unpair + Desemparejar + + + + Disconnect + Desconectar + + + + Unpair device + Desemparejar dispositivo + + + + Do you really want to unpair %1 from your headphones? + ¿Quieres desemparejar %1 de tus auriculares? + + + + OfbQtErrorDialog + + + OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clicking on "Close" button. + OpenFreebuds se ha encontrado con un error. Por favor, guarda el informe de error y envíalo al desarrollador. El informe de error se generará después de hacer clic en el botón "Cerrar". + + + + Application will be closed, restart it manually. + La aplicación se cerrará, reiníciela manualmente. + + + + OfbQtFirstRunDialog + + + Welcome + Bienvenido + + + + This application allows you to manage your HUAWEI Bluetooth earphones. To access them, look for headphones icon in system tray panel, near other icons. + Esta aplicación te permite gestionar tus auriculares Bluetooth HUAWEI. Para acceder a ellos, busqua el icono de los auriculares en el panel de la bandeja del sistema, cerca de otros iconos. + + + + Left-click on this icon will cycle through noise cancellation modes (can be configured), right-click will provide access to full battery status and main options. Settings window provides access to all features. + Al hacer clic con el botón izquierdo del ratón en este icono, te desplazaras por los modos de cancelación de ruido (configurables). Al hacer clic con el botón derecho, accederás al estado completo de la batería y a las opciones principales. La ventana de configuración permite acceder a todas las funciones. + + + + If you're running under GNOME shell and can't find tray icon, please, check FAQ. + Si está ejecutando GNOME shell y no puedes encontrar el icono de la bandeja, por favor, consulta las FAQ. + + + + Launch OpenFreebuds at system boot + Iniciar OpenFreebuds al arrancar el sistema + + + + You could change this options anytime later in settings. + Puedes cambiar esta opción más adelante en los ajustes. + + + + FAQ + FAQ + + + + Get started + Comenzar + + + + OfbQtGesturesModule + + + Long-tap + Pulsación larga + + + + Triple-tap + Triple pulsación + + + + Double-tap in call + Doble pulsación en llamada + + + + Left + Izquierdo + + + + Power button double-tap + Doble pulsación de encendido + + + + Customize device touch panel(s) and button(s) behaviour. This settings are stored inside your device and will work also if OpenFreebuds is closed. + Personalica el comportamiento de los paneles táctiles y los botones del dispositivo. Esta configuración se almacena en el dispositivo y funcionará también si OpenFreebuds está cerrado. + + + + Swipe gesture + Gestos + + + + Double-tap + Pulsación doble + + + + Right + Derecho + + + + Preferred modes + Modos preferidos + + + + Answer to call + Responder una llamada + + + + Adjust volume + Ajustar volumen + + + + Voice assistant + Asistente de voz + + + + Next track + Siguiente canción + + + + + Disabled + Deshabilitado + + + + Play/pause + Play/pausa + + + + Prev track + Canción anterior + + + + Switch device + Cambiar dispositivo + + + + Switch noise control mode + Cambiar modo de cancelación de ruido + + + + Off and cancellation + Apagado y cancelación + + + + Cycle all modes + Rotar los modos + + + + Cancellation and awareness + Cancelación y exterior + + + + Off and awareness + Apagado y exterior + + + + OfbQtHotkeysModule + + + Enable global keyboard shortcuts + Habilitar atajos del teclado + + + + Here you can configure system-wide keyboard shortcuts for OpenFreebuds + Aquí puede configurar los atajos del teclado del sistema para OpenFreebuds + + + + Action + Acción + + + + Shortcut + Atajo + + + + Hint: to remove already assigned shortcut, press Esc while recording a new one. + Sugerencia: para eliminar un atajo ya asignado, pulse "Esc" mientras grabas uno nuevo. + + + + Press new shortcut… + Pulsa nuevo acceso directo… + + + + OfbQtLinuxExtrasModule + + + Compatibility + Compatibilidad + + + + Enable MPRIS helper service + Habilitar el servicio MPRIS + + + + Try this option if auto-pause doesn't work with your desktop environment. Note that only MPRIS-compatible media players are supported (mostly all standalone player and browsers support this API). + Prueba esta opción si la pausa automática no funciona con tu entorno de escritorio. Tenga en cuenta que sólo se admiten reproductores multimedia compatibles con MPRIS (la mayoría de los reproductores independientes y navegadores admiten esta API). + + + + Force use X11 backend (may look better in GNOME-based desktop environments) + Forzar el uso de X11 backend (puede verse mejor en entornos de escritorio basados en GNOME) + + + + Restart application to apply. + Reinicie la aplicación para aplicar los cambios. + + + + Theme + Tema + + + + Fresh versions of OpenFreebuds are written in Qt6, and uses system-wide Qt UI theme. So, if application color scheme didn't match with system, or it looks ugly, you should configure global Qt style settings. + Las nuevas versiones de OpenFreebuds están escritas en Qt6, y utilizan el tema de interfaz de usuario Qt para todo el sistema. Por lo tanto, si el esquema de color de la aplicación no coincide con el sistema, o se ve feo, debes configurar los ajustes globales de estilo Qt. + + + + In KDE, LxQT or other Qt-based desktop environments, use system appearance settings. Otherwise, configure qt manually or use any configuration tool like qt6ct. + En KDE, LxQT u otros entornos de escritorio basados en Qt, utilica la configuración de apariencia del sistema. De lo contrario, configura QT manualmente o utilica alguna herramienta de configuración como qt6ct. + + + + Keyboard shortcuts + Atajos del teclado + + + + Looks like you're using Wayland desktop environment. Due to that OpenFreebuds built-in global hotkeys won't work. If you want to use keyboard shortcuts, setup them from your desktop environment settings. + Parece que estás usando el entorno de escritorio Wayland. Debido a esto, los atajos de teclado globales integrados en OpenFreebuds no funcionarán. Si quieres usar atajos de teclado, configúralos desde los ajustes de tu entorno de escritorio. + + + + Documentation + Documentación + + + + Ensure bus access + Garantizar el acceso al bus + + + + Looks like you're running under Flatpak. To use this feature, OpenFreebuds need to have access to entire session bus, otherwise it won't find any working media players. Ensure that you're granted this permission, refer to FAQ for more details. + Parece que estas ejecutando bajo Flatpak. Para utilizar esta función, OpenFreebuds necesita tener acceso a todo el bus de sesión, de lo contrario no encontrará ningún reproductor multimedia que funcione. Asegúrese de que se le concede este permiso, consulte las FAQ para más detalles. + + + + OfbQtMainWindow + + + Select device + Seleccionar dispositivo + + + + Device info + Información del dispositivo + + + + Dual-connect + Conexión dual + + + + Gestures + Gestos + + + + Sound quality + Calidad del sonido + + + + Other settings + Otros ajustes + + + + Application + Aplicación + + + + User interface + Interfaz de usuario + + + + Keyboard shortcuts + Atajo del teclado + + + + Linux-related + Ajustes de Linux + + + + About… + Acerca de… + + + + Help: FAQ + Ayuda: FAQ + + + + Help: Remote control + Ayuda: Control remoto + + + + Bugreport… + Reportar errores… + + + + Check for updates… + Comprobar actualizaciones… + + + + Remote access… + Acceso remoto… + + + + Temporary replace device + Reemplazar dispositivo temporalmente + + + + Close this window + Cerrar la ventana + + + + Exit OpenFreebuds + Cerrar OpenFreebuds + + + + OfbQtManualConnectDialog + + + Manual connect… + Conexión manual… + + + + Enter bluetooth address of your device and select their model from list. You can find bluetooth address in system settings. + Introduce la dirección bluetooth de tu dispositivo y selecciona tu modelo de la lista. Puedes encontrar la dirección bluetooth en los ajustes del sistema. + + + + Bluetooth address: + Dirección Bluetooth: + + + + Device profile: + Perfil del dispositivo: + + + + OfbQtRpcConfig + + + Remote access… + Acceso remoto… + + + + Change this settings only if you know what you're doing. Require restart of all OpenFreebuds instances and all clients. + Cambia esta configuración sólo si sabes lo que estás haciendo. Requiere reiniciar todas las instancias de OpenFreebuds y todos los clientes. + + + + Allow controlling OpenFreebuds through network + Permitir controlar OpenFreebuds a través de la red + + + + Require following secret to be present in X-Secret header + Se requiere que el siguiente secreto esté presente en la cabecera X-Secret + + + + (enter new secret key) + (escribe la nueva clave secreta) + + + + OfbQtSoundQualityModule + + + Configure sound-related device settings. + Configura los ajustes de los dispositivos relacionados con el sonido. + + + + Sound quality preference: + Preferencia de calidad de sonido: + + + + Prioritize sound quality + Priorizar la calidad del sonido + + + + Device will prefer loseless audio codecs, like LDAC. + El dispositivo preferirá los códecs de audio sin pérdida, como LDAC. + + + + Prioritize connection quality + Priorizar la calidad de la conexión + + + + Device will prefer audio codes with better compression, like AAC + El dispositivo preferirá los códigos de audio con mejor compresión, como AAC + + + + Equalizer + Equalizador + + + + Preset: + Perfil: + + + + Customize preset + Personalizar perfil + + + + Save changes? + ¿Guardar cambios? + + + + Save + Guardar + + + + New preset… + Nuevo perfil… + + + + Delete… + Borrar… + + + + Export to file… + Exportar a un archivo… + + + + Load file… + Cargar archivo… + + + + Create new equalizer preset + Nuevo perfil del equalizador + + + + Enter new preset name: + Nombre del perfil: + + + + Failed + Falló + + + + Can't create: too many custom preset created in device. + No se puede crear: demasiados perfiles personalizados creados en el dispositivo. + + + + Delete equalizer mode? + ¿Borrar el perfil de equalizador? + + + + Will delete following mode: + Se borrará el siguiente perfil: + + + + Save equalizer preset to file… + Guardar perfil del equalizador… + + + + Load equalizer preset from file… + Cargar perfil del equalizador… + + + + OfbQtTrayMenu + + + Left headphone: + Auricular izquierdo: + + + + Right headphone: + Auricular derecho: + + + + Battery case: + Batería de la caja: + + + + Battery: + Batería: + + + + Disable noise control + Deshabilitar cancelación de ruido + + + + Noise cancelling + Cancelación de ruido + + + + Awareness + Exterior + + + + Disconnect + Desconectar + + + + Connect + Conectar + + + + Settings… + Ajustes… + + + + Bugreport… + Reportar errores… + + + + Leave application + Cerrar aplicación + + + + OfbQtUiSettingsModule + + + Looking for UI theme settings? Now it follows system-wide configuration. + ¿Buscas la configuración del tema de IU? Ahora sigue la configuración del sistema. + + + + Main + Principal + + + + Launch at system startup + Abrir al arrancar el sistema + + + + Language: + Idioma: + + + + System + Sistema + + + + Restart OpenFeebuds to apply changes + Reinicia OpenFeebuds para aplicar los cambios + + + + Update checker: + Comprobar actualizaciones: + + + + Notify about new versions + Notificarme de nuevas versiones + + + + Check for new versions, but don't notify + Comprobar nuevas versiones, sin notificaciones + + + + Disabled + Deshabilitado + + + + Tray applet + Widget de bandeja + + + + Icon color + Color del icono + + + + Auto-select + Auto seleccionar + + + + Light + Claro + + + + Dark + Oscuro + + + + Left-click action + Acción de botón izquierdo + + + + Show dual-connect device switcher in menu (if available) + Mostrar el conmutador de dispositivos de conexión dual en el menú (si está disponible) + + + + Show equalizer preset switcher in menu (if available) + Mostrar los perfiles del equalizador en el menu (si está disponible) + + + + OfbTrayIcon + + + OpenFreebuds: Connecting to device… + OpenFreebuds: Conectando al dispositivo… + + + + ShortcutName + + + Connect device + Conectar dispositivo + + + + Disconnect device + Desconectar dispositivo + + + + Connect/disconnect device + Conectar/desconectar dispositivo + + + + Next noise control mode + Siguiente modo de cancelación de ruido + + + + Disable noise control + Deshabilitar cancelación de ruido + + + + Enable noise cancellation + Habilitar cancelación de ruido + + + + Enable awareness mode + Deshabilitar modo exterior + + + + Enable low-latency mode + Activar el modo de baja latencia + + + diff --git a/openfreebuds_qt/assets/i18n/pt-BR.ts b/openfreebuds_qt/assets/i18n/pt-BR.ts new file mode 100644 index 0000000..8bf6e0a --- /dev/null +++ b/openfreebuds_qt/assets/i18n/pt-BR.ts @@ -0,0 +1,1095 @@ + + + + # + + Dialog + + + Unsupported device + + + + + This device isn't supported, for yet. But if you want, you can force connect them. To do that, select an exiting profile. Then application will try to apply it to your device. You can change profile in any time. + + + + + Notice that this may be dangerous for some kind of devices. Continue only if you know what you're doing. + + + + + EqPresetName + + + Default + Padrão + + + + Bass-boost + Reforço de graves + + + + Treble-boost + Aumento de agudos + + + + Voices + + + + + OfbDeviceAncLevelTrayMenu + + + Comfortable + Confortável + + + + Normal + Normal + + + + Ultra + Ultra + + + + Dynamic + Dinâmico + + + + Voice boost + Aumento de voz + + + + Intensity… + Intensidade… + + + + OfbDeviceDualConnectTrayMenu + + + Dual-connect… + Conexão dupla… + + + + OfbDeviceEqualizerTrayMenu + + + Equalizer preset… + + + + + OfbMainWindowDesign + + + New version available, click here to view + + + + + Hide + + + + + Update now + Atualizar + + + + Exit + + + + + OfbQtAboutModule + + + Client application for HUAWEI FreeBuds wireless earphone series. Free and open source. + + + + + Website + Site + + + + Source code + Código fonte + + + + Supported devices + Dispositivos suportados + + + + Libraries + + + + + OfbQtApplication + + + You're running under older version of Qt than expected. It's strongly recommended to switch to Flatpak release, because older Qt version may fail your experience of using OpenFreebuds. + + + + + This warning will be shown only once. Please, test Flatpak version before reporting bugs. + + + + + OfbQtDependencyMissingDialog + + + To use this feature, additional dependencies is required. Install it now? + + + + + OfbQtDeviceInfoModule + + + Firmware version: + Versão do firmware + + + + Bluetooth address: + Endereço Bluetooth: + + + + All available device information fields: + + + + + Property + + + + + Value + Valor + + + + Battery last charged: + + + + + Unknown + + + + + OfbQtDeviceOtherSettingsModule + + + Interaction + + + + + Wear detection + + + + + Pause audio or switch device when earphones are removed + + + + + Networking + + + + + Enable low-latency mode + + + + + Will try to reduce audio latency when using headphones in enviroments with high network load. This option is disabled when your earphones are disconnected. Applies only for current device. + + + + + Service + + + + + Device language: + Idioma do dispositivo: + + + + Due to technical restrictions, current language can't be readden from device and this field will be empty. + + + + + OfbQtDeviceSelectModule + + + Select device automatically + + + + + OpenFreebuds will automatically detect currently connected headset and switch to them. + + + + + List bellow shows all Bluetooth devices paired with your device. Select appropriate device that you want to use with OpenFreebuds: + + + + + Device isn't listed here + Dispositivo não está na lista (conexão manual) + + + + Refresh list + Atualizar + + + + OfbQtDualConnectModule + + + Refresh + Atualizar + + + + Allow connecting to multiple devices at once + + + + + This page allows you to manage devices that are paired with your headphones. + + + + + Bluetooth address: + Endereço Bluetooth: + + + + Device name: + + + + + Preferred device + Dispositivo preferido + + + + Auto connect this device + Conectar automaticamente neste dispositivo + + + + + Connect + Conectar + + + + Unpair + Desemparelhar + + + + Disconnect + Desconectar + + + + Unpair device + + + + + Do you really want to unpair %1 from your headphones? + + + + + OfbQtErrorDialog + + + OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clicking on "Close" button. + + + + + Application will be closed, restart it manually. + + + + + OfbQtFirstRunDialog + + + Welcome + + + + + This application allows you to manage your HUAWEI Bluetooth earphones. To access them, look for headphones icon in system tray panel, near other icons. + + + + + Left-click on this icon will cycle through noise cancellation modes (can be configured), right-click will provide access to full battery status and main options. Settings window provides access to all features. + + + + + If you're running under GNOME shell and can't find tray icon, please, check FAQ. + + + + + Launch OpenFreebuds at system boot + + + + + You could change this options anytime later in settings. + + + + + FAQ + + + + + Get started + + + + + OfbQtGesturesModule + + + Long-tap + Toque longo + + + + Triple-tap + + + + + Double-tap in call + Tocar duas vezes + + + + Left + + + + + Power button double-tap + Ação do botão liga/desliga + + + + Customize device touch panel(s) and button(s) behaviour. This settings are stored inside your device and will work also if OpenFreebuds is closed. + + + + + Swipe gesture + Ação de deslizar + + + + Double-tap + Tocar duas vezes + + + + Right + + + + + Preferred modes + Modos preferidos + + + + Answer to call + Atender a chamada + + + + Adjust volume + Ajustar volume + + + + Voice assistant + Assistente de voz + + + + Next track + Próxima faixa + + + + + Disabled + Desabilitado + + + + Play/pause + Pausar/reproduzir + + + + Prev track + Faixa anterior + + + + Switch device + Trocar dispositivo + + + + Switch noise control mode + Alternar modo de controle de ruído + + + + Off and cancellation + Desativado e cancelamento + + + + Cycle all modes + Ciclo todos os modos + + + + Cancellation and awareness + Cancelamento e sensibilidade ao ambiente + + + + Off and awareness + Desativado e sensibilidade ao ambiente + + + + OfbQtHotkeysModule + + + Enable global keyboard shortcuts + + + + + Here you can configure system-wide keyboard shortcuts for OpenFreebuds + + + + + Action + + + + + Shortcut + + + + + Hint: to remove already assigned shortcut, press Esc while recording a new one. + + + + + Press new shortcut… + + + + + OfbQtLinuxExtrasModule + + + Compatibility + + + + + Enable MPRIS helper service + + + + + Try this option if auto-pause doesn't work with your desktop environment. Note that only MPRIS-compatible media players are supported (mostly all standalone player and browsers support this API). + + + + + Force use X11 backend (may look better in GNOME-based desktop environments) + + + + + Restart application to apply. + + + + + Theme + Tema + + + + Fresh versions of OpenFreebuds are written in Qt6, and uses system-wide Qt UI theme. So, if application color scheme didn't match with system, or it looks ugly, you should configure global Qt style settings. + + + + + In KDE, LxQT or other Qt-based desktop environments, use system appearance settings. Otherwise, configure qt manually or use any configuration tool like qt6ct. + + + + + Keyboard shortcuts + + + + + Looks like you're using Wayland desktop environment. Due to that OpenFreebuds built-in global hotkeys won't work. If you want to use keyboard shortcuts, setup them from your desktop environment settings. + + + + + Documentation + + + + + Ensure bus access + + + + + Looks like you're running under Flatpak. To use this feature, OpenFreebuds need to have access to entire session bus, otherwise it won't find any working media players. Ensure that you're granted this permission, refer to FAQ for more details. + + + + + OfbQtMainWindow + + + Select device + + + + + Device info + Dispositivo + + + + Dual-connect + Conexão dupla + + + + Gestures + Gestos + + + + Sound quality + + + + + Other settings + + + + + Application + Aplicativo + + + + User interface + + + + + Keyboard shortcuts + + + + + Linux-related + + + + + About… + Sobre… + + + + Help: FAQ + + + + + Help: Remote control + + + + + Bugreport… + Reportar erro + + + + Check for updates… + + + + + Remote access… + + + + + Temporary replace device + + + + + Close this window + + + + + Exit OpenFreebuds + + + + + OfbQtManualConnectDialog + + + Manual connect… + Conexão manual + + + + Enter bluetooth address of your device and select their model from list. You can find bluetooth address in system settings. + + + + + Bluetooth address: + Endereço Bluetooth: + + + + Device profile: + Modelo do dispositivo (perfil): + + + + OfbQtRpcConfig + + + Remote access… + + + + + Change this settings only if you know what you're doing. Require restart of all OpenFreebuds instances and all clients. + + + + + Allow controlling OpenFreebuds through network + Permitir conexões externas + + + + Require following secret to be present in X-Secret header + + + + + (enter new secret key) + + + + + OfbQtSoundQualityModule + + + Configure sound-related device settings. + + + + + Sound quality preference: + + + + + Prioritize sound quality + + + + + Device will prefer loseless audio codecs, like LDAC. + + + + + Prioritize connection quality + + + + + Device will prefer audio codes with better compression, like AAC + + + + + Equalizer + + + + + Preset: + + + + + Customize preset + + + + + Save changes? + + + + + Save + + + + + New preset… + + + + + Delete… + + + + + Export to file… + + + + + Load file… + + + + + Create new equalizer preset + + + + + Enter new preset name: + + + + + Failed + + + + + Can't create: too many custom preset created in device. + + + + + Delete equalizer mode? + + + + + Will delete following mode: + + + + + Save equalizer preset to file… + + + + + Load equalizer preset from file… + + + + + OfbQtTrayMenu + + + Left headphone: + Fone de ouvido esquerdo: + + + + Right headphone: + + + + + Battery case: + Bateria da caixa: + + + + Battery: + Bateria: + + + + Disable noise control + Desabilitar cancelamento de ruído + + + + Noise cancelling + Cancelamento de ruído + + + + Awareness + Sensibilidade ao ambiente + + + + Disconnect + Desconectar + + + + Connect + Conectar + + + + Settings… + Configurações… + + + + Bugreport… + Reportar erro… + + + + Leave application + + + + + OfbQtUiSettingsModule + + + Looking for UI theme settings? Now it follows system-wide configuration. + + + + + Main + + + + + Launch at system startup + + + + + Language: + Idioma: + + + + System + + + + + Restart OpenFeebuds to apply changes + + + + + Update checker: + Verificador de atualização: + + + + Notify about new versions + + + + + Check for new versions, but don't notify + + + + + Disabled + Desabilitado + + + + Tray applet + + + + + Icon color + Tema de ícones + + + + Auto-select + Automático + + + + Light + Claro + + + + Dark + Escuro + + + + Left-click action + + + + + Show dual-connect device switcher in menu (if available) + + + + + Show equalizer preset switcher in menu (if available) + + + + + OfbTrayIcon + + + OpenFreebuds: Connecting to device… + + + + + ShortcutName + + + Connect device + Conectar dispositivo + + + + Disconnect device + Desconectar dispositivo + + + + Connect/disconnect device + Conectar ou desconectar + + + + Next noise control mode + + + + + Disable noise control + Desabilitar cancelamento de ruído + + + + Enable noise cancellation + + + + + Enable awareness mode + + + + + Enable low-latency mode + + + + diff --git a/openfreebuds_qt/assets/i18n/ru.ts b/openfreebuds_qt/assets/i18n/ru.ts index a723aee..f0e04b5 100644 --- a/openfreebuds_qt/assets/i18n/ru.ts +++ b/openfreebuds_qt/assets/i18n/ru.ts @@ -1,6 +1,7 @@ + # Dialog @@ -11,32 +12,12 @@ This device isn't supported, for yet. But if you want, you can force connect them. To do that, select an exiting profile. Then application will try to apply it to your device. You can change profile in any time. - Это устройство не поддерживается. Но вы можете подключить его принудительно, для этого выберите профиль устройства ниже. Тогда программа попытается работать с вашим устройством аналогично выбранной модели. Изменить эту опцию можно в любой момент. + Это устройство не поддерживается, по крайней мере сейчас. Но, вы можете подключить его принудительно. Для этого выберите профиль в списке ниже. Тогда приложение попытается применить его к вашему устройству. Эту настройку можно изменить в любое время. - Notice that this may be dangerous for some kind of devices. Do it of your risk. You also can share information about your device and selected profile at GitHub, if you want get offical support. - Учтите, что эта операция несколько рискованная, если вы не уверены в совместимости вашего устройства с выбранным, продолжайте на свой страх и риск. Также вы можете помочь с добавлением поддержки вашего устройства на GitHub проекта. - - - - Manual connect - Ручное подключение - - - - Enter bluetooth address of your device and select their model from list. You can find bluetooth address in system settings. - Введите Bluetooth-адрес устройство и выберите его модель из списка ниже. Вы можете найти адрес устройства в настройках системы. - - - - Bluetooth address: - Bluetooth-адрес: - - - - Device profile: - Профиль устройства: + Notice that this may be dangerous for some kind of devices. Continue only if you know what you're doing. + Учтите, что это может быть опасным для некоторых устройств. Продолжайте только если знаете, что делаете. @@ -44,22 +25,22 @@ Default - По умолчанию + По умолчанию Bass-boost - Больше баса + Больше баса Treble-boost - Больше высоких + Больше высоких Voices - Голос + Вокал @@ -91,105 +72,88 @@ - Intensity... + Intensity… Интенсивность… + + OfbDeviceDualConnectTrayMenu + + + Dual-connect… + Двойное подключение… + + OfbDeviceEqualizerTrayMenu - - Equalizer preset... - + + Equalizer preset… + Эквалайзер… OfbMainWindowDesign - OpenFreebuds - OpenFreebuds + New version available, click here to view + Доступна новая версия, нажмите здесь для просмотра - Exit - Выйти - - - - OfbQtAboutModule - - - Supported devices - Поддерживаемые устройства + Hide + Скрыть - - Libraries - Библиотеки + + Update now + Обновить сейчас - - About - О программе + + Exit + Выход + + + OfbQtAboutModule Client application for HUAWEI FreeBuds wireless earphone series. Free and open source. - Приложение-клиент для беспроводных наушников HUAWEI FreeBuds. Бесплатно и с открытым исходным кодом. + Приложения для управления наушниками серии HUAWEI FreeBuds Бесплатно и с открытым исходным кодом. Website - Сайт + Веб-сайт Source code Исходный код - - - OfbQtCommonWithShortcutsModule - - - Connect device - Подключить устройство - - - - Disconnect device - Отсоединить устройство - - - - Connect/disconnect device - Подключить/отключить устройство - - - Next noise control mode - Следующий режим шумоподавления - - - - Disable noise control - Отключить шумоподавление + + Supported devices + Совместимые устройства - - Enable noise cancellation - Включить шумоподавление + + Libraries + Библиотеки + + + OfbQtApplication - - Enable awareness mode - Включить режим прозрачности + + You're running under older version of Qt than expected. It's strongly recommended to switch to Flatpak release, because older Qt version may fail your experience of using OpenFreebuds. + Вы используете более старую версию Qt, чем ожидалось. Рекомендуем перейти на Flatpak-версию программы, поскольку более старые версии Qt, предоставляемые вашей системой, могут пагубно повлиять на работу программы. - - Enable low-latency mode - Включить режим низкой задержки + + This warning will be shown only once. Please, test Flatpak version before reporting bugs. + Это предупреждение будет показано лишь один раз. Перед тем, как сообщать о проблемах, протестируйте Flatpak версию. @@ -197,54 +161,49 @@ To use this feature, additional dependencies is required. Install it now? - Для использования этой функции требуется дополнительный компонент. Перейти к установке? + Для этой функции требуется дополнительный компонент. Перейти к установке? OfbQtDeviceInfoModule - Deice information - Об устройстве + Firmware version: + Версия прошивки: Bluetooth address: - Bluetooth-адрес: + Bluetooth адрес: All available device information fields: - Все поля с информацией об устройстве: + Вся известная информация об устройстве: - Device name - Название устройства: + Property + Свойство - Firmware version: - Версия ПО: + Value + Значение - Property - Свойство + Battery last charged: + Последняя зарядка аккумулятора: - - Value - Значение + + Unknown + Неизвестно OfbQtDeviceOtherSettingsModule - - - Other settings - Другие настройки - Interaction @@ -253,12 +212,12 @@ Wear detection - Обнаружение извлечения из уха + Обнаружение ношения Pause audio or switch device when earphones are removed - Приостанавливать воспроизведение или менять устройство при извлечении наушников + Приостанавливать звук или переключать устройства при извлечении наушника @@ -273,12 +232,12 @@ Will try to reduce audio latency when using headphones in enviroments with high network load. This option is disabled when your earphones are disconnected. Applies only for current device. - Попытаться уменьшить задержку звука при использовании наушников в местности с высокой загруженностью радиосети. Эта опция действует только для текущего устройства и будет сброшена при отсоединении наушников. + Устройство попытается снизить задержку звука для использования в окружении с высокой сетевой засорённостью. Эта опция отключится при отсоединении наушников. Применяется только для текущего клиента. Service - Устройство + Служебное @@ -288,16 +247,11 @@ Due to technical restrictions, current language can't be readden from device and this field will be empty. - + Из-за технических ограничений прочитать текущий язык устройства невозможно, и поле выше будет пустым. OfbQtDeviceSelectModule - - - Change device... - Сменить устройство - Select device automatically @@ -306,12 +260,12 @@ OpenFreebuds will automatically detect currently connected headset and switch to them. - OpenFreebuds будет автоматически выбирать устройство среди подключенных к компьютеру. + OpenFreebuds будет автоматически определять подключенные наушники и переключится на них. List bellow shows all Bluetooth devices paired with your device. Select appropriate device that you want to use with OpenFreebuds: - Список ниже содержит все Bluetooth-устройства, сопряжённые с вашим компьютером. Выберите устройство, которое хотите использовать с OpenFreebuds: + Список ниже содержит все Bluetooth-устройства, сопряжённые с вашим ПК. Выберите нужное для работы с OpenFreebuds. @@ -326,21 +280,6 @@ OfbQtDualConnectModule - - - Unpair device - Забыть устройство - - - - Do you really want to unpair %1 from your headphones? - Вы действительно хотите отменить сопряжение %1 с наушниками? - - - - Dual connect - Двойное подключение - Refresh @@ -349,7 +288,7 @@ Allow connecting to multiple devices at once - Разрешить подключение к нескольким устройствам одновременно + Разрешить мульти-подключение @@ -359,24 +298,25 @@ Bluetooth address: - Bluetooth-адрес: + Bluetooth адрес: Device name: - Название устройства: + Название: Preferred device - Приоритетное устройство + Предпочитаемое устройство Auto connect this device - + Авто-подключение + Connect Подключить @@ -384,100 +324,82 @@ Unpair - Забыть + Удалить - - - OfbQtErrorDialog - - OpenFreebuds - OpenFreebuds + + Disconnect + Отсоединить - - OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clocking on "Close" button. - В работе OpenFreebuds произошла ошибка. Пожалуйста, сохраните отчёт об ошибке и передайте его разработчику. Отчёт будет создан после нажатия на кнопку "Закрыть". + + Unpair device + Отменить сопряжение устройства - - Application will be closed, restart it manually. - Приложение будет закрыто, перезапустите его вручную + + Do you really want to unpair %1 from your headphones? + Вы действительно хотите разорвать сопряжение между %1 и вашими наушниками? - OfbQtGesturesModule - - - Answer to call - Ответить на звонок - - - - Adjust volume - Изменить громкость - + OfbQtErrorDialog - - Voice assistant - Голосовой помошник + + OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clicking on "Close" button. + В работе OpenFreebuds произошла критическая ошибка. Пожалуйста, сохраните отчёт об ошибке и передайте разработчику, он будет сформирован после нажатия на кнопку "Закрыть". - - Next track - Следующий трек + + Application will be closed, restart it manually. + Программа будет закрыта, перезапустите её вручную. + + + OfbQtFirstRunDialog - - - Disabled - Отключено + + Welcome + Добро пожаловать - - Play/pause - Воспроизвести/Пауза + + This application allows you to manage your HUAWEI Bluetooth earphones. To access them, look for headphones icon in system tray panel, near other icons. + Это приложение позволяет управлять вашим устройством серии HUAWEI FreeBuds. Для доступа к ним, найдите значок в виде наушников на панели задачи, в области уведомлений. - - Prev track - Предыдущий трек + + Left-click on this icon will cycle through noise cancellation modes (can be configured), right-click will provide access to full battery status and main options. Settings window provides access to all features. + Левый клик по этой иконке будет переключать режимы шумоподавления (поведение можно настроить), правый клик предоставит доступ к полной информации о состоянии батареи утройства и основным опциям. Окно "Настройки" предоставит полный доступ до всех опций, доступных в устройстве. - - Switch device - Сменить устройство + + If you're running under GNOME shell and can't find tray icon, please, check FAQ. + Если вы используете рабочий стол GNOME и не можете найти значок в области уведомлений, ознакомьтесь с ЧаВо. - - Switch noise control mode - Сменить режим шумоподавления + + Launch OpenFreebuds at system boot + Запускать OpenFreebuds при включении ПК - - Off and cancellation - Отключено и подавление шума + + You could change this options anytime later in settings. + Вы можете изменить свой выбор в любой момент через настройки программы. - - Cycle all modes - Переключать все режимы + + FAQ + ЧаВо - - Cancellation and awareness - Подавление шума и прозрачность - - - - Off and awareness - Отключено и прозрачность - - - - Gestures - Жесты + + Get started + Начать + + + OfbQtGesturesModule Long-tap @@ -491,7 +413,7 @@ Double-tap in call - Двойное касание (разговор) + …во время звонка @@ -501,17 +423,17 @@ Power button double-tap - Двойное нажатие кнопки питания + Двойной клик кнопки питания Customize device touch panel(s) and button(s) behaviour. This settings are stored inside your device and will work also if OpenFreebuds is closed. - Настройка поведения сенсорных панелей и физических кнопок устройства. Эти настройки хранятся внутри памяти устройства и работают даже если OpenFreebuds закрыт. + Настройка поведения сенсорных панелей и кнопок на устройстве. Эти настройки хранятся прямо в устройстве и работают даже если OpenFreebuds закрыт. Swipe gesture - Свайп + Свайп по наушнику @@ -528,19 +450,75 @@ Preferred modes Предпочитаемые режимы - - - OfbQtHotkeysModule - - Press new shortcut... - Нажмите новое сочетание… + + Answer to call + Ответить на звонок - - Hotkeys... - Сочетания клавиш… + + Adjust volume + Изменить громкость + + + + Voice assistant + Голосовой помощник + + + Next track + Следующий трек + + + + + Disabled + Отключено + + + + Play/pause + Воспроизвести/Пауза + + + + Prev track + Предыдущий трек + + + + Switch device + Сменить устройство + + + + Switch noise control mode + Сменить режим шумоподавления + + + + Off and cancellation + Отключен и шумоподавление + + + + Cycle all modes + Все режимы + + + + Cancellation and awareness + Прозрачность и шумоподавление + + + + Off and awareness + Отключен и прозрачность + + + + OfbQtHotkeysModule Enable global keyboard shortcuts @@ -549,12 +527,12 @@ Here you can configure system-wide keyboard shortcuts for OpenFreebuds - Здесь вы можете настроить сочетания клавиш для управления OpenFreebuds. + Здесь вы можете настроить глобальные сочетания клавиш для OpenFreebuds. Action - Действия + Действие @@ -564,30 +542,55 @@ Hint: to remove already assigned shortcut, press Esc while recording a new one. - Подсказка: для удаления назначенного ранее сочетания клавиш нажмите Esc вместо назначения нового. + Подсказка: для удавления уже назначенного сочетания нажмите Esc во время записи нового + + + + Press new shortcut… + Нажмите новое сочетание клавиш… OfbQtLinuxExtrasModule - Linux-specific - Настройки Linux + Compatibility + Совместимость - Media playback control - Управление воспроизведением + Enable MPRIS helper service + Включить службу урпаления MPRIS - Enable MPRIS helper service - Включить службу управления MPRIS-плеером + Try this option if auto-pause doesn't work with your desktop environment. Note that only MPRIS-compatible media players are supported (mostly all standalone player and browsers support this API). + Попробуйте включить эту опцию, если авто-пауза не работает с вашим рабочим столом. Учтите, что работать это будет только с MPRIS-совместимыми проигрывателями (большинство отдельных программ и браузеров поддерживают этот API). - Try this option if auto-pause doesn't work with your desktop environment. Note that only MPRIS-compatible media players are supported (mostly all standalone player and browsers support this API). - Попробуйте эту опцию, если авто-пауза не работает на вашем ПК. Учтите, что это будет работать только с MPRIS-совместимыми медиаплеерами, к которым относятся все браузеры и большинство отдельных проигрывателей аудио- и видеофайлов. + Force use X11 backend (may look better in GNOME-based desktop environments) + Принудительно использовать X11 (может выглядеть лучше в GNOME) + + + + Restart application to apply. + Перезапустите приложение для применения изменений. + + + + Theme + Тема + + + + Fresh versions of OpenFreebuds are written in Qt6, and uses system-wide Qt UI theme. So, if application color scheme didn't match with system, or it looks ugly, you should configure global Qt style settings. + Новые версии OpenFreebuds написаны с использованием Qt6, и используют общесистемные настройки внешнего вида. Потому, если цветовая схема программы не совпадает с системной, или выглядит плохо, настройте тему для Qt приложений в системе. + + + + In KDE, LxQT or other Qt-based desktop environments, use system appearance settings. Otherwise, configure qt manually or use any configuration tool like qt6ct. + В KDE, LxQT и иных основанных на Qt рабочих столах, используйте системные настройки внешнего вида. Иначе измените настройки вручную или воспользуйтесь утилитой наподобии qt6ct. @@ -597,168 +600,184 @@ Looks like you're using Wayland desktop environment. Due to that OpenFreebuds built-in global hotkeys won't work. If you want to use keyboard shortcuts, setup them from your desktop environment settings. - Похоже что вы используете рабочий стол на базе Wayland. Из-за этого встроенный в OpenFreebuds функционал по управлению сочетаниями клавиш недоступен. Если вы хотите управлять наушниками через сочетания клавиш, задайте их вручную в настройках рабочего стола. + Похоже что вы используете рабочий стол на базе Wayland. В связи с этим, встроенный функционал по управлению сочетаниями клавиш недоступен. Если вам они нужны, сконфигурируйте их вручную через настройки рабочего стола. Documentation - Документация + Справка + + + + Ensure bus access + Убедитесь в доступности DBus + + + + Looks like you're running under Flatpak. To use this feature, OpenFreebuds need to have access to entire session bus, otherwise it won't find any working media players. Ensure that you're granted this permission, refer to FAQ for more details. + Похоже что вы запустили OpenFreebuds через Flatpak. Однако для работы этой функции требуются доступ к DBus-шине пользователя, иначе программа не увидит запущенные медиаплееры. Убедитесь, что доступ предоставлен, см. ЧаВо чтобы узнать подробнее. OfbQtMainWindow - + Select device Выбрать устройство - + Device info Об устройстве - + Dual-connect - Центр подключения + Двойное подключение - + Gestures Жесты - + Sound quality Качество звука - + Other settings - Другие настройки + Прочие настройки - + Application - + Приложение - + User interface - Интерфейс + Внешний вид - + Keyboard shortcuts Сочетания клавиш - + Linux-related Linux-специфичное - - About... - + + About… + О программе… - - Bugreport... + + Help: FAQ + Помощь: Частые вопросы + + + + Help: Remote control + Помощь: Удалённое управление + + + + Bugreport… Отчёт об ошибке… - + + Check for updates… + Проверить наличие обновлений… + + + + Remote access… + Удалённый доступ… + + + Temporary replace device Временно сменить устройство - + Close this window Закрыть окно - + Exit OpenFreebuds Закрыть OpenFreebuds - OfbQtSoundQualityModule + OfbQtManualConnectDialog - - New preset… - - - - - Delete… - - - - - Export to file… - - - - - Load file… - - - - - Create new equalizer preset - + + Manual connect… + Ручное подключение… - - Enter new preset name: - + + Enter bluetooth address of your device and select their model from list. You can find bluetooth address in system settings. + Введите Bluetooth-адрес устройства и выберите его модель из списка. Найти Bluetooth-адрес можно в настройках системы. - - Failed - + + Bluetooth address: + Bluetooth адрес: - - Can't create: too many custom preset created in device. - + + Device profile: + Профиль устройства: + + + OfbQtRpcConfig - - Delete equalizer mode? - + + Remote access… + Удалённый доступ… - - Will delete following mode: - + + Change this settings only if you know what you're doing. Require restart of all OpenFreebuds instances and all clients. + Изменяйте эти настройки только если знаете, что делаете. Потребуется перезапуск всех запущенных OpenFreebuds и иных клиентов. - - Save equalizer preset to file... - + + Allow controlling OpenFreebuds through network + Разрешить управлять OpenFreebuds через сеть - - Load equalizer preset from file... - + + Require following secret to be present in X-Secret header + Требовать наличие ключа ниже в HTTP-заголовке X-Secret - - Sound quality - Качество звука + + (enter new secret key) + (введите новый секретный ключ) + + + OfbQtSoundQualityModule Configure sound-related device settings. - Настройки устройства, относящиеся к звуку. + Настройки устройства, связанные с качеством звука. Sound quality preference: - Предпочтения по качеству звука + Предпочтение по качеству звука: @@ -768,17 +787,17 @@ Device will prefer loseless audio codecs, like LDAC. - Устройство будет предпочитать кодеки с меньшими потерями звуковой информации, наподобии LDAC. + Устройство будет предпочитать аудио-кодеки с лучшим качеством звука, вроде LDAC Prioritize connection quality - Предпочитать качество подключения + Предпочитать качество связи Device will prefer audio codes with better compression, like AAC - Устройство будет предпочитать аудио-кодеки с большим сжатием, наподобии AAC. + Устройство будет предпочитать аудио-кодеки с лучшим сжатием, вроде AAC @@ -788,171 +807,289 @@ Preset: - Пресет: - - - - ... - + Предустановка: Customize preset - + Настроить Save changes? - + Сохранить изменения? Save - + Сохранить + + + + New preset… + Новый… + + + + Delete… + Удалить… + + + + Export to file… + Экспорт в файл… + + + + Load file… + Загрузить файл… + + + + Create new equalizer preset + Создать новую предустановку эквалайзера + + + + Enter new preset name: + Введите название новой предустановки: + + + + Failed + Ошибка + + + + Can't create: too many custom preset created in device. + Не удалось: достигнут лимит кол-ва предустановок в памяти устройства. + + + + Delete equalizer mode? + Удалить предустановку эквалайзера? + + + + Will delete following mode: + Будет удалена предустановка: + + + + Save equalizer preset to file… + Сохранить предустановку в файл… + + + + Load equalizer preset from file… + Загрузить предустановку из файла… OfbQtTrayMenu - + Left headphone: - Левый наушник + Левый наушник: - + Right headphone: Правый наушник - + Battery case: - Кейс + Зарядный чехол: - + Battery: - Батарея + Батарея: - + Disable noise control - Без шумоподавления + Отключить - + Noise cancelling - Подавление шума + Шумоподавление - + Awareness Прозрачность - + Disconnect Отсоединить - + Connect Подключить - - Settings... + + Settings… Настройки… - - Bugreport... + + Bugreport… Отчёт об ошибке… - + Leave application - Выйти из OpenFreebuds + Закрыть программу OfbQtUiSettingsModule - - - UI Settings - - Looking for UI theme settings? Now it follows system-wide configuration. - + Ищите настройку темы оформления? Теперь она всегда соответствует системной настройке. Main - + Главное - Restart OpenFeebuds to apply changes - + Launch at system startup + Запускать вместе с системой Language: - + Язык интерфейса: System - + Системный + + + + Restart OpenFeebuds to apply changes + Перезапустите OpenFreebuds для применения изменения + + + + Update checker: + Проверка обновлений: + + + + Notify about new versions + Уведомлять о новых версиях + + + + Check for new versions, but don't notify + Проверять, но не оповещать + + + + Disabled + Отключить Tray applet - + Иконка в области уведомлений Icon color - + Цвет значка в трее Auto-select - + Авто Light - + Светлый Dark - + Тёмный Left-click action - + Действие по левому клику Show dual-connect device switcher in menu (if available) - + Показывать опции двойного подключения в меню (если доступно) Show equalizer preset switcher in menu (if available) - + Показывать опции эквалайзера в меню (если доступно) OfbTrayIcon - OpenFreebuds: Connecting to device... + OpenFreebuds: Connecting to device… OpenFreebuds: Подключение… + + ShortcutName + + + Connect device + Подключить устройство + + + + Disconnect device + Отсоединить устройство + + + + Connect/disconnect device + Подключить/отключить устройство + + + + Next noise control mode + Следующий режим шумоподавления + + + + Disable noise control + Отключить шумоподавление + + + + Enable noise cancellation + Включить шумоподавление + + + + Enable awareness mode + Включить режим прозрачность + + + + Enable low-latency mode + Включить режим низкой задержки + + diff --git a/openfreebuds_qt/assets/icon/action/settings.png b/openfreebuds_qt/assets/icon/action/settings.png new file mode 100644 index 0000000..321c4ec Binary files /dev/null and b/openfreebuds_qt/assets/icon/action/settings.png differ diff --git a/openfreebuds_qt/assets/icon/action/undo.png b/openfreebuds_qt/assets/icon/action/undo.png new file mode 100644 index 0000000..fefea0e Binary files /dev/null and b/openfreebuds_qt/assets/icon/action/undo.png differ diff --git a/openfreebuds_qt/assets/icon/dc/dual_connect_device.png b/openfreebuds_qt/assets/icon/dc/dual_connect_device.png new file mode 100644 index 0000000..4e612a0 Binary files /dev/null and b/openfreebuds_qt/assets/icon/dc/dual_connect_device.png differ diff --git a/openfreebuds_qt/assets/icon/dc/overlay_playing.png b/openfreebuds_qt/assets/icon/dc/overlay_playing.png new file mode 100644 index 0000000..f11a90a Binary files /dev/null and b/openfreebuds_qt/assets/icon/dc/overlay_playing.png differ diff --git a/openfreebuds_qt/assets/icon/dc/overlay_primary.png b/openfreebuds_qt/assets/icon/dc/overlay_primary.png new file mode 100644 index 0000000..96ebd43 Binary files /dev/null and b/openfreebuds_qt/assets/icon/dc/overlay_primary.png differ diff --git a/openfreebuds_qt/assets/base_headset.png b/openfreebuds_qt/assets/icon/tray/base_headset.png similarity index 100% rename from openfreebuds_qt/assets/base_headset.png rename to openfreebuds_qt/assets/icon/tray/base_headset.png diff --git a/openfreebuds_qt/assets/base_headset_1.png b/openfreebuds_qt/assets/icon/tray/base_headset_1.png similarity index 100% rename from openfreebuds_qt/assets/base_headset_1.png rename to openfreebuds_qt/assets/icon/tray/base_headset_1.png diff --git a/openfreebuds_qt/assets/base_headset_2.png b/openfreebuds_qt/assets/icon/tray/base_headset_2.png similarity index 100% rename from openfreebuds_qt/assets/base_headset_2.png rename to openfreebuds_qt/assets/icon/tray/base_headset_2.png diff --git a/openfreebuds_qt/assets/base_loading.png b/openfreebuds_qt/assets/icon/tray/base_loading.png similarity index 100% rename from openfreebuds_qt/assets/base_loading.png rename to openfreebuds_qt/assets/icon/tray/base_loading.png diff --git a/openfreebuds_qt/assets/overlay_error.png b/openfreebuds_qt/assets/icon/tray/overlay_error.png similarity index 100% rename from openfreebuds_qt/assets/overlay_error.png rename to openfreebuds_qt/assets/icon/tray/overlay_error.png diff --git a/openfreebuds_qt/assets/overlay_setup.png b/openfreebuds_qt/assets/icon/tray/overlay_setup.png similarity index 100% rename from openfreebuds_qt/assets/overlay_setup.png rename to openfreebuds_qt/assets/icon/tray/overlay_setup.png diff --git a/openfreebuds_qt/assets/image/ofb_linux_preview.png b/openfreebuds_qt/assets/image/ofb_linux_preview.png new file mode 100644 index 0000000..01e7005 Binary files /dev/null and b/openfreebuds_qt/assets/image/ofb_linux_preview.png differ diff --git a/openfreebuds_qt/assets/image/ofb_win32_preview.png b/openfreebuds_qt/assets/image/ofb_win32_preview.png new file mode 100644 index 0000000..13fa73d Binary files /dev/null and b/openfreebuds_qt/assets/image/ofb_win32_preview.png differ diff --git a/openfreebuds_qt/config/config_lock.py b/openfreebuds_qt/config/config_lock.py index b0ef35d..d38bacf 100644 --- a/openfreebuds_qt/config/config_lock.py +++ b/openfreebuds_qt/config/config_lock.py @@ -21,7 +21,7 @@ def acquire(): with open(ConfigLock._path, "r") as f: process = Process(int(f.read())) log.info(f"{Path(process.exe())}, {Path(sys.executable).resolve()}") - if Path(process.exe()) == Path(sys.executable).resolve(): + if os.getpid() != process.pid and Path(process.exe()) == Path(sys.executable).resolve(): # Found already running instance, non-exclusive lock ConfigLock.owned = False return diff --git a/openfreebuds_qt/config/main.py b/openfreebuds_qt/config/main.py index 352122b..4d26787 100644 --- a/openfreebuds_qt/config/main.py +++ b/openfreebuds_qt/config/main.py @@ -68,7 +68,7 @@ def get_tray_icon_theme(self): return "dark" if not backend_theme else "light" # Auto-detect using qt - return self.qt_is_dark_theme + return "dark" if not self.qt_is_dark_theme else "light" @cached_property def is_containerized_app(self): diff --git a/openfreebuds_qt/constants.py b/openfreebuds_qt/constants.py index e53ae51..b6af1e4 100644 --- a/openfreebuds_qt/constants.py +++ b/openfreebuds_qt/constants.py @@ -15,3 +15,16 @@ LINK_WEBSITE_HELP = "https://mmk.pw/en/openfreebuds/help" LINK_GITHUB = "https://github.com/melianmiko/OpenFreebuds/" LINK_RPC_HELP = "http://localhost:19823/" + +WIN32_BODY_STYLE = """ +QPushButton, +QComboBox, +QComboBox QAbstractItemView:item, +QTreeView::item { + padding: 6px 12px; +} + +QLineEdit { + padding: 4px 8px; +} +""" diff --git a/openfreebuds_qt/designer/about_module.ui b/openfreebuds_qt/designer/about_module.ui index 0c3277b..acbb5ed 100644 --- a/openfreebuds_qt/designer/about_module.ui +++ b/openfreebuds_qt/designer/about_module.ui @@ -11,7 +11,7 @@ - About + About diff --git a/openfreebuds_qt/designer/device_info.ui b/openfreebuds_qt/designer/device_info.ui index cc51672..91da350 100644 --- a/openfreebuds_qt/designer/device_info.ui +++ b/openfreebuds_qt/designer/device_info.ui @@ -11,7 +11,7 @@ - Deice information + Deice information @@ -139,7 +139,7 @@ - Device name + Device name @@ -153,7 +153,7 @@ - Nobody knows + Nobody knows diff --git a/openfreebuds_qt/designer/device_other.ui b/openfreebuds_qt/designer/device_other.ui index d1c2edc..b4df089 100644 --- a/openfreebuds_qt/designer/device_other.ui +++ b/openfreebuds_qt/designer/device_other.ui @@ -11,7 +11,7 @@ - Other settings + Other settings diff --git a/openfreebuds_qt/designer/dialog_error.ui b/openfreebuds_qt/designer/dialog_error.ui index 6828f23..2d83b5b 100644 --- a/openfreebuds_qt/designer/dialog_error.ui +++ b/openfreebuds_qt/designer/dialog_error.ui @@ -11,13 +11,13 @@ - OpenFreebuds + OpenFreebuds - OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clocking on "Close" button. + OpenFreebuds ran into error. Please, save bugreport and send them to developer. Bugreport will be generated after clicking on "Close" button. true @@ -60,7 +60,8 @@ - + + .. diff --git a/openfreebuds_qt/designer/dialog_manual_connect.ui b/openfreebuds_qt/designer/dialog_manual_connect.ui index 91272be..1f3bd7a 100644 --- a/openfreebuds_qt/designer/dialog_manual_connect.ui +++ b/openfreebuds_qt/designer/dialog_manual_connect.ui @@ -1,7 +1,7 @@ - Dialog - + OfbQtManualConnectDialog + 0 @@ -29,7 +29,7 @@ - Manual connect + Manual connect… @@ -120,7 +120,7 @@ buttonBox accepted() - Dialog + OfbQtManualConnectDialog accept() @@ -136,7 +136,7 @@ buttonBox rejected() - Dialog + OfbQtManualConnectDialog reject() diff --git a/openfreebuds_qt/designer/dialog_profile_picker.ui b/openfreebuds_qt/designer/dialog_profile_picker.ui index 6b2cd52..389cfe8 100644 --- a/openfreebuds_qt/designer/dialog_profile_picker.ui +++ b/openfreebuds_qt/designer/dialog_profile_picker.ui @@ -7,7 +7,7 @@ 0 0 400 - 237 + 200 @@ -27,13 +27,26 @@ - Notice that this may be dangerous for some kind of devices. Do it of your risk. You also can share information about your device and selected profile at GitHub, if you want get offical support. + Notice that this may be dangerous for some kind of devices. Continue only if you know what you're doing. true + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/openfreebuds_qt/designer/dual_connect.ui b/openfreebuds_qt/designer/dual_connect.ui index 3640184..37e6b4f 100644 --- a/openfreebuds_qt/designer/dual_connect.ui +++ b/openfreebuds_qt/designer/dual_connect.ui @@ -11,7 +11,7 @@ - Dual connect + Dual connect diff --git a/openfreebuds_qt/designer/first_run_dialog.ui b/openfreebuds_qt/designer/first_run_dialog.ui new file mode 100644 index 0000000..c73da20 --- /dev/null +++ b/openfreebuds_qt/designer/first_run_dialog.ui @@ -0,0 +1,278 @@ + + + OfbQtFirstRunDialog + + + + 0 + 0 + 570 + 320 + + + + + 16777215 + 320 + + + + Welcome + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 180 + 120 + + + + + 16777215 + 16777215 + + + + Image + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + This application allows you to manage your HUAWEI Bluetooth earphones. To access them, look for headphones icon in system tray panel, near other icons. + + + true + + + + + + + + 0 + 0 + + + + Left-click on this icon will cycle through noise cancellation modes (can be configured), right-click will provide access to full battery status and main options. Settings window provides access to all features. + + + true + + + + + + + + 0 + 0 + + + + If you're running under GNOME shell and can't find tray icon, please, check FAQ. + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Launch OpenFreebuds at system boot + + + true + + + + + + + You could change this options anytime later in settings. + + + true + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + FAQ + + + true + + + + + + + Get started + + + + + + + + + + + + faq_btn + clicked() + OfbQtFirstRunDialog + on_faq_click() + + + 436 + 300 + + + 285 + 160 + + + + + confirm_btn + clicked() + OfbQtFirstRunDialog + on_confirm() + + + 522 + 300 + + + 285 + 160 + + + + + + on_faq_click() + on_confirm() + + diff --git a/openfreebuds_qt/designer/hotkeys.ui b/openfreebuds_qt/designer/hotkeys.ui index 8e7bc6f..bd50534 100644 --- a/openfreebuds_qt/designer/hotkeys.ui +++ b/openfreebuds_qt/designer/hotkeys.ui @@ -11,7 +11,7 @@ - Hotkeys... + Hotkeys… diff --git a/openfreebuds_qt/designer/linux_extras.ui b/openfreebuds_qt/designer/linux_extras.ui index ea3520d..16b9d1d 100644 --- a/openfreebuds_qt/designer/linux_extras.ui +++ b/openfreebuds_qt/designer/linux_extras.ui @@ -11,7 +11,7 @@ - Linux-specific + Linux-specific diff --git a/openfreebuds_qt/designer/main_window.ui b/openfreebuds_qt/designer/main_window.ui index 1c4ad85..804b05a 100644 --- a/openfreebuds_qt/designer/main_window.ui +++ b/openfreebuds_qt/designer/main_window.ui @@ -23,7 +23,7 @@ - OpenFreebuds + OpenFreebuds #side_panel, #tabs_list_content { @@ -137,7 +137,7 @@ - OpenFreebuds v99 + OpenFreebuds v99 diff --git a/openfreebuds_qt/designer/module_device_select.ui b/openfreebuds_qt/designer/module_device_select.ui index c04e411..f47254f 100644 --- a/openfreebuds_qt/designer/module_device_select.ui +++ b/openfreebuds_qt/designer/module_device_select.ui @@ -11,7 +11,7 @@ - Change device... + Change device… QPushButton { diff --git a/openfreebuds_qt/designer/module_geatures.ui b/openfreebuds_qt/designer/module_geatures.ui index 356dea6..da12390 100644 --- a/openfreebuds_qt/designer/module_geatures.ui +++ b/openfreebuds_qt/designer/module_geatures.ui @@ -17,7 +17,7 @@ - Gestures + Gestures diff --git a/openfreebuds_qt/designer/sound_quality.ui b/openfreebuds_qt/designer/sound_quality.ui index 1fcfd75..918e7b2 100644 --- a/openfreebuds_qt/designer/sound_quality.ui +++ b/openfreebuds_qt/designer/sound_quality.ui @@ -11,7 +11,7 @@ - Sound quality + Sound quality @@ -101,7 +101,7 @@ QPushButton::menu-indicator{width:0px;} - ... + @@ -215,9 +215,6 @@ - - - diff --git a/openfreebuds_qt/designer/stupid_rpc_setup.ui b/openfreebuds_qt/designer/stupid_rpc_setup.ui index b2a01e4..f0d548b 100644 --- a/openfreebuds_qt/designer/stupid_rpc_setup.ui +++ b/openfreebuds_qt/designer/stupid_rpc_setup.ui @@ -1,17 +1,17 @@ - Dialog - + OfbQtRpcConfig + 0 0 363 - 172 + 189 - StupidRPC configuration + Remote access… @@ -68,7 +68,7 @@ buttonBox accepted() - Dialog + OfbQtRpcConfig accept() @@ -84,7 +84,7 @@ buttonBox rejected() - Dialog + OfbQtRpcConfig reject() diff --git a/openfreebuds_qt/designer/ui_settings.ui b/openfreebuds_qt/designer/ui_settings.ui index 8867f21..0f7119b 100644 --- a/openfreebuds_qt/designer/ui_settings.ui +++ b/openfreebuds_qt/designer/ui_settings.ui @@ -11,7 +11,7 @@ - UI Settings + UI Settings diff --git a/openfreebuds_qt/main.py b/openfreebuds_qt/main.py index c823f96..edf600b 100644 --- a/openfreebuds_qt/main.py +++ b/openfreebuds_qt/main.py @@ -12,6 +12,7 @@ from openfreebuds import IOpenFreebuds, create as create_ofb, OfbEventKind from openfreebuds.constants import STORAGE_PATH from openfreebuds.utils.logger import setup_logging, screen_handler, create_logger +from openfreebuds_qt.app.dialog.first_run import OfbQtFirstRunDialog from openfreebuds_qt.app.main import OfbQtMainWindow from openfreebuds_qt.config import OfbQtConfigParser, ConfigLock from openfreebuds_qt.constants import IGNORED_LOG_TAGS, I18N_PATH @@ -47,7 +48,7 @@ def __init__(self, args): # Setup logging setup_logging(args.verbose) if not args.verbose: - screen_handler.setLevel(logging.WARN) + screen_handler.setLevel(logging.ERROR) if not args.dont_ignore_logs: for tag in IGNORED_LOG_TAGS: logging.getLogger(tag).disabled = True @@ -120,10 +121,14 @@ async def boot(self): self.tray.show() if self.args.settings: self.main_window.show() + if not self.config.get("ui", "first_run_finished", False): + OfbQtFirstRunDialog(self).show() except SystemExit as e: self.qt_app.exit(e.args[0]) ConfigLock.release() return + except Exception: + log.exception("Boot failure") async def exit(self, ret_code: int = 0): await self.tray.close() @@ -169,7 +174,7 @@ async def _stage_shortcut(self): if self.ofb.role == "standalone": await self.restore_device() while await self.ofb.get_state() != IOpenFreebuds.STATE_CONNECTED: - log.debug("Waiting for device connect...") + log.debug("Waiting for device connect…") await asyncio.sleep(1) await self.ofb.run_shortcut(self.args.shortcut) diff --git a/openfreebuds_qt/tray/main.py b/openfreebuds_qt/tray/main.py index 087155f..b3a1726 100644 --- a/openfreebuds_qt/tray/main.py +++ b/openfreebuds_qt/tray/main.py @@ -75,6 +75,7 @@ async def _update_ui(self, event: OfbCoreEvent): """ state = await self.ofb.get_state() + log.info(f"theme={self.config.get_tray_icon_theme()}") # Update icon icon = create_tray_icon(self.config.get_tray_icon_theme(), @@ -88,7 +89,7 @@ async def _update_ui(self, event: OfbCoreEvent): if state == IOpenFreebuds.STATE_CONNECTED: self.setToolTip(await self._get_tooltip_text(event)) elif state == IOpenFreebuds.STATE_WAIT: - self.setToolTip(self.tr("OpenFreebuds: Connecting to device...")) + self.setToolTip(self.tr("OpenFreebuds: Connecting to device…")) else: self.setToolTip("OpenFreebuds") @@ -136,6 +137,6 @@ async def _update_loop(self): except asyncio.CancelledError: await self.ofb.unsubscribe(member_id) except OfbServerDeadError: - log.info("Server is dead, exiting now...") + log.info("Server is dead, exiting now…") self.ui_update_task = None await self.ctx.exit(1) diff --git a/openfreebuds_qt/tray/menu.py b/openfreebuds_qt/tray/menu.py index b373984..d187f8a 100644 --- a/openfreebuds_qt/tray/menu.py +++ b/openfreebuds_qt/tray/menu.py @@ -74,7 +74,7 @@ def __init__(self, tray: IOfbTrayIcon, context: IOfbQtApplication, ofb: IOpenFre # Extras self.new_section() - self.add_item(self.tr("Settings..."), callback=self.do_settings) + self.add_item(self.tr("Settings…"), callback=self.do_settings) self.equalizer_submenu = OfbDeviceEqualizerTrayMenu(self, self.ctx) self.equalizer_action = self.add_menu(self.equalizer_submenu) self.dual_connect_submenu = OfbDeviceDualConnectTrayMenu(self, self.ctx) @@ -83,7 +83,7 @@ def __init__(self, tray: IOfbTrayIcon, context: IOfbQtApplication, ofb: IOpenFre # Footer self.new_section() - self.add_item(self.tr("Bugreport..."), callback=self.do_bugreport) + self.add_item(self.tr("Bugreport…"), callback=self.do_bugreport) self.add_item(self.tr("Leave application"), callback=self.do_exit) async def on_core_event(self, event: OfbCoreEvent, state: int): diff --git a/openfreebuds_qt/tray/menu_anc_level.py b/openfreebuds_qt/tray/menu_anc_level.py index b1b51c4..e1de5bd 100644 --- a/openfreebuds_qt/tray/menu_anc_level.py +++ b/openfreebuds_qt/tray/menu_anc_level.py @@ -18,7 +18,7 @@ def __init__(self, parent: QWidget, ofb: IOpenFreebuds): "voice_boost": self.tr("Voice boost"), } - self.setTitle(self.tr("Intensity...")) + self.setTitle(self.tr("Intensity…")) self.anc_level_actions: dict[str, QAction] = {} for code in self.anc_level_option_names: self._add_anc_level_option(code, self.anc_level_option_names[code]) diff --git a/openfreebuds_qt/tray/menu_dual_connect.py b/openfreebuds_qt/tray/menu_dual_connect.py index 718e900..653f793 100644 --- a/openfreebuds_qt/tray/menu_dual_connect.py +++ b/openfreebuds_qt/tray/menu_dual_connect.py @@ -11,7 +11,7 @@ class OfbDeviceDualConnectTrayMenu(OfbQtTrayMenuCommon): def __init__(self, parent: QWidget, ctx: IOfbQtApplication): super().__init__(parent, ctx.ofb) - self.setTitle(self.tr("Dual-connect...")) + self.setTitle(self.tr("Dual-connect…")) async def update_ui(self): data = await self.ofb.get_property("dual_connect") diff --git a/openfreebuds_qt/tray/menu_equalizer.py b/openfreebuds_qt/tray/menu_equalizer.py index 38024ba..415c7bb 100644 --- a/openfreebuds_qt/tray/menu_equalizer.py +++ b/openfreebuds_qt/tray/menu_equalizer.py @@ -14,7 +14,7 @@ class OfbDeviceEqualizerTrayMenu(OfbQtTrayMenuCommon): def __init__(self, parent: QWidget, ctx: IOfbQtApplication): super().__init__(parent, ctx.ofb) - self.setTitle(self.tr("Equalizer preset...")) + self.setTitle(self.tr("Equalizer preset…")) self.eq_preset_names = get_eq_preset_names() async def update_ui(self): diff --git a/openfreebuds_qt/utils/hotkeys/recorder.py b/openfreebuds_qt/utils/hotkeys/recorder.py index e005675..8835ce3 100644 --- a/openfreebuds_qt/utils/hotkeys/recorder.py +++ b/openfreebuds_qt/utils/hotkeys/recorder.py @@ -29,7 +29,6 @@ async def record(self): self.listener = keyboard.Listener(on_press=self.on_press, on_release=self.on_release) self.listener.start() - log.debug("Recording...") while self.working: await asyncio.sleep(0.5) diff --git a/openfreebuds_qt/utils/icon/__init__.py b/openfreebuds_qt/utils/icon/__init__.py index f05f282..721fadb 100644 --- a/openfreebuds_qt/utils/icon/__init__.py +++ b/openfreebuds_qt/utils/icon/__init__.py @@ -1,3 +1,3 @@ from .tray_factory import create_tray_icon from .dual_connect_device import create_dual_connect_icon -from .qt_icon import get_qt_icon_colored +from .qt_icon import get_img_colored diff --git a/openfreebuds_qt/utils/icon/dual_connect_device.py b/openfreebuds_qt/utils/icon/dual_connect_device.py index bac0c88..b00196d 100644 --- a/openfreebuds_qt/utils/icon/dual_connect_device.py +++ b/openfreebuds_qt/utils/icon/dual_connect_device.py @@ -5,14 +5,15 @@ from openfreebuds_qt.utils.draw import image_combine_mask ICON_SIZE = (32, 32) +DC_ICONS_PATH = ASSETS_PATH / "icon/dc" # Load files BASE_DC_DEVICE_ICONS = { - "device": Image.open(ASSETS_PATH / "dual_connect_device.png"), + "device": Image.open(DC_ICONS_PATH / "dual_connect_device.png"), } -OVERLAY_PLAYING = Image.open(ASSETS_PATH / "overlay_playing.png") +OVERLAY_PLAYING = Image.open(DC_ICONS_PATH / "overlay_playing.png") OVERLAY_PLAYING.thumbnail(ICON_SIZE) -OVERLAY_PRIMARY = Image.open(ASSETS_PATH / "overlay_primary.png") +OVERLAY_PRIMARY = Image.open(DC_ICONS_PATH / "overlay_primary.png") OVERLAY_PRIMARY.thumbnail(ICON_SIZE) # Presets @@ -45,20 +46,21 @@ def create_dual_connect_icon( foreground=Image.new("RGBA", ICON_SIZE, color=main_icon_color), background=PRESET_TRANSPARENT) + try: + r, g, b, a = palette.accent().color().getRgb() + accent_color = (255 - r, 255 - g, 255 - b, a) + except AttributeError: + accent_color = (255, 102, 0) + if is_playing: - try: - accent_color = palette.accent().color().getRgb() - except AttributeError: - accent_color = (0, 128, 256) overlay = image_combine_mask(OVERLAY_PLAYING, foreground=Image.new("RGBA", ICON_SIZE, color=accent_color), background=PRESET_TRANSPARENT) icon = Image.alpha_composite(icon, overlay) if is_primary: - link_color = palette.link().color().getRgb() overlay = image_combine_mask(OVERLAY_PRIMARY, - foreground=Image.new("RGBA", ICON_SIZE, color=link_color), + foreground=Image.new("RGBA", ICON_SIZE, color=accent_color), background=PRESET_TRANSPARENT) icon = Image.alpha_composite(icon, overlay) diff --git a/openfreebuds_qt/utils/icon/qt_icon.py b/openfreebuds_qt/utils/icon/qt_icon.py index 285963d..1a9e91f 100644 --- a/openfreebuds_qt/utils/icon/qt_icon.py +++ b/openfreebuds_qt/utils/icon/qt_icon.py @@ -1,20 +1,17 @@ import functools from PIL import Image, ImageQt -from PyQt6.QtGui import QIcon +from PyQt6.QtGui import QPixmap from openfreebuds_qt.constants import ASSETS_PATH from openfreebuds_qt.utils.draw import image_combine_mask -ICON_SIZE = (64, 64) -PRESET_TRANSPARENT = Image.new("RGBA", ICON_SIZE, color="#00000000") - @functools.cache -def get_qt_icon_colored(name: str, color) -> QIcon: - image = Image.open(ASSETS_PATH / f"icon_{name}.png") +def get_img_colored(name: str, color, base_dir: str = "icon/action") -> QPixmap: + image = Image.open(ASSETS_PATH / f"{base_dir}/{name}.png") image = image_combine_mask(image, - foreground=Image.new("RGBA", ICON_SIZE, color=color), - background=PRESET_TRANSPARENT) + foreground=Image.new("RGBA", image.size, color=color), + background=Image.new("RGBA", image.size, color="#00000000")) - return QIcon(ImageQt.toqpixmap(image)) + return ImageQt.toqpixmap(image) diff --git a/openfreebuds_qt/utils/icon/tray_factory.py b/openfreebuds_qt/utils/icon/tray_factory.py index d61d1b4..32954e2 100644 --- a/openfreebuds_qt/utils/icon/tray_factory.py +++ b/openfreebuds_qt/utils/icon/tray_factory.py @@ -7,14 +7,15 @@ from openfreebuds_qt.utils.draw import image_combine_mask, image_spawn_bg_mask ICON_SIZE = (64, 64) +TRAY_ICON_PATH = ASSETS_PATH / "icon/tray" # Images -ICON_LOADING = Image.open(ASSETS_PATH / "base_loading.png") -ICON_ANC_OFF = Image.open(ASSETS_PATH / "base_headset.png") -ICON_ANC_ON = Image.open(ASSETS_PATH / "base_headset_1.png") -ICON_ANC_AWR = Image.open(ASSETS_PATH / "base_headset_2.png") -ICON_OVERLAY_ERROR = Image.open(ASSETS_PATH / "overlay_error.png") -ICON_OVERLAY_SETUP = Image.open(ASSETS_PATH / "overlay_setup.png") +ICON_LOADING = Image.open(TRAY_ICON_PATH / "base_loading.png") +ICON_ANC_OFF = Image.open(TRAY_ICON_PATH / "base_headset.png") +ICON_ANC_ON = Image.open(TRAY_ICON_PATH / "base_headset_1.png") +ICON_ANC_AWR = Image.open(TRAY_ICON_PATH / "base_headset_2.png") +ICON_OVERLAY_ERROR = Image.open(TRAY_ICON_PATH / "overlay_error.png") +ICON_OVERLAY_SETUP = Image.open(TRAY_ICON_PATH / "overlay_setup.png") # Presets PRESET_TRANSPARENT = Image.new("RGBA", ICON_SIZE, color="#00000000") diff --git a/openfreebuds_qt/version_info.py b/openfreebuds_qt/version_info.py index aabd42f..c42c1cb 100644 --- a/openfreebuds_qt/version_info.py +++ b/openfreebuds_qt/version_info.py @@ -1,83 +1,36 @@ -VERSION = '0.99.1' +VERSION = '0.14.0' LIBRARIES = [ - 'aiocmd==0.1.5 ; python_version >= "3.10" and python_version < "3.13"', - 'aiohappyeyeballs==2.4.0 ; python_version >= "3.10" and python_version < "3.13"', - 'aiohttp==3.10.5 ; python_version >= "3.10" and python_version < "3.13"', - 'aiosignal==1.3.1 ; python_version >= "3.10" and python_version < "3.13"', - 'altgraph==0.17.4 ; python_version >= "3.10" and python_version < "3.13"', - 'async-timeout==4.0.3 ; python_version >= "3.10" and python_version < "3.11"', - 'attrs==24.2.0 ; python_version >= "3.10" and python_version < "3.13"', - 'build==1.2.1 ; python_version >= "3.10" and python_version < "3.13"', - 'cachecontrol[filecache]==0.14.0 ; python_version >= "3.10" and python_version < "3.13"', - 'certifi==2024.8.30 ; python_version >= "3.10" and python_version < "3.13"', - 'cffi==1.17.0 ; python_version >= "3.10" and python_version < "3.13" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy")', - 'charset-normalizer==3.3.2 ; python_version >= "3.10" and python_version < "3.13"', - 'cleo==2.1.0 ; python_version >= "3.10" and python_version < "3.13"', - 'colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and os_name == "nt"', - 'crashtest==0.4.1 ; python_version >= "3.10" and python_version < "3.13"', - 'cryptography==43.0.0 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "linux"', - 'distlib==0.3.8 ; python_version >= "3.10" and python_version < "3.13"', - 'dulwich==0.21.7 ; python_version >= "3.10" and python_version < "3.13"', - 'evdev==1.7.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform in "linux"', - 'fastjsonschema==2.20.0 ; python_version >= "3.10" and python_version < "3.13"', - 'filelock==3.15.4 ; python_version >= "3.10" and python_version < "3.13"', - 'frozenlist==1.4.1 ; python_version >= "3.10" and python_version < "3.13"', - 'idna==3.8 ; python_version >= "3.10" and python_version < "3.13"', - 'importlib-metadata==8.4.0 ; python_version >= "3.10" and python_version < "3.12"', - 'installer==0.7.0 ; python_version >= "3.10" and python_version < "3.13"', - 'jaraco-classes==3.4.0 ; python_version >= "3.10" and python_version < "3.13"', - 'jeepney==0.8.0 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "linux"', - 'keyring==24.3.1 ; python_version >= "3.10" and python_version < "3.13"', - 'macholib==1.16.3 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', - 'more-itertools==10.4.0 ; python_version >= "3.10" and python_version < "3.13"', - 'msgpack==1.0.8 ; python_version >= "3.10" and python_version < "3.13"', - 'multidict==6.0.5 ; python_version >= "3.10" and python_version < "3.13"', - 'packaging==24.1 ; python_version >= "3.10" and python_version < "3.13"', - 'pefile==2024.8.26 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "win32"', - 'pexpect==4.9.0 ; python_version >= "3.10" and python_version < "3.13"', - 'pillow==10.4.0 ; python_version >= "3.10" and python_version < "3.13"', - 'pkginfo==1.11.1 ; python_version >= "3.10" and python_version < "3.13"', - 'platformdirs==4.2.2 ; python_version >= "3.10" and python_version < "3.13"', - 'poetry-core==1.9.0 ; python_version >= "3.10" and python_version < "3.13"', - 'poetry-plugin-export==1.8.0 ; python_version >= "3.10" and python_version < "3.13"', - 'poetry==1.8.3 ; python_version >= "3.10" and python_version < "3.13"', - 'prompt-toolkit==3.0.47 ; python_version >= "3.10" and python_version < "3.13"', - 'psutil==6.0.0 ; python_version >= "3.10" and python_version < "3.13"', - 'ptyprocess==0.7.0 ; python_version >= "3.10" and python_version < "3.13"', - 'pycairo==1.26.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "linux"', - 'pycparser==2.22 ; python_version >= "3.10" and python_version < "3.13" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy")', - 'pygobject==3.48.2 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "linux"', - 'pyinstaller-hooks-contrib==2024.8 ; python_version >= "3.10" and python_version < "3.13"', - 'pyinstaller==6.10.0 ; python_version >= "3.10" and python_version < "3.13"', - 'pynput==1.7.7 ; python_version >= "3.10" and python_version < "3.13"', - 'pyobjc-core==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', - 'pyobjc-framework-applicationservices==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', - 'pyobjc-framework-cocoa==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', - 'pyobjc-framework-coretext==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', - 'pyobjc-framework-quartz==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', - 'pyproject-hooks==1.1.0 ; python_version >= "3.10" and python_version < "3.13"', - 'pyqt6-qt6==6.7.2 ; python_version >= "3.10" and python_version < "3.13"', - 'pyqt6-sip==13.8.0 ; python_version >= "3.10" and python_version < "3.13"', - 'pyqt6==6.7.1 ; python_version >= "3.10" and python_version < "3.13"', - 'python-xlib==0.33 ; python_version >= "3.10" and python_version < "3.13" and sys_platform in "linux"', - 'pywin32-ctypes==0.2.3 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "win32"', - 'qasync==0.27.1 ; python_version >= "3.10" and python_version < "3.13"', - 'rapidfuzz==3.9.6 ; python_version >= "3.10" and python_version < "3.13"', - 'requests-toolbelt==1.0.0 ; python_version >= "3.10" and python_version < "3.13"', - 'requests==2.32.3 ; python_version >= "3.10" and python_version < "3.13"', - 'sdbus==0.12.0 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "linux"', - 'secretstorage==3.3.3 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "linux"', - 'setuptools==74.0.0 ; python_version >= "3.10" and python_version < "3.13"', - 'shellingham==1.5.4 ; python_version >= "3.10" and python_version < "3.13"', - 'six==1.16.0 ; python_version >= "3.10" and python_version < "3.13"', - 'tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11"', - 'tomlkit==0.13.2 ; python_version >= "3.10" and python_version < "3.13"', - 'trove-classifiers==2024.7.2 ; python_version >= "3.10" and python_version < "3.13"', - 'urllib3==2.2.2 ; python_version >= "3.10" and python_version < "3.13"', - 'virtualenv==20.26.3 ; python_version >= "3.10" and python_version < "3.13"', - 'wcwidth==0.2.13 ; python_version >= "3.10" and python_version < "3.13"', - 'winsdk==1.0.0b10 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "win32"', - 'xattr==1.1.0 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', - 'yarl==1.9.5 ; python_version >= "3.10" and python_version < "3.13"', - 'zipp==3.20.1 ; python_version >= "3.10" and python_version < "3.12"', + 'aiocmd==0.1.5 ; python_version >= "3.10" and python_version < "3.13"', + 'aiohappyeyeballs==2.4.2 ; python_version >= "3.10" and python_version < "3.13"', + 'aiohttp==3.10.7 ; python_version >= "3.10" and python_version < "3.13"', + 'aiosignal==1.3.1 ; python_version >= "3.10" and python_version < "3.13"', + 'async-timeout==4.0.3 ; python_version >= "3.10" and python_version < "3.11"', + 'attrs==24.2.0 ; python_version >= "3.10" and python_version < "3.13"', + 'dbus-next==0.2.3 ; python_version >= "3.10" and python_version < "3.13"', + 'evdev==1.7.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform in "linux"', + 'frozenlist==1.4.1 ; python_version >= "3.10" and python_version < "3.13"', + 'idna==3.10 ; python_version >= "3.10" and python_version < "3.13"', + 'mmk-updater==0.15.3 ; python_version >= "3.10" and python_version < "3.13"', + 'multidict==6.1.0 ; python_version >= "3.10" and python_version < "3.13"', + 'packaging==24.1 ; python_version >= "3.10" and python_version < "3.13"', + 'pillow==10.4.0 ; python_version >= "3.10" and python_version < "3.13"', + 'prompt-toolkit==3.0.48 ; python_version >= "3.10" and python_version < "3.13"', + 'psutil==6.0.0 ; python_version >= "3.10" and python_version < "3.13"', + 'pynput==1.7.7 ; python_version >= "3.10" and python_version < "3.13"', + 'pyobjc-core==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', + 'pyobjc-framework-applicationservices==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', + 'pyobjc-framework-cocoa==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', + 'pyobjc-framework-coretext==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', + 'pyobjc-framework-quartz==10.3.1 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "darwin"', + 'pyqt6-qt6==6.7.2 ; python_version >= "3.10" and python_version < "3.13"', + 'pyqt6-sip==13.8.0 ; python_version >= "3.10" and python_version < "3.13"', + 'pyqt6==6.7.1 ; python_version >= "3.10" and python_version < "3.13"', + 'python-xlib==0.33 ; python_version >= "3.10" and python_version < "3.13" and sys_platform in "linux"', + 'qasync==0.27.1 ; python_version >= "3.10" and python_version < "3.13"', + 'six==1.16.0 ; python_version >= "3.10" and python_version < "3.13"', + 'typing-extensions==4.12.2 ; python_version >= "3.10" and python_version < "3.11"', + 'wcwidth==0.2.13 ; python_version >= "3.10" and python_version < "3.13"', + 'winsdk==1.0.0b10 ; python_version >= "3.10" and python_version < "3.13" and sys_platform == "win32"', + 'yarl==1.13.1 ; python_version >= "3.10" and python_version < "3.13"', ] + diff --git a/poetry.lock b/poetry.lock index fd97f61..1999894 100644 --- a/poetry.lock +++ b/poetry.lock @@ -17,113 +17,113 @@ prompt-toolkit = ">=2.0.9" [[package]] name = "aiohappyeyeballs" -version = "2.4.0" +version = "2.4.2" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd"}, - {file = "aiohappyeyeballs-2.4.0.tar.gz", hash = "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2"}, + {file = "aiohappyeyeballs-2.4.2-py3-none-any.whl", hash = "sha256:8522691d9a154ba1145b157d6d5c15e5c692527ce6a53c5e5f9876977f6dab2f"}, + {file = "aiohappyeyeballs-2.4.2.tar.gz", hash = "sha256:4ca893e6c5c1f5bf3888b04cb5a3bee24995398efef6e0b9f747b5e89d84fd74"}, ] [[package]] name = "aiohttp" -version = "3.10.5" +version = "3.10.7" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683"}, - {file = "aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef"}, - {file = "aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058"}, - {file = "aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072"}, - {file = "aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6"}, - {file = "aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12"}, - {file = "aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987"}, - {file = "aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04"}, - {file = "aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511"}, - {file = "aiohttp-3.10.5-cp38-cp38-win32.whl", hash = "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a"}, - {file = "aiohttp-3.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11"}, - {file = "aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1"}, - {file = "aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862"}, - {file = "aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691"}, + {file = "aiohttp-3.10.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df23cb35bec54b73fba371c7c904994433651458acf8bfb7c84464fef5834c0a"}, + {file = "aiohttp-3.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f33a6d023b207ad8227e607814c0020b42c53e01a66004fc0f2555e1a4941282"}, + {file = "aiohttp-3.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4d23df9f01c8945d03cffcdd9ba9bfd88aa21ac567a39d0ac4d0c80499ed0d23"}, + {file = "aiohttp-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ddf2c8c9ec6bb3f5c057e5c95605adb8e3f1e2d999e8801736f448aff29280e"}, + {file = "aiohttp-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d09e40e2ae6723af487ffde019055d0b6ce4eae0749fcfe9de624b61f1af6ec"}, + {file = "aiohttp-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc1f4e0f4b1ae9289b4d0cc3bf5d6d55176c38ef1d41484550f3f9a0a78bedae"}, + {file = "aiohttp-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:636e3efb0bb024817cefa1ef86d678d1a73eb210ae162aff4234214060011ff5"}, + {file = "aiohttp-3.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bab2544f09cd1db154c105e03b1c941032fd7237da5da184595771999ca90daa"}, + {file = "aiohttp-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:431852e77cd72f60a0278f8cf557c8e568cd856f755a4b6c5232c7d8c6343d2e"}, + {file = "aiohttp-3.10.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6bae913cbb183cd34863905088ef26a17c75332bd6bdd451ee8bf158c987cf19"}, + {file = "aiohttp-3.10.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:278cd430ba93a157ad1faf490fdd6051801085ffa31a27762133472555e56888"}, + {file = "aiohttp-3.10.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e083e29b6db8e34a507cd678f89eab3ae5f307486ea6010c6473436d3769628d"}, + {file = "aiohttp-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:150deb28d5302cfec89fc31ea4bce774df06f5c03d95519f7588ca6517a472d7"}, + {file = "aiohttp-3.10.7-cp310-cp310-win32.whl", hash = "sha256:e19337d6552af197ebb8c886daea0b938ae34eff776c1fa914ad433f6db3970f"}, + {file = "aiohttp-3.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:bff7ef30cb6fc186ea6dda9e19d6105b1c213e3a3f759b5a23c271c778027260"}, + {file = "aiohttp-3.10.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1378164474a3866f7684a95efede1bee4016cd104bc10bf885e492c4459b715a"}, + {file = "aiohttp-3.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:87d0e52b2905dbc1aeffcbf0611fa82e27874764332c11b984293a4b91cc8e9f"}, + {file = "aiohttp-3.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2783754bfcee0b13b8e55932b418cf8984c17099fd1b37341d4696447d0c328"}, + {file = "aiohttp-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d26881d98274ef0dbd4f069f383e5e90eb6e42e957289db14c47186386832ce"}, + {file = "aiohttp-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e152296b2c50417445eacdb2353d3c10e702f6593aa774277510fb7761304302"}, + {file = "aiohttp-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf1cd9bfd598899396bdb8a4dc5234144a77e482e7489972b7956cf66e272872"}, + {file = "aiohttp-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:871c2bf68ecc55056e5e3b0ae5929a1149f41c4255bbf99b1f858005f63360d1"}, + {file = "aiohttp-3.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd8a0a0ef895e4c3f1afd31c2a6f89d68a94baacdbe2eb9bf90ac54b997cf99b"}, + {file = "aiohttp-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:99c11c5d632fa2222cc5805105841f6f3c40df116368fde40fbd71f8b14ea692"}, + {file = "aiohttp-3.10.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8fbf91559400fe1a98d84af36f5a66aa59c359ac3cb113b17d304ced6a4601b4"}, + {file = "aiohttp-3.10.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:73f151a1e21369a84d56b91a209590c23270c847463029fdcbda710516217644"}, + {file = "aiohttp-3.10.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:80531f6f4fff5a1f7e495afbc4aff5c4230b605f26d56c40ecad27a269665608"}, + {file = "aiohttp-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:164068b338c52dfe44f3490c70ef7b33c0e73d441c89f599ae2d93f7dcf3e395"}, + {file = "aiohttp-3.10.7-cp311-cp311-win32.whl", hash = "sha256:a84fe27904dbb43a236532d6d841d6132200b7bb53ba73d0300b0b586ceab6cc"}, + {file = "aiohttp-3.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:beda1abd7b23d489a5b66a46eba5a9e0db58e4ad91d68697409eeabda343fb9d"}, + {file = "aiohttp-3.10.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:68120c12c98bfc0e024ef1279be5f41327a54a5094710adc970ecc9724b91871"}, + {file = "aiohttp-3.10.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e1a9b4026b6fe41adde784e308b0ad0d6a8b5cc9062f9c349125fd57149bc8a9"}, + {file = "aiohttp-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85d8a1d716516ef92c769eadb020600d27223899018ef8d07c09c117001cc7d5"}, + {file = "aiohttp-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87652147515031dafc1b37c9c3c42fbe9e2697af6264ec26080a6fe603cc5196"}, + {file = "aiohttp-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c6140d6cbf8eebbcf1528364ce0b26d0a95788111659cfc008fba3a12fc874f"}, + {file = "aiohttp-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:342600665e74eea20b3286045ebeb0aa2f9cececf2eb0acc6f6817205b112b29"}, + {file = "aiohttp-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b7794b3d23451e355b4a87959943125afff8dd31d8059651c2734de12f9e7f2"}, + {file = "aiohttp-3.10.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d8d12d6a192f7b9f8a335cad8634a4f081d8319b75dd42257a1a3e557848d00"}, + {file = "aiohttp-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b5d8c94fd23f41007799ec657e18661f9f8c5b566a1e4fe944e3514e505a6b49"}, + {file = "aiohttp-3.10.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a1fe407bec2f14a3d79ec92aa767b930857a6782589ea87ac76fd8081dea3dab"}, + {file = "aiohttp-3.10.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7ed4435dcf507ef2de5b4be64276933eb19c78e5c7d00ca376fcd9a67d0139a0"}, + {file = "aiohttp-3.10.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c161f9e353f291d23069a8f67180fd52c76d72d4671f4f53602ea9ac29f47d50"}, + {file = "aiohttp-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:caf083bf26b1e286ab1929dbd8d8cab6230160576a0ed5e3bfb3487bb19474c2"}, + {file = "aiohttp-3.10.7-cp312-cp312-win32.whl", hash = "sha256:4296dd120e7e9728625eef1091039aff1a454c7147913d47839876c94b202226"}, + {file = "aiohttp-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:10d19997f2f8d49d53b76163b71e263bb7b23f48041d0d4050a43445a0052c35"}, + {file = "aiohttp-3.10.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:582536d3d7f95a6d4d072d2326dd03eeb1549c1cc86d02c9bcec71899f4c66f2"}, + {file = "aiohttp-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:365eff442a47b13e0e12c37240a6f75940ebee0b7943af43c84d5b43643fc80c"}, + {file = "aiohttp-3.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e2e0083e6f9f9cb0a0bedd694782e7fb8a54eb4de40e1743d9bb526f1c1eea88"}, + {file = "aiohttp-3.10.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da5a03cbe746f182f7b61e119dde24d388cf77965fea320bc8aba61b75039d06"}, + {file = "aiohttp-3.10.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b210484fccff00cafa9bd8abedea8749b6d975df8c8e21c82d92bb25403db85"}, + {file = "aiohttp-3.10.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b75cfa1e5fc7c87fc5f9de7124bb039b898791bb87207d2107bed5e3509670f"}, + {file = "aiohttp-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b4aa816cd3ab876f96ce8c6986648392137cbd6feddbf4189322515f34e1f6"}, + {file = "aiohttp-3.10.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3915944c87c9bf488db4ca1ae6edca40b5bc77c4c2cf2f49b69886bc47b97db1"}, + {file = "aiohttp-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cd658aeaa65fb99fcc3b93882bb33cbd600501d40473488aec163a981d7b05ee"}, + {file = "aiohttp-3.10.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:aeea07c89a5a53463c70957feb85d4b846982c0f054b521fc44f52862e7871cf"}, + {file = "aiohttp-3.10.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f8aaa0bc8e39352684982b378ba3f7e32e78a746da433aaeceb7e93d7fdf9ce3"}, + {file = "aiohttp-3.10.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f25a79ac4ac0bd94cf283d3e86e6f3ec78fc39e2de6949b902c342148b7b5f6"}, + {file = "aiohttp-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fc3538efae4e4df222a563559f8766234f49e845e8dbb2dd477eb8f3fd97242"}, + {file = "aiohttp-3.10.7-cp313-cp313-win32.whl", hash = "sha256:eea89c47ae8d592f7563f4355132fe844b5e2f8660292deacc292253bef291cd"}, + {file = "aiohttp-3.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:7ce1b54feaaf264e28a4474e13635d302a59aafb720b18c3c2885b8f35ce5040"}, + {file = "aiohttp-3.10.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7a372f9ea521741667cec2ef4a64419448030411af2e844dfa8dbbb8074baea6"}, + {file = "aiohttp-3.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:feff2170b23921a526f31d78c8f76bbb9cde825e78035286d8571ce0c81901ab"}, + {file = "aiohttp-3.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa42c4e78925a438a6f7df0d9b165d29cdc0a44fc5ce838d6c293a0161a2bd9a"}, + {file = "aiohttp-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ced77f4dd0c4f0107ee96f8df162b984470ac9f94ef93dd44dba62838fd85cde"}, + {file = "aiohttp-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13085c0129a906b001d87dd43e247155f6c76820d98147c079b746e8a0665b17"}, + {file = "aiohttp-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b92100555f86b314ed840ed61d937fc30ca39ad453c9aa9020414a3cce955d9b"}, + {file = "aiohttp-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77bc82d7b10f377957ba8e99bb1b13d946e9e9038fe89ba0888ad0b12e60c9c0"}, + {file = "aiohttp-3.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6052d92b47b8cf3736b1f01ac8f83cf02f188ef7542848055a5e227db0e16cb"}, + {file = "aiohttp-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:82fa5fb983922b03f2b08d1140550c68b50313305115639e19b13489c284c30c"}, + {file = "aiohttp-3.10.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:0246659d9a54a23a83f11842bdd58f335a1370aa66b376eeae16b7cf29009dde"}, + {file = "aiohttp-3.10.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:befc2f0794bc4bbbb1f8d0e245d32ee13331205b58f54910789e9e78d2a6fbf5"}, + {file = "aiohttp-3.10.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:9cd67e5c84cb75a471b2e35f3fb0da52e6d359d1794d3465a87052fb240e64b5"}, + {file = "aiohttp-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:af10344fb1ee195b2cd5840b61d8c8121b16d3b3baa2da5a86cf4001a7e5bd98"}, + {file = "aiohttp-3.10.7-cp38-cp38-win32.whl", hash = "sha256:81d3fc1b187656b6b465ed4ed4c9858f16ff2d9864da6225d80b8018abd7739b"}, + {file = "aiohttp-3.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:b6fb89edeadfd69df75f8cea97c3533805a9960cc56034ad296abe9b18771842"}, + {file = "aiohttp-3.10.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:318824b98a2bdf84e9a21d413737a3c4f27bbad0a9ce16141488f631dbffb9b2"}, + {file = "aiohttp-3.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:63c9de949e05a5f729aecba6bf4b3d5403846caf546ea5020f8b9bf315bd8f12"}, + {file = "aiohttp-3.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0245e1a71f3503b01d2c304529779a70277ccc0fe9847b48d437363de6e4336e"}, + {file = "aiohttp-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14dbfb208ffe3388e0770fd23bf9114cc933c10bb1dba35b538f3c9d685334d8"}, + {file = "aiohttp-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f6b014f2176d2774b759b8e2951af4a613385ebcc08841cb5c0ca6d5dee74ee"}, + {file = "aiohttp-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fcfabf9338fed009fd9e11bf496a927ea67b1ce15d34847cb0a98aa6f042b989"}, + {file = "aiohttp-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:171f1f5364a0ef5873480e6fddc3870ee37f1dfe216fa67507bbd4c91306f110"}, + {file = "aiohttp-3.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87e243b1df27ff685ab08228b7a938c0530beb60ad3dea7554da1554d46c9ad4"}, + {file = "aiohttp-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fee4d2246b091b7e252cd5bcdbd4362fa21c3cc6a445fef54de793731546ab24"}, + {file = "aiohttp-3.10.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bfa8c8af8c92e3d6c1eff02cf5127f62c1e7564e7b0f1a9767035f81a2e6bb20"}, + {file = "aiohttp-3.10.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:f44f09b67a458400215d9efedb9cfb5e3256dbeb2cc2da68e4592b7b36bac0c9"}, + {file = "aiohttp-3.10.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b5f8270946777d6971c27479cb6e7f54578be960928a8922cb59130e856d8484"}, + {file = "aiohttp-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e8ccaa99871303323bd2cda120043039729497642da5c6f53e066b19f73d9df8"}, + {file = "aiohttp-3.10.7-cp39-cp39-win32.whl", hash = "sha256:ce7c12bfbb1579e81cdf2e7db4338f8c768da2493aa0db60a858a542d551563c"}, + {file = "aiohttp-3.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:189979c7e9d8f40236534760daf5b41d2026d5ebabdf913e771d9b6bfbc992af"}, + {file = "aiohttp-3.10.7.tar.gz", hash = "sha256:18c72a69ba20713f26fa40932cac17437b0c1d25edff2e27437a204c12275bd9"}, ] [package.dependencies] @@ -133,7 +133,7 @@ async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" -yarl = ">=1.0,<2.0" +yarl = ">=1.12.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] @@ -621,13 +621,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prompt-toolkit" -version = "3.0.47" +version = "3.0.48" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, - {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, + {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, + {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, ] [package.dependencies] @@ -1061,103 +1061,103 @@ files = [ [[package]] name = "yarl" -version = "1.11.1" +version = "1.13.1" description = "Yet another URL library" optional = false python-versions = ">=3.8" files = [ - {file = "yarl-1.11.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:400cd42185f92de559d29eeb529e71d80dfbd2f45c36844914a4a34297ca6f00"}, - {file = "yarl-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8258c86f47e080a258993eed877d579c71da7bda26af86ce6c2d2d072c11320d"}, - {file = "yarl-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2164cd9725092761fed26f299e3f276bb4b537ca58e6ff6b252eae9631b5c96e"}, - {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08ea567c16f140af8ddc7cb58e27e9138a1386e3e6e53982abaa6f2377b38cc"}, - {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:768ecc550096b028754ea28bf90fde071c379c62c43afa574edc6f33ee5daaec"}, - {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2909fa3a7d249ef64eeb2faa04b7957e34fefb6ec9966506312349ed8a7e77bf"}, - {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01a8697ec24f17c349c4f655763c4db70eebc56a5f82995e5e26e837c6eb0e49"}, - {file = "yarl-1.11.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e286580b6511aac7c3268a78cdb861ec739d3e5a2a53b4809faef6b49778eaff"}, - {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4179522dc0305c3fc9782549175c8e8849252fefeb077c92a73889ccbcd508ad"}, - {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:27fcb271a41b746bd0e2a92182df507e1c204759f460ff784ca614e12dd85145"}, - {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f61db3b7e870914dbd9434b560075e0366771eecbe6d2b5561f5bc7485f39efd"}, - {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:c92261eb2ad367629dc437536463dc934030c9e7caca861cc51990fe6c565f26"}, - {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d95b52fbef190ca87d8c42f49e314eace4fc52070f3dfa5f87a6594b0c1c6e46"}, - {file = "yarl-1.11.1-cp310-cp310-win32.whl", hash = "sha256:489fa8bde4f1244ad6c5f6d11bb33e09cf0d1d0367edb197619c3e3fc06f3d91"}, - {file = "yarl-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:476e20c433b356e16e9a141449f25161e6b69984fb4cdbd7cd4bd54c17844998"}, - {file = "yarl-1.11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:946eedc12895873891aaceb39bceb484b4977f70373e0122da483f6c38faaa68"}, - {file = "yarl-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21a7c12321436b066c11ec19c7e3cb9aec18884fe0d5b25d03d756a9e654edfe"}, - {file = "yarl-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c35f493b867912f6fda721a59cc7c4766d382040bdf1ddaeeaa7fa4d072f4675"}, - {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25861303e0be76b60fddc1250ec5986c42f0a5c0c50ff57cc30b1be199c00e63"}, - {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4b53f73077e839b3f89c992223f15b1d2ab314bdbdf502afdc7bb18e95eae27"}, - {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:327c724b01b8641a1bf1ab3b232fb638706e50f76c0b5bf16051ab65c868fac5"}, - {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4307d9a3417eea87715c9736d050c83e8c1904e9b7aada6ce61b46361b733d92"}, - {file = "yarl-1.11.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48a28bed68ab8fb7e380775f0029a079f08a17799cb3387a65d14ace16c12e2b"}, - {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:067b961853c8e62725ff2893226fef3d0da060656a9827f3f520fb1d19b2b68a"}, - {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8215f6f21394d1f46e222abeb06316e77ef328d628f593502d8fc2a9117bde83"}, - {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:498442e3af2a860a663baa14fbf23fb04b0dd758039c0e7c8f91cb9279799bff"}, - {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:69721b8effdb588cb055cc22f7c5105ca6fdaa5aeb3ea09021d517882c4a904c"}, - {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e969fa4c1e0b1a391f3fcbcb9ec31e84440253325b534519be0d28f4b6b533e"}, - {file = "yarl-1.11.1-cp311-cp311-win32.whl", hash = "sha256:7d51324a04fc4b0e097ff8a153e9276c2593106a811704025bbc1d6916f45ca6"}, - {file = "yarl-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:15061ce6584ece023457fb8b7a7a69ec40bf7114d781a8c4f5dcd68e28b5c53b"}, - {file = "yarl-1.11.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a4264515f9117be204935cd230fb2a052dd3792789cc94c101c535d349b3dab0"}, - {file = "yarl-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f41fa79114a1d2eddb5eea7b912d6160508f57440bd302ce96eaa384914cd265"}, - {file = "yarl-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:02da8759b47d964f9173c8675710720b468aa1c1693be0c9c64abb9d8d9a4867"}, - {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9361628f28f48dcf8b2f528420d4d68102f593f9c2e592bfc842f5fb337e44fd"}, - {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b91044952da03b6f95fdba398d7993dd983b64d3c31c358a4c89e3c19b6f7aef"}, - {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74db2ef03b442276d25951749a803ddb6e270d02dda1d1c556f6ae595a0d76a8"}, - {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e975a2211952a8a083d1b9d9ba26472981ae338e720b419eb50535de3c02870"}, - {file = "yarl-1.11.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aef97ba1dd2138112890ef848e17d8526fe80b21f743b4ee65947ea184f07a2"}, - {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7915ea49b0c113641dc4d9338efa9bd66b6a9a485ffe75b9907e8573ca94b84"}, - {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:504cf0d4c5e4579a51261d6091267f9fd997ef58558c4ffa7a3e1460bd2336fa"}, - {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3de5292f9f0ee285e6bd168b2a77b2a00d74cbcfa420ed078456d3023d2f6dff"}, - {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a34e1e30f1774fa35d37202bbeae62423e9a79d78d0874e5556a593479fdf239"}, - {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66b63c504d2ca43bf7221a1f72fbe981ff56ecb39004c70a94485d13e37ebf45"}, - {file = "yarl-1.11.1-cp312-cp312-win32.whl", hash = "sha256:a28b70c9e2213de425d9cba5ab2e7f7a1c8ca23a99c4b5159bf77b9c31251447"}, - {file = "yarl-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:17b5a386d0d36fb828e2fb3ef08c8829c1ebf977eef88e5367d1c8c94b454639"}, - {file = "yarl-1.11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1fa2e7a406fbd45b61b4433e3aa254a2c3e14c4b3186f6e952d08a730807fa0c"}, - {file = "yarl-1.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:750f656832d7d3cb0c76be137ee79405cc17e792f31e0a01eee390e383b2936e"}, - {file = "yarl-1.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b8486f322d8f6a38539136a22c55f94d269addb24db5cb6f61adc61eabc9d93"}, - {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fce4da3703ee6048ad4138fe74619c50874afe98b1ad87b2698ef95bf92c96d"}, - {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed653638ef669e0efc6fe2acb792275cb419bf9cb5c5049399f3556995f23c7"}, - {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18ac56c9dd70941ecad42b5a906820824ca72ff84ad6fa18db33c2537ae2e089"}, - {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:688654f8507464745ab563b041d1fb7dab5d9912ca6b06e61d1c4708366832f5"}, - {file = "yarl-1.11.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4973eac1e2ff63cf187073cd4e1f1148dcd119314ab79b88e1b3fad74a18c9d5"}, - {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:964a428132227edff96d6f3cf261573cb0f1a60c9a764ce28cda9525f18f7786"}, - {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6d23754b9939cbab02c63434776df1170e43b09c6a517585c7ce2b3d449b7318"}, - {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c2dc4250fe94d8cd864d66018f8344d4af50e3758e9d725e94fecfa27588ff82"}, - {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09696438cb43ea6f9492ef237761b043f9179f455f405279e609f2bc9100212a"}, - {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:999bfee0a5b7385a0af5ffb606393509cfde70ecca4f01c36985be6d33e336da"}, - {file = "yarl-1.11.1-cp313-cp313-win32.whl", hash = "sha256:ce928c9c6409c79e10f39604a7e214b3cb69552952fbda8d836c052832e6a979"}, - {file = "yarl-1.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:501c503eed2bb306638ccb60c174f856cc3246c861829ff40eaa80e2f0330367"}, - {file = "yarl-1.11.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dae7bd0daeb33aa3e79e72877d3d51052e8b19c9025ecf0374f542ea8ec120e4"}, - {file = "yarl-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3ff6b1617aa39279fe18a76c8d165469c48b159931d9b48239065767ee455b2b"}, - {file = "yarl-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3257978c870728a52dcce8c2902bf01f6c53b65094b457bf87b2644ee6238ddc"}, - {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f351fa31234699d6084ff98283cb1e852270fe9e250a3b3bf7804eb493bd937"}, - {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8aef1b64da41d18026632d99a06b3fefe1d08e85dd81d849fa7c96301ed22f1b"}, - {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7175a87ab8f7fbde37160a15e58e138ba3b2b0e05492d7351314a250d61b1591"}, - {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba444bdd4caa2a94456ef67a2f383710928820dd0117aae6650a4d17029fa25e"}, - {file = "yarl-1.11.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ea9682124fc062e3d931c6911934a678cb28453f957ddccf51f568c2f2b5e05"}, - {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8418c053aeb236b20b0ab8fa6bacfc2feaaf7d4683dd96528610989c99723d5f"}, - {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:61a5f2c14d0a1adfdd82258f756b23a550c13ba4c86c84106be4c111a3a4e413"}, - {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f3a6d90cab0bdf07df8f176eae3a07127daafcf7457b997b2bf46776da2c7eb7"}, - {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:077da604852be488c9a05a524068cdae1e972b7dc02438161c32420fb4ec5e14"}, - {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:15439f3c5c72686b6c3ff235279630d08936ace67d0fe5c8d5bbc3ef06f5a420"}, - {file = "yarl-1.11.1-cp38-cp38-win32.whl", hash = "sha256:238a21849dd7554cb4d25a14ffbfa0ef380bb7ba201f45b144a14454a72ffa5a"}, - {file = "yarl-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:67459cf8cf31da0e2cbdb4b040507e535d25cfbb1604ca76396a3a66b8ba37a6"}, - {file = "yarl-1.11.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:884eab2ce97cbaf89f264372eae58388862c33c4f551c15680dd80f53c89a269"}, - {file = "yarl-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a336eaa7ee7e87cdece3cedb395c9657d227bfceb6781295cf56abcd3386a26"}, - {file = "yarl-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87f020d010ba80a247c4abc335fc13421037800ca20b42af5ae40e5fd75e7909"}, - {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:637c7ddb585a62d4469f843dac221f23eec3cbad31693b23abbc2c366ad41ff4"}, - {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48dfd117ab93f0129084577a07287376cc69c08138694396f305636e229caa1a"}, - {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e0ae31fb5ccab6eda09ba1494e87eb226dcbd2372dae96b87800e1dcc98804"}, - {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f46f81501160c28d0c0b7333b4f7be8983dbbc161983b6fb814024d1b4952f79"}, - {file = "yarl-1.11.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04293941646647b3bfb1719d1d11ff1028e9c30199509a844da3c0f5919dc520"}, - {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:250e888fa62d73e721f3041e3a9abf427788a1934b426b45e1b92f62c1f68366"}, - {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e8f63904df26d1a66aabc141bfd258bf738b9bc7bc6bdef22713b4f5ef789a4c"}, - {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:aac44097d838dda26526cffb63bdd8737a2dbdf5f2c68efb72ad83aec6673c7e"}, - {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:267b24f891e74eccbdff42241c5fb4f974de2d6271dcc7d7e0c9ae1079a560d9"}, - {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6907daa4b9d7a688063ed098c472f96e8181733c525e03e866fb5db480a424df"}, - {file = "yarl-1.11.1-cp39-cp39-win32.whl", hash = "sha256:14438dfc5015661f75f85bc5adad0743678eefee266ff0c9a8e32969d5d69f74"}, - {file = "yarl-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:94d0caaa912bfcdc702a4204cd5e2bb01eb917fc4f5ea2315aa23962549561b0"}, - {file = "yarl-1.11.1-py3-none-any.whl", hash = "sha256:72bf26f66456baa0584eff63e44545c9f0eaed9b73cb6601b647c91f14c11f38"}, - {file = "yarl-1.11.1.tar.gz", hash = "sha256:1bb2d9e212fb7449b8fb73bc461b51eaa17cc8430b4a87d87be7b25052d92f53"}, + {file = "yarl-1.13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:82e692fb325013a18a5b73a4fed5a1edaa7c58144dc67ad9ef3d604eccd451ad"}, + {file = "yarl-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df4e82e68f43a07735ae70a2d84c0353e58e20add20ec0af611f32cd5ba43fb4"}, + {file = "yarl-1.13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec9dd328016d8d25702a24ee274932aebf6be9787ed1c28d021945d264235b3c"}, + {file = "yarl-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5820bd4178e6a639b3ef1db8b18500a82ceab6d8b89309e121a6859f56585b05"}, + {file = "yarl-1.13.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86c438ce920e089c8c2388c7dcc8ab30dfe13c09b8af3d306bcabb46a053d6f7"}, + {file = "yarl-1.13.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3de86547c820e4f4da4606d1c8ab5765dd633189791f15247706a2eeabc783ae"}, + {file = "yarl-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca53632007c69ddcdefe1e8cbc3920dd88825e618153795b57e6ebcc92e752a"}, + {file = "yarl-1.13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4ee1d240b84e2f213565f0ec08caef27a0e657d4c42859809155cf3a29d1735"}, + {file = "yarl-1.13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c49f3e379177f4477f929097f7ed4b0622a586b0aa40c07ac8c0f8e40659a1ac"}, + {file = "yarl-1.13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5c5e32fef09ce101fe14acd0f498232b5710effe13abac14cd95de9c274e689e"}, + {file = "yarl-1.13.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab9524e45ee809a083338a749af3b53cc7efec458c3ad084361c1dbf7aaf82a2"}, + {file = "yarl-1.13.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:b1481c048fe787f65e34cb06f7d6824376d5d99f1231eae4778bbe5c3831076d"}, + {file = "yarl-1.13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:31497aefd68036d8e31bfbacef915826ca2e741dbb97a8d6c7eac66deda3b606"}, + {file = "yarl-1.13.1-cp310-cp310-win32.whl", hash = "sha256:1fa56f34b2236f5192cb5fceba7bbb09620e5337e0b6dfe2ea0ddbd19dd5b154"}, + {file = "yarl-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:1bbb418f46c7f7355084833051701b2301092e4611d9e392360c3ba2e3e69f88"}, + {file = "yarl-1.13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:216a6785f296169ed52cd7dcdc2612f82c20f8c9634bf7446327f50398732a51"}, + {file = "yarl-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40c6e73c03a6befb85b72da213638b8aaa80fe4136ec8691560cf98b11b8ae6e"}, + {file = "yarl-1.13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2430cf996113abe5aee387d39ee19529327205cda975d2b82c0e7e96e5fdabdc"}, + {file = "yarl-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fb4134cc6e005b99fa29dbc86f1ea0a298440ab6b07c6b3ee09232a3b48f495"}, + {file = "yarl-1.13.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:309c104ecf67626c033845b860d31594a41343766a46fa58c3309c538a1e22b2"}, + {file = "yarl-1.13.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f90575e9fe3aae2c1e686393a9689c724cd00045275407f71771ae5d690ccf38"}, + {file = "yarl-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d2e1626be8712333a9f71270366f4a132f476ffbe83b689dd6dc0d114796c74"}, + {file = "yarl-1.13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b66c87da3c6da8f8e8b648878903ca54589038a0b1e08dde2c86d9cd92d4ac9"}, + {file = "yarl-1.13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cf1ad338620249f8dd6d4b6a91a69d1f265387df3697ad5dc996305cf6c26fb2"}, + {file = "yarl-1.13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9915300fe5a0aa663c01363db37e4ae8e7c15996ebe2c6cce995e7033ff6457f"}, + {file = "yarl-1.13.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:703b0f584fcf157ef87816a3c0ff868e8c9f3c370009a8b23b56255885528f10"}, + {file = "yarl-1.13.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1d8e3ca29f643dd121f264a7c89f329f0fcb2e4461833f02de6e39fef80f89da"}, + {file = "yarl-1.13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7055bbade838d68af73aea13f8c86588e4bcc00c2235b4b6d6edb0dbd174e246"}, + {file = "yarl-1.13.1-cp311-cp311-win32.whl", hash = "sha256:a3442c31c11088e462d44a644a454d48110f0588de830921fd201060ff19612a"}, + {file = "yarl-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:81bad32c8f8b5897c909bf3468bf601f1b855d12f53b6af0271963ee67fff0d2"}, + {file = "yarl-1.13.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f452cc1436151387d3d50533523291d5f77c6bc7913c116eb985304abdbd9ec9"}, + {file = "yarl-1.13.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9cec42a20eae8bebf81e9ce23fb0d0c729fc54cf00643eb251ce7c0215ad49fe"}, + {file = "yarl-1.13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d959fe96e5c2712c1876d69af0507d98f0b0e8d81bee14cfb3f6737470205419"}, + {file = "yarl-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8c837ab90c455f3ea8e68bee143472ee87828bff19ba19776e16ff961425b57"}, + {file = "yarl-1.13.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94a993f976cdcb2dc1b855d8b89b792893220db8862d1a619efa7451817c836b"}, + {file = "yarl-1.13.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b2442a415a5f4c55ced0fade7b72123210d579f7d950e0b5527fc598866e62c"}, + {file = "yarl-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fdbf0418489525231723cdb6c79e7738b3cbacbaed2b750cb033e4ea208f220"}, + {file = "yarl-1.13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b7f6e699304717fdc265a7e1922561b02a93ceffdaefdc877acaf9b9f3080b8"}, + {file = "yarl-1.13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bcd5bf4132e6a8d3eb54b8d56885f3d3a38ecd7ecae8426ecf7d9673b270de43"}, + {file = "yarl-1.13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2a93a4557f7fc74a38ca5a404abb443a242217b91cd0c4840b1ebedaad8919d4"}, + {file = "yarl-1.13.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:22b739f99c7e4787922903f27a892744189482125cc7b95b747f04dd5c83aa9f"}, + {file = "yarl-1.13.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2db874dd1d22d4c2c657807562411ffdfabec38ce4c5ce48b4c654be552759dc"}, + {file = "yarl-1.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4feaaa4742517eaceafcbe74595ed335a494c84634d33961214b278126ec1485"}, + {file = "yarl-1.13.1-cp312-cp312-win32.whl", hash = "sha256:bbf9c2a589be7414ac4a534d54e4517d03f1cbb142c0041191b729c2fa23f320"}, + {file = "yarl-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:d07b52c8c450f9366c34aa205754355e933922c79135125541daae6cbf31c799"}, + {file = "yarl-1.13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:95c6737f28069153c399d875317f226bbdea939fd48a6349a3b03da6829fb550"}, + {file = "yarl-1.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cd66152561632ed4b2a9192e7f8e5a1d41e28f58120b4761622e0355f0fe034c"}, + {file = "yarl-1.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6a2acde25be0cf9be23a8f6cbd31734536a264723fca860af3ae5e89d771cd71"}, + {file = "yarl-1.13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a18595e6a2ee0826bf7dfdee823b6ab55c9b70e8f80f8b77c37e694288f5de1"}, + {file = "yarl-1.13.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a31d21089894942f7d9a8df166b495101b7258ff11ae0abec58e32daf8088813"}, + {file = "yarl-1.13.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45f209fb4bbfe8630e3d2e2052535ca5b53d4ce2d2026bed4d0637b0416830da"}, + {file = "yarl-1.13.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f722f30366474a99745533cc4015b1781ee54b08de73260b2bbe13316079851"}, + {file = "yarl-1.13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3bf60444269345d712838bb11cc4eadaf51ff1a364ae39ce87a5ca8ad3bb2c8"}, + {file = "yarl-1.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:942c80a832a79c3707cca46bd12ab8aa58fddb34b1626d42b05aa8f0bcefc206"}, + {file = "yarl-1.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:44b07e1690f010c3c01d353b5790ec73b2f59b4eae5b0000593199766b3f7a5c"}, + {file = "yarl-1.13.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:396e59b8de7e4d59ff5507fb4322d2329865b909f29a7ed7ca37e63ade7f835c"}, + {file = "yarl-1.13.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3bb83a0f12701c0b91112a11148b5217617982e1e466069d0555be9b372f2734"}, + {file = "yarl-1.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c92b89bffc660f1274779cb6fbb290ec1f90d6dfe14492523a0667f10170de26"}, + {file = "yarl-1.13.1-cp313-cp313-win32.whl", hash = "sha256:269c201bbc01d2cbba5b86997a1e0f73ba5e2f471cfa6e226bcaa7fd664b598d"}, + {file = "yarl-1.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:1d0828e17fa701b557c6eaed5edbd9098eb62d8838344486248489ff233998b8"}, + {file = "yarl-1.13.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8be8cdfe20787e6a5fcbd010f8066227e2bb9058331a4eccddec6c0db2bb85b2"}, + {file = "yarl-1.13.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08d7148ff11cb8e886d86dadbfd2e466a76d5dd38c7ea8ebd9b0e07946e76e4b"}, + {file = "yarl-1.13.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4afdf84610ca44dcffe8b6c22c68f309aff96be55f5ea2fa31c0c225d6b83e23"}, + {file = "yarl-1.13.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0d12fe78dcf60efa205e9a63f395b5d343e801cf31e5e1dda0d2c1fb618073d"}, + {file = "yarl-1.13.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298c1eecfd3257aa16c0cb0bdffb54411e3e831351cd69e6b0739be16b1bdaa8"}, + {file = "yarl-1.13.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c14c16831b565707149c742d87a6203eb5597f4329278446d5c0ae7a1a43928e"}, + {file = "yarl-1.13.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a9bacedbb99685a75ad033fd4de37129449e69808e50e08034034c0bf063f99"}, + {file = "yarl-1.13.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:658e8449b84b92a4373f99305de042b6bd0d19bf2080c093881e0516557474a5"}, + {file = "yarl-1.13.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:373f16f38721c680316a6a00ae21cc178e3a8ef43c0227f88356a24c5193abd6"}, + {file = "yarl-1.13.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:45d23c4668d4925688e2ea251b53f36a498e9ea860913ce43b52d9605d3d8177"}, + {file = "yarl-1.13.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f7917697bcaa3bc3e83db91aa3a0e448bf5cde43c84b7fc1ae2427d2417c0224"}, + {file = "yarl-1.13.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5989a38ba1281e43e4663931a53fbf356f78a0325251fd6af09dd03b1d676a09"}, + {file = "yarl-1.13.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:11b3ca8b42a024513adce810385fcabdd682772411d95bbbda3b9ed1a4257644"}, + {file = "yarl-1.13.1-cp38-cp38-win32.whl", hash = "sha256:dcaef817e13eafa547cdfdc5284fe77970b891f731266545aae08d6cce52161e"}, + {file = "yarl-1.13.1-cp38-cp38-win_amd64.whl", hash = "sha256:7addd26594e588503bdef03908fc207206adac5bd90b6d4bc3e3cf33a829f57d"}, + {file = "yarl-1.13.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a0ae6637b173d0c40b9c1462e12a7a2000a71a3258fa88756a34c7d38926911c"}, + {file = "yarl-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:576365c9f7469e1f6124d67b001639b77113cfd05e85ce0310f5f318fd02fe85"}, + {file = "yarl-1.13.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:78f271722423b2d4851cf1f4fa1a1c4833a128d020062721ba35e1a87154a049"}, + {file = "yarl-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d74f3c335cfe9c21ea78988e67f18eb9822f5d31f88b41aec3a1ec5ecd32da5"}, + {file = "yarl-1.13.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1891d69a6ba16e89473909665cd355d783a8a31bc84720902c5911dbb6373465"}, + {file = "yarl-1.13.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb382fd7b4377363cc9f13ba7c819c3c78ed97c36a82f16f3f92f108c787cbbf"}, + {file = "yarl-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c8854b9f80693d20cec797d8e48a848c2fb273eb6f2587b57763ccba3f3bd4b"}, + {file = "yarl-1.13.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbf2c3f04ff50f16404ce70f822cdc59760e5e2d7965905f0e700270feb2bbfc"}, + {file = "yarl-1.13.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fb9f59f3848edf186a76446eb8bcf4c900fe147cb756fbbd730ef43b2e67c6a7"}, + {file = "yarl-1.13.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ef9b85fa1bc91c4db24407e7c4da93a5822a73dd4513d67b454ca7064e8dc6a3"}, + {file = "yarl-1.13.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:098b870c18f1341786f290b4d699504e18f1cd050ed179af8123fd8232513424"}, + {file = "yarl-1.13.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:8c723c91c94a3bc8033dd2696a0f53e5d5f8496186013167bddc3fb5d9df46a3"}, + {file = "yarl-1.13.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:44a4c40a6f84e4d5955b63462a0e2a988f8982fba245cf885ce3be7618f6aa7d"}, + {file = "yarl-1.13.1-cp39-cp39-win32.whl", hash = "sha256:84bbcdcf393139f0abc9f642bf03f00cac31010f3034faa03224a9ef0bb74323"}, + {file = "yarl-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:fc2931ac9ce9c61c9968989ec831d3a5e6fcaaff9474e7cfa8de80b7aff5a093"}, + {file = "yarl-1.13.1-py3-none-any.whl", hash = "sha256:6a5185ad722ab4dd52d5fb1f30dcc73282eb1ed494906a92d1a228d3f89607b0"}, + {file = "yarl-1.13.1.tar.gz", hash = "sha256:ec8cfe2295f3e5e44c51f57272afbd69414ae629ec7c6b27f5a410efc78b70a0"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 9e098c9..6c54aac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "OpenFreebuds" -version = "0.1.0" +version = "0.14.0" description = "FOSS Windows/Linux client for HUAWEI FreeBuds headset series" authors = ["MelianMiko "] packages = [ diff --git a/scripts/build_debian/Makefile b/scripts/build_debian/Makefile index 8e6bcf3..ee2dc6b 100644 --- a/scripts/build_debian/Makefile +++ b/scripts/build_debian/Makefile @@ -12,6 +12,7 @@ install: pip install --upgrade --no-dependencies --target="${DESTDIR}${DIST_PACKAGES_PATH}" ${WHEEL_FILE} mkdir -p ${DESTDIR}/usr/bin mv ${DESTDIR}${DIST_PACKAGES_PATH}/bin/* ${DESTDIR}/usr/bin/ + ln -s ${DESTDIR}/usr/bin/openfreebuds_qt ${DESTDIR}/usr/bin/openfreebuds sed -i '1 s/^.*$$/\#\!\/usr\/bin\/env python3/' ${DESTDIR}/usr/bin/* rm -rf ${DESTDIR}${DIST_PACKAGES_PATH}/bin mkdir -p ${DESTDIR}/usr/share/icons/hicolor/256x256/apps diff --git a/scripts/build_debian/build.sh b/scripts/build_debian/build.sh index c4c6dc5..55a24bf 100755 --- a/scripts/build_debian/build.sh +++ b/scripts/build_debian/build.sh @@ -2,6 +2,7 @@ cd "$(dirname "$0")" +rm ../../dist/* rm openfreebuds* make prepare diff --git a/scripts/build_debian/debian/changelog b/scripts/build_debian/debian/changelog index 338aa02..5e83263 100644 --- a/scripts/build_debian/debian/changelog +++ b/scripts/build_debian/debian/changelog @@ -1,3 +1,27 @@ +openfreebuds (0.14.0-1) bookworm noble; urgency=medium + + * [Core] Client-server architecture, close #14; + * Now multiple instances of OpenFreebuds could be launched, for multi-user usage for example; + * Built-in HTTP-server is now used as cross process communication protocol, so it can't be fully disabled, remote access is still disallowed out-of-box; + * If you need to launch multiple instances from single user, use -c CLI flag; + * [Core] Web-server authorization + * [Core] Rewritten (mostly from scratch) to asyncio ; + * [Core] Drop pybluez from dependencies, now will use predefined port numbers instead of SDP detection; + * [UI] Rewritten from scratch to asyncio and PyQT6, introduce redesigned Settings UI; + * [UI] Disable logging to CLI / `journalctl` if -v isn't present, close #29; + * [Device compatibility] Bug fixes for modern HUAWEI Devices (5i, Pro 2, Pro 3); + * [HUAWEI FreeBuds 5i & other] Better Dual-Connect configuration; + * [HUAWEI FreeBuds 5i & other] Add low-latency mode setting; + * [HUAWEI FreeBuds 5i & other] Add triple-tap settings; + * [HUAWEI FreeBuds 5i & other] Fix SQ preference switch; + * [Device compatibility] Add HUAWEI FreeLace Pro 2 compatibility; + * Custom equalizer preset configuration (should also work with Pro 3); + * [Linux] Flatpak as installation option + * [i18n] Add Spanish translation, thanks to @Pedro-vk (GitHub) + * [i18n] Add partial Portuguese (Brazilian), thanks to @Lobo (Accent) + + -- MelianMiko Sat, 28 Sep 2024 11:15:46 +0700 + openfreebuds (0.13.3-2) bookworm trixie jammy mantic noble; urgency=medium * Fix: Random crash when enumerating dual-connect devices diff --git a/scripts/build_debian/debian/control b/scripts/build_debian/debian/control index aba3b0c..3d6f564 100644 --- a/scripts/build_debian/debian/control +++ b/scripts/build_debian/debian/control @@ -3,17 +3,28 @@ Section: utils Priority: optional Maintainer: MelianMiko Build-Depends: debhelper-compat (= 12), - python3 (>= 3.11), python3-pip, pyqt6-dev-tools, - libcairo2-dev, gobject-introspection, libgirepository1.0-dev, - qt6-l10n-tools, make + python3 (>= 3.11), + python3-pip, + pyqt6-dev-tools, + libcairo2-dev, + gobject-introspection, + libgirepository1.0-dev, + qt6-l10n-tools, + make Standards-Version: 4.4.1 Homepage: https://github.com/melianmiko/OpenFreebuds Package: openfreebuds Architecture: all Depends: - ${misc:Depends}, python3 (>= 3.11), - python3-sdbus, python3-pyqt6, python3-pil, python3-qasync, python3-aiohttp + ${misc:Depends}, + python3 (>= 3.11), + python3-dbus-next, + python3-pyqt6, + python3-pil, + python3-qasync, + python3-aiohttp, + python3-psutil Description: Open-source client application for HUAWEI FreeBuds bluetooth headset series. . diff --git a/scripts/build_flatpak/pw.mmk.OpenFreebuds.metainfo.xml b/scripts/build_flatpak/pw.mmk.OpenFreebuds.metainfo.xml index 825f029..156cecb 100644 --- a/scripts/build_flatpak/pw.mmk.OpenFreebuds.metainfo.xml +++ b/scripts/build_flatpak/pw.mmk.OpenFreebuds.metainfo.xml @@ -24,8 +24,28 @@ This application allows to control HUAWEI FreeBuds earphone settings from PC. Check exact battery level, toggle noise cancellation, control built-in equalizer, change gestures, and all other in-device settings and features are now available without official mobile application.

- Features: - Dynamic system tray icon that shows current active noise cancellation mode and battery level; - Tray menu with battery levels and active noise cancellation settings; - Ability to change voice language (not all devices supported); - Device settings dialog, eg. change equalizer preset, gesture actions, etc; - Built-in HTTP-server for remote control & scripting; - Built-in global hotkeys support (for Windows and Xorg-Linux) + Features:

+
    +
  • + Dynamic system tray icon that shows current active noise cancellation mode and battery level; +
  • +
  • + Tray menu with battery levels and active noise cancellation settings; +
  • +
  • + Ability to change voice language (not all devices supported); +
  • +
  • + Device settings dialog, eg. change equalizer preset, gesture actions, etc; +
  • +
  • + Built-in HTTP-server for remote control & scripting; +
  • +
  • + Built-in global hotkeys support (XOrg only, for wayand see FAQ); +
  • +

Tested with following devices: HUAWEI FreeBuds 4i / 5i / Pro / Pro 2 / Pro 3 / SE, HUAWEI FreeLace Pro / Pro 2.

@@ -78,12 +98,29 @@ - + https://github.com/melianmiko/OpenFreebuds/blob/main/CHANGELOG.md#v0.14.0
    -
  • Application rewritter from scratch to Qt
  • -
  • Add HUAWEI FreeBuds Pro 2 compatibility
  • +
  • [Core] Client-server architecture, close #14;
  • +
  • Now multiple instances of OpenFreebuds could be launched, for multi-user usage for example;
  • +
  • Built-in HTTP-server is now used as cross process communication protocol, so it can't be fully disabled, remote access is still disallowed out-of-box;
  • +
  • If you need to launch multiple instances from single user, use -c CLI flag;
  • +
  • [Core] Web-server authorization
  • +
  • [Core] Rewritten (mostly from scratch) to asyncio ;
  • +
  • [Core] Drop pybluez from dependencies, now will use predefined port numbers instead of SDP detection;
  • +
  • [UI] Rewritten from scratch to asyncio and PyQT6, introduce redesigned Settings UI;
  • +
  • [UI] Disable logging to CLI / `journalctl` if -v isn't present, close #29;
  • +
  • [Device compatibility] Bug fixes for modern HUAWEI Devices (5i, Pro 2, Pro 3);
  • +
  • [HUAWEI FreeBuds 5i & other] Better Dual-Connect configuration;
  • +
  • [HUAWEI FreeBuds 5i & other] Add low-latency mode setting;
  • +
  • [HUAWEI FreeBuds 5i & other] Add triple-tap settings;
  • +
  • [HUAWEI FreeBuds 5i & other] Fix SQ preference switch;
  • +
  • [Device compatibility] Add HUAWEI FreeLace Pro 2 compatibility;
  • +
  • Custom equalizer preset configuration (should also work with Pro 3);
  • +
  • [Linux] Flatpak as installation option
  • +
  • [i18n] Add Spanish translation, thanks to @Pedro-vk (GitHub)
  • +
  • [i18n] Add partial Portuguese (Brazilian), thanks to @Lobo (Accent)
diff --git a/scripts/build_win32/openfreebuds.nsi b/scripts/build_win32/openfreebuds.nsi index b327ccc..fef9111 100644 --- a/scripts/build_win32/openfreebuds.nsi +++ b/scripts/build_win32/openfreebuds.nsi @@ -3,7 +3,7 @@ !include "FileFunc.nsh" !define APP_NAME "OpenFreebuds" -!define APP_VERSION "0.13.3" +!define APP_VERSION "0.14.0" !define APP_DEVELOPER "MelianMiko" !define APP_BUILD_NAME "openfreebuds" !define APP_EXE "openfreebuds.exe" diff --git a/scripts/bump_version.py b/scripts/bump_version.py index 9946416..958ce5c 100644 --- a/scripts/bump_version.py +++ b/scripts/bump_version.py @@ -7,7 +7,7 @@ from pathlib import Path from xml.sax.saxutils import escape -DEB_CODENAMES = "bookworm jammy mantic" +DEB_CODENAMES = "bookworm noble" DEVELOPER_SIGN = "MelianMiko " DEBUG = False @@ -81,7 +81,7 @@ def bump_nsis(line: str): def create_version_info(path: Path): - export_data = subprocess.getoutput("poetry export --without-hashes -n --with extras") + export_data = subprocess.getoutput("poetry export --without-hashes -n --with extras --with no_flatpak") libraries = [] for line in export_data.replace("\r", "").splitlines(): libraries.append(f" '{line}',") diff --git a/scripts/sync_translations.sh b/scripts/sync_translations.sh index 5d12ce7..73672db 100755 --- a/scripts/sync_translations.sh +++ b/scripts/sync_translations.sh @@ -26,12 +26,17 @@ do locale=`basename ${ts_file%.*}` if [ ./assets/i18n/$locale.po -nt ./assets/i18n/$locale.ts ] then - echo "--- Update $locale from PO-file" + echo "-- Update $locale from PO-file" lconvert ./assets/i18n/$locale.po -o ./assets/i18n/$locale.ts else # Create *.po-file for accent echo "-- Update $locale" lconvert ./assets/i18n/$locale.ts -o ./assets/i18n/$locale.po + + if [[ "$locale" == "en" ]] + then + python ../scripts/sync_translations_fill_msgstr.py ./assets/i18n/$locale.po + fi fi [[ "$locale" == "en" ]] || pylupdate6 --no-obsolete --ts $ts_file . diff --git a/scripts/sync_translations_fill_msgstr.py b/scripts/sync_translations_fill_msgstr.py new file mode 100644 index 0000000..acb9083 --- /dev/null +++ b/scripts/sync_translations_fill_msgstr.py @@ -0,0 +1,9 @@ +import sys +import polib + +po = polib.pofile(sys.argv[1]) +for entry in po: + if entry.msgstr == "": + entry.msgstr = entry.msgid + +po.save(sys.argv[1])