[improvement] Not breaking the application when a i18n (translation) key was not found

This commit is contained in:
Vinicius Moreira
2019-11-25 13:09:50 -03:00
parent 8c1bf684ed
commit b59cb347c4
25 changed files with 175 additions and 108 deletions

View File

@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.7.3]
### Improvements
- Not breaking the application when a i18n (translation) key was not found
## [0.7.2] 2019-11-01 ## [0.7.2] 2019-11-01
### Improvements ### Improvements
- Snap - Snap

View File

@@ -20,3 +20,11 @@ The way to go here is to ask yourself if the improvement would be useful for mor
* Explain why you think these changes could be useful * Explain why you think these changes could be useful
* If it fixes a bug, be sure to link to the issue itself. * If it fixes a bug, be sure to link to the issue itself.
* Follow the [PEP 8](https://www.python.org/dev/peps/pep-0008/) code style to keep the code consistent. * Follow the [PEP 8](https://www.python.org/dev/peps/pep-0008/) code style to keep the code consistent.
# Adding a new translation
* To add a new translation, you will have to create a file in each directory listed below named as the first two letters in the ISO format (e.g: for 'english' would be 'en'):
- **bauh/view/resources/locale**
- **bauh/gems/appimage/resources/locale**
- **bauh/gems/arch/resources/locale**
- **bauh/gems/flatpak/resources/locale**
- **bauh/gems/snap/resources/locale**

View File

@@ -5,6 +5,8 @@ It has a **tray mode** (see **Settings** below) that attaches the application ic
This project has an official Twitter account ( **@bauh4linux** ) so people can stay on top of its news. This project has an official Twitter account ( **@bauh4linux** ) so people can stay on top of its news.
To contribute with this project, have a look at [CONTRIBUTING.md](https://github.com/vinifmor/bauh/blob/master/CONTRIBUTING.md)
![management panel](https://raw.githubusercontent.com/vinifmor/bauh/master/pictures/panel.png) ![management panel](https://raw.githubusercontent.com/vinifmor/bauh/master/pictures/panel.png)
@@ -65,13 +67,13 @@ If you do not want to clone / download this repository, go to your **Home** fold
In order to autostart the application, use your Desktop Environment settings to register it as a startup application / script (**bauh --tray=1**). In order to autostart the application, use your Desktop Environment settings to register it as a startup application / script (**bauh --tray=1**).
### Gems ( package technology support ) ### Gems ( package technology support )
#### Flatpak ( flatpak gem ) #### Flatpak ( flatpak )
- The user is able to search, install, uninstall, downgrade, launch and retrieve the applications history - The user is able to search, install, uninstall, downgrade, launch and retrieve the applications history
#### Snap ( snap gem ) #### Snap ( snap )
- The user is able to search, install, uninstall, refresh, launch and downgrade applications - The user is able to search, install, uninstall, refresh, launch and downgrade applications
#### AUR ( arch gem ) #### AUR ( arch )
- It is **not enabled by default** - It is **not enabled by default**
- The user is able to search, install, uninstall, downgrade, launch and retrieve the packages history - The user is able to search, install, uninstall, downgrade, launch and retrieve the packages history
- It handles conflicts, and missing / optional packages installations ( including from your distro mirrors ) - It handles conflicts, and missing / optional packages installations ( including from your distro mirrors )
@@ -90,7 +92,7 @@ will be pre-downloaded faster ( it does **NOT** modify your **pacman** settings
- Arch package memory-indexer running every 20 minutes. This memory index is used when AUR Api cannot handle the amount of results found for a given search. It can be disabled via the environment variable **BAUH_ARCH_AUR_INDEX_UPDATER=0**. - Arch package memory-indexer running every 20 minutes. This memory index is used when AUR Api cannot handle the amount of results found for a given search. It can be disabled via the environment variable **BAUH_ARCH_AUR_INDEX_UPDATER=0**.
- If some of your installed packages are not categorized, send an e-mail to **bauh4linux@gmail.com** informing their names and categories in the following format: ```name=category1[,category2,category3,...]``` - If some of your installed packages are not categorized, send an e-mail to **bauh4linux@gmail.com** informing their names and categories in the following format: ```name=category1[,category2,category3,...]```
#### AppImage ( appimage gem ) #### AppImage ( appimage )
- The user is able to search, install, uninstall, downgrade, launch and retrieve the applications history - The user is able to search, install, uninstall, downgrade, launch and retrieve the applications history
- Supported sources: [AppImageHub](https://appimage.github.io) ( **applications with no releases published to GitHub are currently not available** ) - Supported sources: [AppImageHub](https://appimage.github.io) ( **applications with no releases published to GitHub are currently not available** )
- Faster downloads if **aria2c** is installed. Same behavior described in the **AUR support** section. - Faster downloads if **aria2c** is installed. Same behavior described in the **AUR support** section.

View File

@@ -1,4 +1,4 @@
__version__ = '0.7.2' __version__ = '0.7.3'
__app_name__ = 'bauh' __app_name__ = 'bauh'
import os import os

View File

@@ -1,16 +1,16 @@
import logging import logging
import platform
import sys import sys
from bauh.api.abstract.cache import MemoryCacheFactory from bauh.api.abstract.cache import MemoryCacheFactory
from bauh.api.abstract.disk import DiskCacheLoaderFactory from bauh.api.abstract.disk import DiskCacheLoaderFactory
from bauh.api.abstract.download import FileDownloader from bauh.api.abstract.download import FileDownloader
from bauh.api.http import HttpClient from bauh.api.http import HttpClient
from bauh.view.util.translation import I18n
class ApplicationContext: class ApplicationContext:
def __init__(self, disk_cache: bool, download_icons: bool, http_client: HttpClient, app_root_dir: str, i18n: dict, def __init__(self, disk_cache: bool, download_icons: bool, http_client: HttpClient, app_root_dir: str, i18n: I18n,
cache_factory: MemoryCacheFactory, disk_loader_factory: DiskCacheLoaderFactory, cache_factory: MemoryCacheFactory, disk_loader_factory: DiskCacheLoaderFactory,
logger: logging.Logger, file_downloader: FileDownloader, distro: str): logger: logging.Logger, file_downloader: FileDownloader, distro: str):
""" """
@@ -18,7 +18,7 @@ class ApplicationContext:
:param download_icons: if packages icons should be downloaded :param download_icons: if packages icons should be downloaded
:param http_client: a shared instance of http client :param http_client: a shared instance of http client
:param app_root_dir: GUI root dir :param app_root_dir: GUI root dir
:param i18n: the i18n dictionary keys :param i18n: the translation keys
:param cache_factory: :param cache_factory:
:param disk_loader_factory: :param disk_loader_factory:
:param logger: a logger instance :param logger: a logger instance

View File

@@ -12,9 +12,12 @@ from bauh.view.core.controller import GenericSoftwareManager
from bauh.view.core.downloader import AdaptableFileDownloader from bauh.view.core.downloader import AdaptableFileDownloader
from bauh.view.qt.systray import TrayIcon from bauh.view.qt.systray import TrayIcon
from bauh.view.qt.window import ManageWindow from bauh.view.qt.window import ManageWindow
from bauh.view.util import util, logs, resource from bauh.view.util import util, logs, resource, translation
from bauh.view.util.cache import DefaultMemoryCacheFactory, CacheCleaner from bauh.view.util.cache import DefaultMemoryCacheFactory, CacheCleaner
from bauh.view.util.disk import DefaultDiskCacheLoaderFactory from bauh.view.util.disk import DefaultDiskCacheLoaderFactory
from bauh.view.util.translation import I18n
DEFAULT_I18N_KEY = 'en'
def main(): def main():
@@ -25,7 +28,9 @@ def main():
logger = logs.new_logger(__app_name__, bool(args.logs)) logger = logs.new_logger(__app_name__, bool(args.logs))
app_args.validate(args, logger) app_args.validate(args, logger)
i18n_key, i18n = util.get_locale_keys(args.locale) i18n_key, current_i18n = translation.get_locale_keys(args.locale)
default_i18n = translation.get_locale_keys(DEFAULT_I18N_KEY)[1] if i18n_key != DEFAULT_I18N_KEY else {}
i18n = I18n(current_i18n, default_i18n)
cache_cleaner = CacheCleaner() cache_cleaner = CacheCleaner()
cache_factory = DefaultMemoryCacheFactory(expiration_time=args.cache_exp, cleaner=cache_cleaner) cache_factory = DefaultMemoryCacheFactory(expiration_time=args.cache_exp, cleaner=cache_cleaner)
@@ -57,7 +62,7 @@ def main():
if app.style().objectName().lower() not in {'fusion', 'breeze'}: if app.style().objectName().lower() not in {'fusion', 'breeze'}:
app.setStyle('Fusion') app.setStyle('Fusion')
managers = gems.load_managers(context=context, locale=i18n_key, config=user_config) managers = gems.load_managers(context=context, locale=i18n_key, config=user_config, default_locale=DEFAULT_I18N_KEY)
manager = GenericSoftwareManager(managers, context=context, app_args=args) manager = GenericSoftwareManager(managers, context=context, app_args=args)
manager.prepare() manager.prepare()

View File

@@ -2,11 +2,11 @@ from typing import Set
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.view import MultipleSelectComponent, InputOption from bauh.api.abstract.view import MultipleSelectComponent, InputOption
from bauh.commons.html import bold from bauh.commons.html import bold
from bauh.view.util.translation import I18n
def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatcher, i18n: dict) -> Set[str]: def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatcher, i18n: I18n) -> Set[str]:
opts = [InputOption('{}{} ( {} )'.format(p, ': ' + d['desc'] if d['desc'] else '', d['mirror'].upper()), p) for p, d in pkg_mirrors.items()] opts = [InputOption('{}{} ( {} )'.format(p, ': ' + d['desc'] if d['desc'] else '', d['mirror'].upper()), p) for p, d in pkg_mirrors.items()]
view_opts = MultipleSelectComponent(label='', view_opts = MultipleSelectComponent(label='',
options=opts, options=opts,
@@ -21,7 +21,7 @@ def request_optional_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatch
return {o.value for o in view_opts.values} return {o.value for o in view_opts.values}
def request_install_missing_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatcher, i18n: dict) -> bool: def request_install_missing_deps(pkgname: str, pkg_mirrors: dict, watcher: ProcessWatcher, i18n: I18n) -> bool:
deps_str = ''.join(['<br/><span style="font-weight:bold"> - {} ( {} )</span>'.format(d, m.upper()) for d, m in pkg_mirrors.items()]) deps_str = ''.join(['<br/><span style="font-weight:bold"> - {} ( {} )</span>'.format(d, m.upper()) for d, m in pkg_mirrors.items()])
msg = '<p>{}</p>'.format(i18n['arch.missing_deps.body'].format(bold(pkgname)) + ':<br/>' + deps_str) msg = '<p>{}</p>'.format(i18n['arch.missing_deps.body'].format(bold(pkgname)) + ':<br/>' + deps_str)
msg += i18n['ask.continue'] msg += i18n['ask.continue']

View File

@@ -1,21 +1,22 @@
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.view import MessageType from bauh.api.abstract.view import MessageType
from bauh.commons.html import bold from bauh.commons.html import bold
from bauh.view.util.translation import I18n
def show_dep_not_installed(watcher: ProcessWatcher, pkgname: str, depname: str, i18n: dict): def show_dep_not_installed(watcher: ProcessWatcher, pkgname: str, depname: str, i18n: I18n):
watcher.show_message(title=i18n['error'], watcher.show_message(title=i18n['error'],
body=i18n['arch.install.dependency.install.error'].format(bold(depname), bold(pkgname)), body=i18n['arch.install.dependency.install.error'].format(bold(depname), bold(pkgname)),
type_=MessageType.ERROR) type_=MessageType.ERROR)
def show_dep_not_found(depname: str, i18n: dict, watcher: ProcessWatcher): def show_dep_not_found(depname: str, i18n: I18n, watcher: ProcessWatcher):
watcher.show_message(title=i18n['arch.install.dep_not_found.title'], watcher.show_message(title=i18n['arch.install.dep_not_found.title'],
body=i18n['arch.install.dep_not_found.body'].format(bold(depname)), body=i18n['arch.install.dep_not_found.body'].format(bold(depname)),
type_=MessageType.ERROR) type_=MessageType.ERROR)
def show_optdep_not_installed(depname: str, watcher: ProcessWatcher, i18n: dict): def show_optdep_not_installed(depname: str, watcher: ProcessWatcher, i18n: I18n):
watcher.show_message(title=i18n['error'], watcher.show_message(title=i18n['error'],
body=i18n['arch.install.optdep.error'].format(bold(depname)), body=i18n['arch.install.optdep.error'].format(bold(depname)),
type_=MessageType.ERROR) type_=MessageType.ERROR)

View File

@@ -8,11 +8,12 @@ from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.http import HttpClient from bauh.api.http import HttpClient
from bauh.commons.html import bold from bauh.commons.html import bold
from bauh.commons.system import run_cmd, new_subprocess, ProcessHandler, SystemProcess, SimpleProcess from bauh.commons.system import run_cmd, new_subprocess, ProcessHandler, SystemProcess, SimpleProcess
from bauh.view.util.translation import I18n
class AdaptableFileDownloader(FileDownloader): class AdaptableFileDownloader(FileDownloader):
def __init__(self, logger: logging.Logger, multithread_enabled: bool, i18n: dict, http_client: HttpClient): def __init__(self, logger: logging.Logger, multithread_enabled: bool, i18n: I18n, http_client: HttpClient):
self.logger = logger self.logger = logger
self.multithread_enabled = multithread_enabled self.multithread_enabled = multithread_enabled
self.i18n = i18n self.i18n = i18n

View File

@@ -6,7 +6,7 @@ from typing import List
from bauh import ROOT_DIR from bauh import ROOT_DIR
from bauh.api.abstract.controller import SoftwareManager, ApplicationContext from bauh.api.abstract.controller import SoftwareManager, ApplicationContext
from bauh.view.core.config import Configuration from bauh.view.core.config import Configuration
from bauh.view.util import util from bauh.view.util import util, translation
def find_manager(member): def find_manager(member):
@@ -20,7 +20,7 @@ def find_manager(member):
return manager_found return manager_found
def load_managers(locale: str, context: ApplicationContext, config: Configuration) -> List[SoftwareManager]: def load_managers(locale: str, context: ApplicationContext, config: Configuration, default_locale: str) -> List[SoftwareManager]:
managers = [] managers = []
for f in os.scandir(ROOT_DIR + '/gems'): for f in os.scandir(ROOT_DIR + '/gems'):
@@ -37,7 +37,10 @@ def load_managers(locale: str, context: ApplicationContext, config: Configuratio
locale_path = '{}/resources/locale'.format(f.path) locale_path = '{}/resources/locale'.format(f.path)
if os.path.exists(locale_path): if os.path.exists(locale_path):
context.i18n.update(util.get_locale_keys(locale, locale_path)[1]) context.i18n.current.update(translation.get_locale_keys(locale, locale_path)[1])
if default_locale and context.i18n.default:
context.i18n.default.update(translation.get_locale_keys(default_locale, locale_path)[1])
man = manager_class(context=context) man = manager_class(context=context)

View File

@@ -1,11 +1,12 @@
from glob import glob from glob import glob
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QIcon from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QVBoxLayout, QDialog, QLabel, QWidget, QHBoxLayout from PyQt5.QtWidgets import QVBoxLayout, QDialog, QLabel, QWidget, QHBoxLayout
from bauh import __version__, __app_name__, ROOT_DIR from bauh import __version__, __app_name__, ROOT_DIR
from bauh.view.util import resource from bauh.view.util import resource
from bauh.view.util.translation import I18n
PROJECT_URL = 'https://github.com/vinifmor/' + __app_name__ PROJECT_URL = 'https://github.com/vinifmor/' + __app_name__
LICENSE_URL = 'https://raw.githubusercontent.com/vinifmor/{}/master/LICENSE'.format(__app_name__) LICENSE_URL = 'https://raw.githubusercontent.com/vinifmor/{}/master/LICENSE'.format(__app_name__)
@@ -13,9 +14,9 @@ LICENSE_URL = 'https://raw.githubusercontent.com/vinifmor/{}/master/LICENSE'.for
class AboutDialog(QDialog): class AboutDialog(QDialog):
def __init__(self, locale_keys: dict): def __init__(self, i18n: I18n):
super(AboutDialog, self).__init__() super(AboutDialog, self).__init__()
self.setWindowTitle(locale_keys['tray.action.about']) self.setWindowTitle(i18n['tray.action.about'])
layout = QVBoxLayout() layout = QVBoxLayout()
self.setLayout(layout) self.setLayout(layout)
@@ -33,7 +34,7 @@ class AboutDialog(QDialog):
line_desc = QLabel(self) line_desc = QLabel(self)
line_desc.setStyleSheet('font-size: 12px; font-weight: bold;') line_desc.setStyleSheet('font-size: 12px; font-weight: bold;')
line_desc.setText(locale_keys['about.info.desc']) line_desc.setText(i18n['about.info.desc'])
line_desc.setAlignment(Qt.AlignCenter) line_desc.setAlignment(Qt.AlignCenter)
line_desc.setMinimumWidth(400) line_desc.setMinimumWidth(400)
layout.addWidget(line_desc) layout.addWidget(line_desc)
@@ -55,21 +56,21 @@ class AboutDialog(QDialog):
layout.addWidget(gems_widget) layout.addWidget(gems_widget)
layout.addWidget(QLabel('')) layout.addWidget(QLabel(''))
label_version = QLabel(locale_keys['version'].lower() + ' ' + __version__) label_version = QLabel(i18n['version'].lower() + ' ' + __version__)
label_version.setStyleSheet('QLabel { font-size: 11px; font-weight: bold }') label_version.setStyleSheet('QLabel { font-size: 11px; font-weight: bold }')
label_version.setAlignment(Qt.AlignCenter) label_version.setAlignment(Qt.AlignCenter)
layout.addWidget(label_version) layout.addWidget(label_version)
label_more_info = QLabel() label_more_info = QLabel()
label_more_info.setStyleSheet('font-size: 11px;') label_more_info.setStyleSheet('font-size: 11px;')
label_more_info.setText(locale_keys['about.info.link'] + ": <a href='{url}'>{url}</a>".format(url=PROJECT_URL)) label_more_info.setText(i18n['about.info.link'] + ": <a href='{url}'>{url}</a>".format(url=PROJECT_URL))
label_more_info.setOpenExternalLinks(True) label_more_info.setOpenExternalLinks(True)
label_more_info.setAlignment(Qt.AlignCenter) label_more_info.setAlignment(Qt.AlignCenter)
layout.addWidget(label_more_info) layout.addWidget(label_more_info)
label_license = QLabel() label_license = QLabel()
label_license.setStyleSheet('font-size: 11px;') label_license.setStyleSheet('font-size: 11px;')
label_license.setText("<a href='{}'>{}</a>".format(LICENSE_URL, locale_keys['about.info.license'])) label_license.setText("<a href='{}'>{}</a>".format(LICENSE_URL, i18n['about.info.license']))
label_license.setOpenExternalLinks(True) label_license.setOpenExternalLinks(True)
label_license.setAlignment(Qt.AlignCenter) label_license.setAlignment(Qt.AlignCenter)
layout.addWidget(label_license) layout.addWidget(label_license)
@@ -78,7 +79,7 @@ class AboutDialog(QDialog):
label_rate = QLabel() label_rate = QLabel()
label_rate.setStyleSheet('font-size: 11px; font-weight: bold;') label_rate.setStyleSheet('font-size: 11px; font-weight: bold;')
label_rate.setText(locale_keys['about.info.rate'] + ' :)') label_rate.setText(i18n['about.info.rate'] + ' :)')
label_rate.setOpenExternalLinks(True) label_rate.setOpenExternalLinks(True)
label_rate.setAlignment(Qt.AlignCenter) label_rate.setAlignment(Qt.AlignCenter)
layout.addWidget(label_rate) layout.addWidget(label_rate)

View File

@@ -15,6 +15,7 @@ from bauh.view.qt import dialog
from bauh.view.qt.components import IconButton from bauh.view.qt.components import IconButton
from bauh.view.qt.view_model import PackageView, PackageViewStatus from bauh.view.qt.view_model import PackageView, PackageViewStatus
from bauh.view.util import resource from bauh.view.util import resource
from bauh.view.util.translation import I18n
INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold' INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold'
@@ -25,7 +26,7 @@ PUBLISHER_MAX_SIZE = 25
class UpdateToggleButton(QWidget): class UpdateToggleButton(QWidget):
def __init__(self, app_view: PackageView, root: QWidget, i18n: dict, checked: bool = True, clickable: bool = True): def __init__(self, app_view: PackageView, root: QWidget, i18n: I18n, checked: bool = True, clickable: bool = True):
super(UpdateToggleButton, self).__init__() super(UpdateToggleButton, self).__init__()
self.app_view = app_view self.app_view = app_view
@@ -113,7 +114,7 @@ class AppsTable(QTableWidget):
if dialog.ask_confirmation( if dialog.ask_confirmation(
title=self.i18n['manage_window.apps_table.row.actions.downgrade'], title=self.i18n['manage_window.apps_table.row.actions.downgrade'],
body=self._parag(self.i18n['manage_window.apps_table.row.actions.downgrade.popup.body'].format(self._bold(str(pkg)))), body=self._parag(self.i18n['manage_window.apps_table.row.actions.downgrade.popup.body'].format(self._bold(str(pkg)))),
locale_keys=self.i18n): i18n=self.i18n):
self.window.downgrade(pkg) self.window.downgrade(pkg)
action_downgrade.triggered.connect(downgrade) action_downgrade.triggered.connect(downgrade)
@@ -131,7 +132,7 @@ class AppsTable(QTableWidget):
if dialog.ask_confirmation( if dialog.ask_confirmation(
title=self.i18n[action.i18_label_key], title=self.i18n[action.i18_label_key],
body=self._parag('{} {} ?'.format(self.i18n[action.i18_label_key], self._bold(str(pkg)))), body=self._parag('{} {} ?'.format(self.i18n[action.i18_label_key], self._bold(str(pkg)))),
locale_keys=self.i18n): i18n=self.i18n):
self.window.execute_custom_action(pkg, action) self.window.execute_custom_action(pkg, action)
item.triggered.connect(custom_action) item.triggered.connect(custom_action)
@@ -162,7 +163,7 @@ class AppsTable(QTableWidget):
def _uninstall_app(self, app_v: PackageView): def _uninstall_app(self, app_v: PackageView):
if dialog.ask_confirmation(title=self.i18n['manage_window.apps_table.row.actions.uninstall.popup.title'], if dialog.ask_confirmation(title=self.i18n['manage_window.apps_table.row.actions.uninstall.popup.title'],
body=self._parag(self.i18n['manage_window.apps_table.row.actions.uninstall.popup.body'].format(self._bold(str(app_v)))), body=self._parag(self.i18n['manage_window.apps_table.row.actions.uninstall.popup.body'].format(self._bold(str(app_v)))),
locale_keys=self.i18n): i18n=self.i18n):
self.window.uninstall_app(app_v) self.window.uninstall_app(app_v)
def _bold(self, text: str) -> str: def _bold(self, text: str) -> str:
@@ -176,7 +177,7 @@ class AppsTable(QTableWidget):
if dialog.ask_confirmation( if dialog.ask_confirmation(
title=self.i18n['manage_window.apps_table.row.actions.install.popup.title'], title=self.i18n['manage_window.apps_table.row.actions.install.popup.title'],
body=self._parag(self.i18n['manage_window.apps_table.row.actions.install.popup.body'].format(self._bold(str(pkgv)))), body=self._parag(self.i18n['manage_window.apps_table.row.actions.install.popup.body'].format(self._bold(str(pkgv)))),
locale_keys=self.i18n): i18n=self.i18n):
self.window.install(pkgv) self.window.install(pkgv)

View File

@@ -1,22 +1,23 @@
from typing import List from typing import List
from PyQt5.QtWidgets import QMessageBox, QVBoxLayout, QLabel, QWidget from PyQt5.QtWidgets import QMessageBox, QVBoxLayout, QLabel, QWidget
from bauh.api.abstract.view import ViewComponent, SingleSelectComponent, MultipleSelectComponent from bauh.api.abstract.view import ViewComponent, SingleSelectComponent, MultipleSelectComponent
from bauh.view.qt import css from bauh.view.qt import css
from bauh.view.qt.components import MultipleSelectQt, new_single_select from bauh.view.qt.components import MultipleSelectQt, new_single_select
from bauh.view.util.translation import I18n
class ConfirmationDialog(QMessageBox): class ConfirmationDialog(QMessageBox):
def __init__(self, title: str, body: str, locale_keys: dict, components: List[ViewComponent] = None, confirmation_label: str = None, deny_label: str = None): def __init__(self, title: str, body: str, i18n: I18n, components: List[ViewComponent] = None, confirmation_label: str = None, deny_label: str = None):
super(ConfirmationDialog, self).__init__() super(ConfirmationDialog, self).__init__()
self.setWindowTitle(title) self.setWindowTitle(title)
self.setStyleSheet('QLabel { margin-right: 25px; }') self.setStyleSheet('QLabel { margin-right: 25px; }')
self.bt_yes = self.addButton(locale_keys['popup.button.yes'] if not confirmation_label else confirmation_label.capitalize(), QMessageBox.YesRole) self.bt_yes = self.addButton(i18n['popup.button.yes'] if not confirmation_label else confirmation_label.capitalize(), QMessageBox.YesRole)
self.bt_yes.setStyleSheet(css.OK_BUTTON) self.bt_yes.setStyleSheet(css.OK_BUTTON)
self.addButton(locale_keys['popup.button.no'] if not deny_label else deny_label.capitalize(), QMessageBox.NoRole) self.addButton(i18n['popup.button.no'] if not deny_label else deny_label.capitalize(), QMessageBox.NoRole)
if body: if body:
if not components: if not components:

View File

@@ -6,6 +6,7 @@ from bauh.api.abstract.view import MessageType
from bauh.view.util import resource from bauh.view.util import resource
from bauh.view.qt import css from bauh.view.qt import css
from bauh.view.util.translation import I18n
MSG_TYPE_MAP = { MSG_TYPE_MAP = {
MessageType.ERROR: QMessageBox.Critical, MessageType.ERROR: QMessageBox.Critical,
@@ -26,7 +27,7 @@ def show_message(title: str, body: str, type_: MessageType, icon: QIcon = QIcon(
popup.exec_() popup.exec_()
def ask_confirmation(title: str, body: str, locale_keys: dict, icon: QIcon = QIcon(resource.get_path('img/logo.svg')), widgets: List[QWidget] = None): def ask_confirmation(title: str, body: str, i18n: I18n, icon: QIcon = QIcon(resource.get_path('img/logo.svg')), widgets: List[QWidget] = None):
diag = QMessageBox() diag = QMessageBox()
diag.setIcon(QMessageBox.Question) diag.setIcon(QMessageBox.Question)
diag.setWindowTitle(title) diag.setWindowTitle(title)
@@ -42,10 +43,10 @@ def ask_confirmation(title: str, body: str, locale_keys: dict, icon: QIcon = QIc
diag.layout().addWidget(wbody, 0, 1) diag.layout().addWidget(wbody, 0, 1)
bt_yes = diag.addButton(locale_keys['popup.button.yes'], QMessageBox.YesRole) bt_yes = diag.addButton(i18n['popup.button.yes'], QMessageBox.YesRole)
bt_yes.setStyleSheet(css.OK_BUTTON) bt_yes.setStyleSheet(css.OK_BUTTON)
diag.addButton(locale_keys['popup.button.no'], QMessageBox.NoRole) diag.addButton(i18n['popup.button.no'], QMessageBox.NoRole)
if icon: if icon:
diag.setWindowIcon(icon) diag.setWindowIcon(icon)

View File

@@ -9,11 +9,12 @@ from bauh.view.core.controller import GenericSoftwareManager
from bauh.view.util import resource from bauh.view.util import resource
from bauh.view.qt import qt_utils, css from bauh.view.qt import qt_utils, css
from bauh.view.qt.components import MultipleSelectQt, CheckboxQt, new_spacer from bauh.view.qt.components import MultipleSelectQt, CheckboxQt, new_spacer
from bauh.view.util.translation import I18n
class GemSelectorPanel(QWidget): class GemSelectorPanel(QWidget):
def __init__(self, window: QWidget, manager: GenericSoftwareManager, i18n: dict, config: Configuration, show_panel_after_restart: bool = False): def __init__(self, window: QWidget, manager: GenericSoftwareManager, i18n: I18n, config: Configuration, show_panel_after_restart: bool = False):
super(GemSelectorPanel, self).__init__() super(GemSelectorPanel, self).__init__()
self.window = window self.window = window
self.manager = manager self.manager = manager

View File

@@ -7,11 +7,12 @@ from PyQt5.QtWidgets import QDialog, QVBoxLayout, QTableWidget, QTableWidgetItem
from bauh.api.abstract.cache import MemoryCache from bauh.api.abstract.cache import MemoryCache
from bauh.api.abstract.model import PackageHistory from bauh.api.abstract.model import PackageHistory
from bauh.view.util.translation import I18n
class HistoryDialog(QDialog): class HistoryDialog(QDialog):
def __init__(self, history: PackageHistory, icon_cache: MemoryCache, i18n: dict): def __init__(self, history: PackageHistory, icon_cache: MemoryCache, i18n: I18n):
super(HistoryDialog, self).__init__() super(HistoryDialog, self).__init__()
self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint)

View File

@@ -4,13 +4,14 @@ from PyQt5.QtWidgets import QDialog, QVBoxLayout, QGroupBox, \
QLineEdit, QLabel, QGridLayout, QPushButton, QPlainTextEdit, QToolBar QLineEdit, QLabel, QGridLayout, QPushButton, QPlainTextEdit, QToolBar
from bauh.api.abstract.cache import MemoryCache from bauh.api.abstract.cache import MemoryCache
from bauh.view.util.translation import I18n
IGNORED_ATTRS = {'name', '__app__'} IGNORED_ATTRS = {'name', '__app__'}
class InfoDialog(QDialog): class InfoDialog(QDialog):
def __init__(self, app: dict, icon_cache: MemoryCache, i18n: dict, screen_size: QSize()): def __init__(self, app: dict, icon_cache: MemoryCache, i18n: I18n, screen_size: QSize()):
super(InfoDialog, self).__init__() super(InfoDialog, self).__init__()
self.setWindowTitle(str(app['__app__'])) self.setWindowTitle(str(app['__app__']))
self.screen_size = screen_size self.screen_size = screen_size

View File

@@ -7,13 +7,14 @@ from bauh.api.abstract.view import MessageType
from bauh.commons.system import new_subprocess from bauh.commons.system import new_subprocess
from bauh.view.qt.dialog import show_message from bauh.view.qt.dialog import show_message
from bauh.view.util import resource from bauh.view.util import resource
from bauh.view.util.translation import I18n
def is_root(): def is_root():
return os.getuid() == 0 return os.getuid() == 0
def ask_root_password(i18n: dict): def ask_root_password(i18n: I18n):
diag = QInputDialog() diag = QInputDialog()
diag.setStyleSheet("""QLineEdit { border-radius: 5px; font-size: 16px }""") diag.setStyleSheet("""QLineEdit { border-radius: 5px; font-size: 16px }""")
diag.setInputMode(QInputDialog.TextInput) diag.setInputMode(QInputDialog.TextInput)

View File

@@ -12,6 +12,7 @@ from bauh.view.qt import qt_utils
from bauh.view.qt.components import new_spacer from bauh.view.qt.components import new_spacer
from bauh.view.qt.thread import AnimateProgress from bauh.view.qt.thread import AnimateProgress
from bauh.view.qt.view_model import PackageView from bauh.view.qt.view_model import PackageView
from bauh.view.util.translation import I18n
class ScreenshotsDialog(QDialog): class ScreenshotsDialog(QDialog):
@@ -19,7 +20,7 @@ class ScreenshotsDialog(QDialog):
MAX_HEIGHT = 600 MAX_HEIGHT = 600
MAX_WIDTH = 800 MAX_WIDTH = 800
def __init__(self, pkg: PackageView, http_client: HttpClient, icon_cache: MemoryCache, i18n: dict, screenshots: List[QPixmap], logger: logging.Logger): def __init__(self, pkg: PackageView, http_client: HttpClient, icon_cache: MemoryCache, i18n: I18n, screenshots: List[QPixmap], logger: logging.Logger):
super(ScreenshotsDialog, self).__init__() super(ScreenshotsDialog, self).__init__()
self.setWindowTitle(str(pkg)) self.setWindowTitle(str(pkg))
self.screenshots = screenshots self.screenshots = screenshots

View File

@@ -5,11 +5,12 @@ from bauh.commons.html import bold
from bauh.view.core import config from bauh.view.core import config
from bauh.view.util import util from bauh.view.util import util
from bauh.view.qt import dialog from bauh.view.qt import dialog
from bauh.view.util.translation import I18n
class StylesComboBox(QComboBox): class StylesComboBox(QComboBox):
def __init__(self, parent: QWidget, i18n: dict, show_panel_after_restart: bool): def __init__(self, parent: QWidget, i18n: I18n, show_panel_after_restart: bool):
super(StylesComboBox, self).__init__(parent=parent) super(StylesComboBox, self).__init__(parent=parent)
self.app = QApplication.instance() self.app = QApplication.instance()
self.styles = [] self.styles = []

View File

@@ -14,6 +14,7 @@ from bauh.api.abstract.model import PackageUpdate
from bauh.view.util import util, resource from bauh.view.util import util, resource
from bauh.view.qt.about import AboutDialog from bauh.view.qt.about import AboutDialog
from bauh.view.qt.window import ManageWindow from bauh.view.qt.window import ManageWindow
from bauh.view.util.translation import I18n
class UpdateCheck(QThread): class UpdateCheck(QThread):
@@ -35,7 +36,7 @@ class UpdateCheck(QThread):
class TrayIcon(QSystemTrayIcon): class TrayIcon(QSystemTrayIcon):
def __init__(self, i18n: dict, manager: SoftwareManager, manage_window: ManageWindow, check_interval: int = 60, update_notification: bool = True): def __init__(self, i18n: I18n, manager: SoftwareManager, manage_window: ManageWindow, check_interval: int = 60, update_notification: bool = True):
super(TrayIcon, self).__init__() super(TrayIcon, self).__init__()
self.i18n = i18n self.i18n = i18n
self.manager = manager self.manager = manager

View File

@@ -12,9 +12,9 @@ from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.model import PackageStatus, SoftwarePackage, PackageAction from bauh.api.abstract.model import PackageStatus, SoftwarePackage, PackageAction
from bauh.api.abstract.view import InputViewComponent, MessageType from bauh.api.abstract.view import InputViewComponent, MessageType
from bauh.api.exception import NoInternetException from bauh.api.exception import NoInternetException
from bauh.api.http import HttpClient
from bauh.view.qt import commons from bauh.view.qt import commons
from bauh.view.qt.view_model import PackageView from bauh.view.qt.view_model import PackageView
from bauh.view.util.translation import I18n
RE_VERSION_IN_NAME = re.compile(r'\s+version\s+[\w\.]+\s*$') RE_VERSION_IN_NAME = re.compile(r'\s+version\s+[\w\.]+\s*$')
@@ -76,12 +76,12 @@ class AsyncAction(QThread, ProcessWatcher):
class UpdateSelectedApps(AsyncAction): class UpdateSelectedApps(AsyncAction):
def __init__(self, manager: SoftwareManager, locale_keys: dict, apps_to_update: List[PackageView] = None): def __init__(self, manager: SoftwareManager, i18n: I18n, apps_to_update: List[PackageView] = None):
super(UpdateSelectedApps, self).__init__() super(UpdateSelectedApps, self).__init__()
self.apps_to_update = apps_to_update self.apps_to_update = apps_to_update
self.manager = manager self.manager = manager
self.root_password = None self.root_password = None
self.locale_keys = locale_keys self.i18n = i18n
def run(self): def run(self):
@@ -93,7 +93,7 @@ class UpdateSelectedApps(AsyncAction):
name = app.model.name if not RE_VERSION_IN_NAME.findall(app.model.name) else app.model.name.split('version')[0].strip() name = app.model.name if not RE_VERSION_IN_NAME.findall(app.model.name) else app.model.name.split('version')[0].strip()
self.change_status('{} {} {}...'.format(self.locale_keys['manage_window.status.upgrading'], name, app.model.version)) self.change_status('{} {} {}...'.format(self.i18n['manage_window.status.upgrading'], name, app.model.version))
success = bool(self.manager.update(app.model, self.root_password, self)) success = bool(self.manager.update(app.model, self.root_password, self))
self.change_substatus('') self.change_substatus('')
@@ -168,11 +168,11 @@ class UninstallApp(AsyncAction):
class DowngradeApp(AsyncAction): class DowngradeApp(AsyncAction):
def __init__(self, manager: SoftwareManager, locale_keys: dict, app: PackageView = None): def __init__(self, manager: SoftwareManager, i18n: I18n, app: PackageView = None):
super(DowngradeApp, self).__init__() super(DowngradeApp, self).__init__()
self.manager = manager self.manager = manager
self.app = app self.app = app
self.locale_keys = locale_keys self.i18n = i18n
self.root_password = None self.root_password = None
def run(self): def run(self):
@@ -182,7 +182,7 @@ class DowngradeApp(AsyncAction):
success = self.manager.downgrade(self.app.model, self.root_password, self) success = self.manager.downgrade(self.app.model, self.root_password, self)
except (requests.exceptions.ConnectionError, NoInternetException) as e: except (requests.exceptions.ConnectionError, NoInternetException) as e:
success = False success = False
self.print(self.locale_keys['internet.required']) self.print(self.i18n['internet.required'])
finally: finally:
self.notify_finished({'app': self.app, 'success': success}) self.notify_finished({'app': self.app, 'success': success})
self.app = None self.app = None
@@ -206,18 +206,18 @@ class GetAppInfo(AsyncAction):
class GetAppHistory(AsyncAction): class GetAppHistory(AsyncAction):
def __init__(self, manager: SoftwareManager, locale_keys: dict, app: PackageView = None): def __init__(self, manager: SoftwareManager, i18n: I18n, app: PackageView = None):
super(GetAppHistory, self).__init__() super(GetAppHistory, self).__init__()
self.app = app self.app = app
self.manager = manager self.manager = manager
self.locale_keys = locale_keys self.i18n = i18n
def run(self): def run(self):
if self.app: if self.app:
try: try:
self.notify_finished({'history': self.manager.get_history(self.app.model)}) self.notify_finished({'history': self.manager.get_history(self.app.model)})
except (requests.exceptions.ConnectionError, NoInternetException) as e: except (requests.exceptions.ConnectionError, NoInternetException) as e:
self.notify_finished({'error': self.locale_keys['internet.required']}) self.notify_finished({'error': self.i18n['internet.required']})
finally: finally:
self.app = None self.app = None
@@ -246,13 +246,13 @@ class SearchPackages(AsyncAction):
class InstallPackage(AsyncAction): class InstallPackage(AsyncAction):
def __init__(self, manager: SoftwareManager, disk_cache: bool, icon_cache: MemoryCache, locale_keys: dict, pkg: PackageView = None): def __init__(self, manager: SoftwareManager, disk_cache: bool, icon_cache: MemoryCache, i18n: I18n, pkg: PackageView = None):
super(InstallPackage, self).__init__() super(InstallPackage, self).__init__()
self.pkg = pkg self.pkg = pkg
self.manager = manager self.manager = manager
self.icon_cache = icon_cache self.icon_cache = icon_cache
self.disk_cache = disk_cache self.disk_cache = disk_cache
self.locale_keys = locale_keys self.i18n = i18n
self.root_password = None self.root_password = None
def run(self): def run(self):
@@ -272,7 +272,7 @@ class InstallPackage(AsyncAction):
only_icon=False) only_icon=False)
except (requests.exceptions.ConnectionError, NoInternetException): except (requests.exceptions.ConnectionError, NoInternetException):
success = False success = False
self.print(self.locale_keys['internet.required']) self.print(self.i18n['internet.required'])
finally: finally:
self.signal_finished.emit({'success': success, 'pkg': self.pkg}) self.signal_finished.emit({'success': success, 'pkg': self.pkg})
self.pkg = None self.pkg = None
@@ -403,9 +403,9 @@ class ListWarnings(QThread):
signal_warnings = pyqtSignal(list) signal_warnings = pyqtSignal(list)
def __init__(self, man: SoftwareManager, locale_keys: dict): def __init__(self, man: SoftwareManager, i18n: I18n):
super(QThread, self).__init__() super(QThread, self).__init__()
self.locale_keys = locale_keys self.i18n = i18n
self.man = man self.man = man
def run(self): def run(self):
@@ -464,12 +464,13 @@ class ApplyFilters(AsyncAction):
class CustomAction(AsyncAction): class CustomAction(AsyncAction):
def __init__(self, manager: SoftwareManager, custom_action: PackageAction = None, pkg: PackageView = None, root_password: str = None): def __init__(self, manager: SoftwareManager, i18n: I18n, custom_action: PackageAction = None, pkg: PackageView = None, root_password: str = None):
super(CustomAction, self).__init__() super(CustomAction, self).__init__()
self.manager = manager self.manager = manager
self.pkg = pkg self.pkg = pkg
self.custom_action = custom_action self.custom_action = custom_action
self.root_password = root_password self.root_password = root_password
self.i18n = i18n
def run(self): def run(self):
success = True success = True
@@ -481,7 +482,7 @@ class CustomAction(AsyncAction):
watcher=self) watcher=self)
except (requests.exceptions.ConnectionError, NoInternetException): except (requests.exceptions.ConnectionError, NoInternetException):
success = False success = False
self.signal_output.emit(self.locale_keys['internet.required']) self.signal_output.emit(self.i18n['internet.required'])
self.notify_finished({'success': success, 'pkg': self.pkg}) self.notify_finished({'success': success, 'pkg': self.pkg})
self.pkg = None self.pkg = None

View File

@@ -36,6 +36,7 @@ from bauh.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, D
from bauh.view.qt.view_model import PackageView from bauh.view.qt.view_model import PackageView
from bauh.view.qt.view_utils import load_icon from bauh.view.qt.view_utils import load_icon
from bauh.view.util import util, resource from bauh.view.util import util, resource
from bauh.view.util.translation import I18n
DARK_ORANGE = '#FF4500' DARK_ORANGE = '#FF4500'
@@ -50,7 +51,7 @@ class ManageWindow(QWidget):
signal_user_res = pyqtSignal(bool) signal_user_res = pyqtSignal(bool)
signal_table_update = pyqtSignal() signal_table_update = pyqtSignal()
def __init__(self, i18n: dict, icon_cache: MemoryCache, manager: SoftwareManager, disk_cache: bool, def __init__(self, i18n: I18n, icon_cache: MemoryCache, manager: SoftwareManager, disk_cache: bool,
download_icons: bool, screen_size, suggestions: bool, display_limit: int, config: Configuration, download_icons: bool, screen_size, suggestions: bool, display_limit: int, config: Configuration,
context: ApplicationContext, notifications: bool, http_client: HttpClient, logger: logging.Logger, context: ApplicationContext, notifications: bool, http_client: HttpClient, logger: logging.Logger,
tray_icon=None): tray_icon=None):
@@ -231,7 +232,7 @@ class ManageWindow(QWidget):
self.thread_downgrade = self._bind_async_action(DowngradeApp(self.manager, self.i18n), finished_call=self._finish_downgrade) self.thread_downgrade = self._bind_async_action(DowngradeApp(self.manager, self.i18n), finished_call=self._finish_downgrade)
self.thread_suggestions = self._bind_async_action(FindSuggestions(man=self.manager), finished_call=self._finish_search, only_finished=True) self.thread_suggestions = self._bind_async_action(FindSuggestions(man=self.manager), finished_call=self._finish_search, only_finished=True)
self.thread_run_app = self._bind_async_action(LaunchApp(self.manager), finished_call=self._finish_run_app, only_finished=False) self.thread_run_app = self._bind_async_action(LaunchApp(self.manager), finished_call=self._finish_run_app, only_finished=False)
self.thread_custom_action = self._bind_async_action(CustomAction(manager=self.manager), finished_call=self._finish_custom_action) self.thread_custom_action = self._bind_async_action(CustomAction(manager=self.manager, i18n=self.i18n), finished_call=self._finish_custom_action)
self.thread_screenshots = self._bind_async_action(GetScreenshots(self.manager), finished_call=self._finish_get_screenshots) self.thread_screenshots = self._bind_async_action(GetScreenshots(self.manager), finished_call=self._finish_get_screenshots)
self.thread_apply_filters = ApplyFilters() self.thread_apply_filters = ApplyFilters()
@@ -239,7 +240,7 @@ class ManageWindow(QWidget):
self.thread_apply_filters.signal_table.connect(self._update_table_and_upgrades) self.thread_apply_filters.signal_table.connect(self._update_table_and_upgrades)
self.signal_table_update.connect(self.thread_apply_filters.stop_waiting) self.signal_table_update.connect(self.thread_apply_filters.stop_waiting)
self.thread_install = InstallPackage(manager=self.manager, disk_cache=self.disk_cache, icon_cache=self.icon_cache, locale_keys=self.i18n) self.thread_install = InstallPackage(manager=self.manager, disk_cache=self.disk_cache, icon_cache=self.icon_cache, i18n=self.i18n)
self._bind_async_action(self.thread_install, finished_call=self._finish_install) self._bind_async_action(self.thread_install, finished_call=self._finish_install)
self.thread_animate_progress = AnimateProgress() self.thread_animate_progress = AnimateProgress()
@@ -289,7 +290,7 @@ class ManageWindow(QWidget):
self.dialog_about = None self.dialog_about = None
self.first_refresh = suggestions self.first_refresh = suggestions
self.thread_warnings = ListWarnings(man=manager, locale_keys=i18n) self.thread_warnings = ListWarnings(man=manager, i18n=i18n)
self.thread_warnings.signal_warnings.connect(self._show_warnings) self.thread_warnings.signal_warnings.connect(self._show_warnings)
def set_tray_icon(self, tray_icon): def set_tray_icon(self, tray_icon):
@@ -349,7 +350,7 @@ class ManageWindow(QWidget):
self.thread_animate_progress.pause() self.thread_animate_progress.pause()
diag = ConfirmationDialog(title=msg['title'], diag = ConfirmationDialog(title=msg['title'],
body=msg['body'], body=msg['body'],
locale_keys=self.i18n, i18n=self.i18n,
components=msg['components'], components=msg['components'],
confirmation_label=msg['confirmation_label'], confirmation_label=msg['confirmation_label'],
deny_label=msg['deny_label']) deny_label=msg['deny_label'])
@@ -792,7 +793,7 @@ class ManageWindow(QWidget):
if to_update and dialog.ask_confirmation(title=self.i18n['manage_window.upgrade_all.popup.title'], if to_update and dialog.ask_confirmation(title=self.i18n['manage_window.upgrade_all.popup.title'],
body=self.i18n['manage_window.upgrade_all.popup.body'], body=self.i18n['manage_window.upgrade_all.popup.body'],
locale_keys=self.i18n, i18n=self.i18n,
widgets=[UpdateToggleButton(None, self, self.i18n, clickable=False)]): widgets=[UpdateToggleButton(None, self, self.i18n, clickable=False)]):
pwd = None pwd = None

View File

@@ -0,0 +1,67 @@
import glob
import locale
from typing import Tuple
from bauh.view.util import resource
class I18n(dict):
def __init__(self, current_locale: dict, default_locale: dict):
super(I18n, self).__init__()
self.current = current_locale
self.default = default_locale
def __getitem__(self, item):
try:
return self.current.__getitem__(item)
except KeyError:
if self.default:
return self.default.__getitem__(item)
else:
raise
def get(self, *args, **kwargs):
res = self.current.get(args[0])
if res is None:
if self.default:
return self.default.get(*args, **kwargs)
else:
return self.current.get(*args, **kwargs)
return res
def get_locale_keys(key: str = None, locale_dir: str = resource.get_path('locale')) -> Tuple[str, dict]:
locale_path = None
if key is None:
current_locale = locale.getdefaultlocale()
else:
current_locale = [key.strip().lower()]
if current_locale:
current_locale = current_locale[0]
for locale_file in glob.glob(locale_dir + '/*'):
name = locale_file.split('/')[-1]
if current_locale == name or current_locale.startswith(name + '_'):
locale_path = locale_file
break
if not locale_path:
return key, {}
with open(locale_path, 'r') as f:
locale_keys = f.readlines()
locale_obj = {}
for line in locale_keys:
if line:
keyval = line.strip().split('=')
locale_obj[keyval[0].strip()] = keyval[1].strip()
return locale_path.split('/')[-1], locale_obj

View File

@@ -1,9 +1,6 @@
import glob
import locale
import os import os
import subprocess import subprocess
import sys import sys
from typing import Tuple
from PyQt5.QtCore import QCoreApplication from PyQt5.QtCore import QCoreApplication
@@ -12,40 +9,6 @@ from bauh.commons.system import run_cmd
from bauh.view.util import resource from bauh.view.util import resource
def get_locale_keys(key: str = None, locale_dir: str = resource.get_path('locale')) -> Tuple[str, dict]:
locale_path = None
if key is None:
current_locale = locale.getdefaultlocale()
else:
current_locale = [key.strip().lower()]
if current_locale:
current_locale = current_locale[0]
for locale_file in glob.glob(locale_dir + '/*'):
name = locale_file.split('/')[-1]
if current_locale == name or current_locale.startswith(name + '_'):
locale_path = locale_file
break
if not locale_path:
locale_path = resource.get_path('locale/en')
with open(locale_path, 'r') as f:
locale_keys = f.readlines()
locale_obj = {}
for line in locale_keys:
if line:
keyval = line.strip().split('=')
locale_obj[keyval[0].strip()] = keyval[1].strip()
return locale_path.split('/')[-1], locale_obj
def notify_user(msg: str, icon_path: str = resource.get_path('img/logo.svg')): def notify_user(msg: str, icon_path: str = resource.get_path('img/logo.svg')):
os.system("notify-send -a {} {} '{}'".format(__app_name__, "-i {}".format(icon_path) if icon_path else '', msg)) os.system("notify-send -a {} {} '{}'".format(__app_name__, "-i {}".format(icon_path) if icon_path else '', msg))