[config] finished moving

This commit is contained in:
Vinícius Moreira
2019-12-20 12:28:05 -03:00
parent f173a7c742
commit e626b8df7e
10 changed files with 157 additions and 141 deletions

View File

@@ -1,5 +1,5 @@
# Changelog
All notable changes to this project will be documented in this file.
All notable changes to this project will be documented in this file.uh-staging
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
@@ -13,35 +13,36 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Improvements
- configuration file **~/.config/bauh/config.json** renamed to **~/.config/bauh/config.yml**
- some parameters were moved to the configuration file ( **~/.config/bauh/config.yml** ):
- `--cache-exp` and `--icon-exp` became:
```cache:
data_expiration:
icon_expiration:
```
- `--locale`
- `--check-interval` became:
```
updates:
check_interval:
```
- `--system-notifications` -> `system_notifications`
- `--disk-cache`
- `--download-icons`
- `--check-packaging-once`
- `--sugs` ( renamed as `suggestions` )
- `--max-displayed`
- `--download-mthread`
- some settings from **~/.config/bauh/config.json** were renamed in **~/.config/bauh/config.yml**:
- `enabled_gems` -> `gems`
- some environment variables were moved as fields in **~/.config/bauh/config.yml**:
- `BAUH_TRAY_DEFAULT_ICON_PATH` and `BAUH_TRAY_UPDATES_ICON_PATH` became:
```
tray:
icon_default: null, # path to the icon representing the default state
icon_updates: null # path to the icon representing the "new updates" state
```
- some parameters and environment variable were moved to the configuration file ( **~/.config/bauh/config.yml** )
```
disk_cache: # old '--disk_cache'
enabled: true
download:
icons: true # old '--download-icons'
multithreaded: true # old '--download-mthread'
gems: null
locale: null # old '--locale'
memory_cache:
data_expiration: 3600 # old '--cache-exp'
icon_expiration: 300 # old '--icon-exp'
suggestions:
by_type: 10 # new -> defines the max number of suggestions by package type
enabled: true # old '--sugs'
system:
notifications: true # old '--system-notifications'
single_dependency_checking: false # old '---check-packaging-once'
ui:
style: null
table:
max_displayed: 50 # old '--max-displayed'
tray:
default_icon: null # old environment variable 'BAUH_TRAY_DEFAULT_ICON_PATH'
updates_icon: null # old environment variable 'BAUH_TRAY_UPDATES_ICON_PATH'
updates:
check_interval: 30 # old '--check-interval'
```
- The default update checking interval is now 30 seconds
- AppImage:
- cleaning the downloaded database files when **--reset** is passed as parameter
- environment variables **BAUH_APPIMAGE_DB_UPDATER** and **BAUH_APPIMAGE_DB_UPDATER_TIME** dropped in favor of the new configuration file located at **~/.config/bauh/appimage.yml**

View File

@@ -182,21 +182,51 @@ environment:
- Debian-based systems ( using pip ): **beautifulsoup4**, **lxml**
### General settings
You can change some application settings via environment variables or arguments (type ```bauh --help``` to get more information).
- **BAUH_TRAY**: If the tray icon and update-check daemon should be created. Use **0** (disable, default) or **1** (enable).
- **BAUH_LOGS**: enable **bauh** logs (for debugging purposes). Use: **0** (disable, default) or **1** (enable)
- **BAUH_TRAY_DEFAULT_ICON_PATH**: define a custom icon for the tray mode ( absolute path)
- **BAUH_TRAY_UPDATES_ICON_PATH** define a custom updates icon for the tray mode ( absolute path)
### How to improve **bauh** performance
#### Environment variables / parameters
You can change some application settings via environment variables or arguments (type ```bauh --help``` to get more information).
- `BAUH_TRAY (--tray )`: If the tray icon and update-check daemon should be created. Use `0` (disable, default) or `1` (enable).
- `BAUH_LOGS (--logs )`: enable **bauh** logs (for debugging purposes). Use: `0` (disable, default) or `1` (enable)
- `--reset`: cleans all configurations and cached data stored in HOME directory
#### General configuration file ( **/.config/bauh/config.yml** )
```
disk_cache:
enabled: true # allows bauh to save applications icons and data to the disk to load them faster when needed
download:
icons: true # allows bauh to download the applications icons when they are not saved on the disk
multithreaded: true # allows bauh to use a multithreaded download client installed on the system to download applications source files faster ( current only **aria2** is supported )
gems: null # defines the enabled applications types managed by bauh ( a null value means all available )
locale: null # defines a different translation for bauh ( a null value will retrieve the system's default locale )
memory_cache:
data_expiration: 3600 # the interval in SECONDS that data cached in memory will live
icon_expiration: 300 # the interval in SECONDS that icons cached in memory will live
suggestions:
by_type: 10 # the maximum number of application suggestions that must be retrieved per type
enabled: true # if suggestions must be displayed when no application is installed
system:
notifications: true # if system popup should be displayed for some events. e.g: when there are updates, bauh will display a system popup
single_dependency_checking: false # if bauh should check only once if for the available technologies on the system.
ui:
style: null # the bauh QT styles. a null value will map to 'Fusion' or 'Breeze' ( depending on what is installed )
table:
max_displayed: 50 # defines the maximum number of displayed applications on the table.
tray: # system tray settings
default_icon: null # defines a path to a custom icon
updates_icon: null # defines a path to a custom icon indicating updates
updates:
check_interval: 30 # the updates checking interval in SECONDS
```
### How to improve the performance
- Disable package types that you do not want to deal with ( via GUI )
- If you don't care about restarting the app every time a new supported packaging technology is installed, set "check-packaging-once=1" (**bauh --check-packaging-once=1**). This can reduce the application response time up in some scenarios, since it won't need to recheck if the packaging type is available for every action you request.
- If you don't mind to see the applications icons, you can set "download-icons=0" (**bauh --download-icons=0**). The application may have a slight response improvement, since it will reduce the parallelism within it.
- Let the disk cache always enabled so **bauh** does not need to dynamically retrieve some data every time you launch it.
- If you don't care about restarting the app every time a new supported packaging technology is installed, enable `single_dependency_checking`. This can reduce the application response time up in some scenarios, since it won't need to recheck if required technologies are available for every action you request.
- If you don't mind to see the applications icons, you can disable `download: icons: false`. The application may have a slight response improvement, since it will reduce the IO and parallelism within it.
- Let the `disk_cache` always enabled so **bauh** does not need to dynamically retrieve data every time you launch it.
### Files and Logs
- Some application settings are stored in **~/.config/bauh/config.json**
- Installation logs are saved at **/tmp/bauh/logs/install**
- Some data about your installed applications are stored in **~/.cache/bauh** to load them faster ( default behavior ).

View File

@@ -34,28 +34,27 @@ def main():
app_args.validate(args, logger)
local_config = config.read_config(update_file=True)
config.validate(local_config, logger)
i18n_key, current_i18n = translation.get_locale_keys(local_config.locale)
i18n_key, current_i18n = translation.get_locale_keys(local_config['locale'])
default_i18n = translation.get_locale_keys(DEFAULT_I18N_KEY)[1] if i18n_key != DEFAULT_I18N_KEY else {}
i18n = I18n(i18n_key, current_i18n, DEFAULT_I18N_KEY, default_i18n)
cache_cleaner = CacheCleaner()
cache_factory = DefaultMemoryCacheFactory(expiration_time=local_config.cache_exp, cleaner=cache_cleaner)
icon_cache = cache_factory.new(local_config.icon_exp)
cache_factory = DefaultMemoryCacheFactory(expiration_time=int(local_config['memory_cache']['data_expiration']), cleaner=cache_cleaner)
icon_cache = cache_factory.new(int(local_config['memory_cache']['icon_expiration']))
http_client = HttpClient(logger)
context = ApplicationContext(i18n=i18n,
http_client=http_client,
disk_cache=local_config.disk_cache,
download_icons=local_config.download_icons,
disk_cache=bool(local_config['disk_cache']['enabled']),
download_icons=bool(local_config['download']['icons']),
app_root_dir=ROOT_DIR,
cache_factory=cache_factory,
disk_loader_factory=DefaultDiskCacheLoaderFactory(disk_cache_enabled=local_config.disk_cache, logger=logger),
disk_loader_factory=DefaultDiskCacheLoaderFactory(disk_cache_enabled=bool(local_config['disk_cache']['enabled']), logger=logger),
logger=logger,
distro=util.get_distro(),
file_downloader=AdaptableFileDownloader(logger, local_config.download_mthread,
file_downloader=AdaptableFileDownloader(logger, bool(local_config['download']['multithreaded']),
i18n, http_client))
managers = gems.load_managers(context=context, locale=i18n_key, config=local_config, default_locale=DEFAULT_I18N_KEY)
@@ -72,8 +71,8 @@ def main():
app.setApplicationVersion(__version__)
app.setWindowIcon(QIcon(resource.get_path('img/logo.svg')))
if local_config.style:
app.setStyle(local_config.style)
if local_config['ui']['style']:
app.setStyle(str(local_config['ui']['style']))
else:
if app.style().objectName().lower() not in {'fusion', 'breeze'}:
app.setStyle('Fusion')
@@ -91,8 +90,7 @@ def main():
tray_icon = TrayIcon(i18n=i18n,
manager=manager,
manage_window=manage_window,
check_interval=local_config.update_check_interval,
update_notification=local_config.system_notifications)
config=local_config)
manage_window.set_tray_icon(tray_icon)
tray_icon.show()

View File

@@ -12,67 +12,52 @@ from bauh.commons.config import read_config as read
CONFIG_PATH = '{}/.config/{}'.format(Path.home(), __app_name__)
FILE_PATH = '{}/config.yml'.format(CONFIG_PATH)
# TODO stopped here
class UpdatesSettings:
def __init__(self, check_interval: int, **kwargs):
self.check_interval = check_interval
class CacheSettings:
def __init__(self, data_expiration: int, icon_expiration: int, **kwargs):
self.data_expiration = data_expiration
self.icon_expiration = icon_expiration
class Configuration:
def __init__(self, gems: List[str], style: str, cache: dict, locale: str,
updates: dict, system_notifications: bool, disk_cache: bool, download_icons: bool,
check_packaging_once: bool, suggestions: bool, max_displayed: int, download_mthread: bool,
**kwargs):
self.gems = gems
self.style = style
self.cache = CacheSettings(**cache)
self.locale = locale
self.updates = UpdatesSettings(**updates)
self.system_notifications = system_notifications
self.disk_cache = disk_cache
self.download_icons = download_icons
self.check_packaging_once = check_packaging_once
self.suggestions = suggestions
self.max_displayed = max_displayed
self.download_mthread = download_mthread
def read_config(update_file: bool = False) -> Configuration:
def read_config(update_file: bool = False) -> dict:
default = {
'gems': None,
'style': None,
'cache_exp': 60 * 60,
'icon_exp': 60 * 5,
'memory_cache': {
'data_expiration': 60 * 60,
'icon_expiration': 60 * 5
},
'locale': None,
'updates': {
'check_interval': 60
'check_interval': 30
},
'system_notifications': True,
'disk_cache': True,
'download_icons': True,
'check_packaging_once': False,
'suggestions': True,
'max_displayed': 50, # table
'download_mthread': True # downloads
'system': {
'notifications': True,
'single_dependency_checking': False
},
'disk_cache': {
'enabled': True
},
'suggestions': {
'enabled': True,
'by_type': 10
},
'ui': {
'table': {
'max_displayed': 50
},
'tray': {
'default_icon': None,
'updates_icon': None
},
'style': None
},
'download': {
'multithreaded': True,
'icons': True
}
}
obj = read(FILE_PATH, default, update_file=update_file, update_async=True)
return Configuration(**obj)
return read(FILE_PATH, default, update_file=update_file, update_async=True)
def save(config: Configuration):
def save(config: dict):
Path(CONFIG_PATH).mkdir(parents=True, exist_ok=True)
with open(FILE_PATH, 'w+') as f:
f.write(yaml.safe_dump(config.__dict__))
f.write(yaml.safe_dump(config))
def remove_old_config(logger: logging.Logger):

View File

@@ -1,7 +1,6 @@
import re
import time
import traceback
from argparse import Namespace
from threading import Thread
from typing import List, Set, Type
@@ -11,26 +10,24 @@ from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.model import SoftwarePackage, PackageUpdate, PackageHistory, PackageSuggestion, PackageAction
from bauh.api.exception import NoInternetException
from bauh.commons import internet
from bauh.view.core.config import Configuration
RE_IS_URL = re.compile(r'^https?://.+')
SUGGESTIONS_LIMIT = 10
class GenericSoftwareManager(SoftwareManager):
def __init__(self, managers: List[SoftwareManager], context: ApplicationContext, config: Configuration):
def __init__(self, managers: List[SoftwareManager], context: ApplicationContext, config: dict):
super(GenericSoftwareManager, self).__init__(context=context)
self.managers = managers
self.map = {t: m for m in self.managers for t in m.get_managed_types()}
self._available_cache = {} if config.check_packaging_once else None
self._available_cache = {} if config['system']['single_dependency_checking'] else None
self.thread_prepare = None
self.i18n = context.i18n
self.disk_loader_factory = context.disk_loader_factory
self.logger = context.logger
self._already_prepared = []
self.working_managers = []
self.config = config
def reset_cache(self):
if self._available_cache is not None:
@@ -345,20 +342,22 @@ class GenericSoftwareManager(SoftwareManager):
suggestions.extend(man_sugs)
def list_suggestions(self, limit: int) -> List[PackageSuggestion]:
if self.managers and internet.is_available(self.context.http_client, self.context.logger):
suggestions, threads = [], []
for man in self.managers:
t = Thread(target=self._fill_suggestions, args=(suggestions, man, SUGGESTIONS_LIMIT))
t.start()
threads.append(t)
if bool(self.config['suggestions']['enabled']):
if self.managers and internet.is_available(self.context.http_client, self.context.logger):
suggestions, threads = [], []
for man in self.managers:
t = Thread(target=self._fill_suggestions, args=(suggestions, man, int(self.config['suggestions']['by_type'])))
t.start()
threads.append(t)
for t in threads:
t.join()
for t in threads:
t.join()
if suggestions:
suggestions.sort(key=lambda s: s.priority.value, reverse=True)
if suggestions:
suggestions.sort(key=lambda s: s.priority.value, reverse=True)
return suggestions
return suggestions
return []
def execute_custom_action(self, action: PackageAction, pkg: SoftwarePackage, root_password: str, watcher: ProcessWatcher):
man = self._get_manager_for(pkg)

View File

@@ -5,8 +5,7 @@ from typing import List
from bauh import ROOT_DIR
from bauh.api.abstract.controller import SoftwareManager, ApplicationContext
from bauh.view.core.config import Configuration
from bauh.view.util import util, translation
from bauh.view.util import translation
def find_manager(member):
@@ -20,7 +19,7 @@ def find_manager(member):
return manager_found
def load_managers(locale: str, context: ApplicationContext, config: Configuration, default_locale: str) -> List[SoftwareManager]:
def load_managers(locale: str, context: ApplicationContext, config: dict, default_locale: str) -> List[SoftwareManager]:
managers = []
for f in os.scandir(ROOT_DIR + '/gems'):
@@ -44,10 +43,10 @@ def load_managers(locale: str, context: ApplicationContext, config: Configuratio
man = manager_class(context=context)
if config.gems is None:
if config['gems'] is None:
man.set_enabled(man.is_default_enabled())
else:
man.set_enabled(f.name in config.gems)
man.set_enabled(f.name in config['gems'])
managers.append(man)

View File

@@ -4,7 +4,7 @@ from PyQt5.QtWidgets import QWidget, QLabel, QGridLayout, QPushButton
from bauh import ROOT_DIR
from bauh.api.abstract.view import MultipleSelectComponent, InputOption
from bauh.view.core.config import Configuration, save
from bauh.view.core.config import save
from bauh.view.core.controller import GenericSoftwareManager
from bauh.view.util import resource
from bauh.view.qt import qt_utils, css
@@ -14,7 +14,7 @@ from bauh.view.util.translation import I18n
class GemSelectorPanel(QWidget):
def __init__(self, window: QWidget, manager: GenericSoftwareManager, i18n: I18n, config: Configuration, show_panel_after_restart: bool = False):
def __init__(self, window: QWidget, manager: GenericSoftwareManager, i18n: I18n, config: dict, show_panel_after_restart: bool = False):
super(GemSelectorPanel, self).__init__()
self.window = window
self.manager = manager
@@ -57,8 +57,8 @@ class GemSelectorPanel(QWidget):
if m.is_enabled() and m in manager.working_managers:
default.add(op)
if self.config.enabled_gems:
default_ops = {o for o in gem_options if o.value in self.config.enabled_gems}
if self.config['gems']:
default_ops = {o for o in gem_options if o.value in self.config['gems']}
else:
default_ops = default
@@ -89,7 +89,7 @@ class GemSelectorPanel(QWidget):
enabled = module in enabled_gems
man.set_enabled(enabled)
self.config.enabled_gems = enabled_gems
self.config['gems'] = enabled_gems
save(self.config)
self.manager.reset_cache()

View File

@@ -35,7 +35,7 @@ class StylesComboBox(QComboBox):
style = self.styles[idx]
user_config = config.read_config()
user_config.style = style
user_config['ui']['style'] = style
config.save(user_config)
util.restart_app(self.show_panel_after_restart)

View File

@@ -36,13 +36,13 @@ class UpdateCheck(QThread):
class TrayIcon(QSystemTrayIcon):
def __init__(self, i18n: I18n, manager: SoftwareManager, manage_window: ManageWindow, check_interval: int = 60, update_notification: bool = True):
def __init__(self, i18n: I18n, manager: SoftwareManager, manage_window: ManageWindow, config: dict):
super(TrayIcon, self).__init__()
self.i18n = i18n
self.manager = manager
self.icon_default = QIcon(os.getenv('BAUH_TRAY_DEFAULT_ICON_PATH', resource.get_path('img/logo.png')))
self.icon_update = QIcon(os.getenv('BAUH_TRAY_UPDATES_ICON_PATH', resource.get_path('img/logo_update.png')))
self.icon_default = QIcon(config['ui']['tray']['default_icon'] or resource.get_path('img/logo.png'))
self.icon_update = QIcon(config['ui']['tray']['updates_icon'] or resource.get_path('img/logo_update.png'))
self.setIcon(self.icon_default)
self.menu = QMenu()
@@ -60,12 +60,12 @@ class TrayIcon(QSystemTrayIcon):
self.manage_window = None
self.dialog_about = None
self.check_thread = UpdateCheck(check_interval=check_interval, manager=self.manager)
self.check_thread = UpdateCheck(check_interval=int(config['updates']['check_interval']), manager=self.manager)
self.check_thread.signal.connect(self.notify_updates)
self.check_thread.start()
self.last_updates = set()
self.update_notification = update_notification
self.update_notification = bool(config['system']['notifications'])
self.lock_notify = Lock()
self.activated.connect(self.handle_click)

View File

@@ -17,7 +17,6 @@ from bauh.api.abstract.model import SoftwarePackage, PackageAction
from bauh.api.abstract.view import MessageType
from bauh.api.http import HttpClient
from bauh.commons.html import bold
from bauh.view.core.config import Configuration
from bauh.view.core.controller import GenericSoftwareManager
from bauh.view.qt import dialog, commons, qt_utils
from bauh.view.qt.about import AboutDialog
@@ -51,7 +50,7 @@ class ManageWindow(QWidget):
signal_user_res = pyqtSignal(bool)
signal_table_update = pyqtSignal()
def __init__(self, i18n: I18n, icon_cache: MemoryCache, manager: SoftwareManager, screen_size, config: Configuration,
def __init__(self, i18n: I18n, icon_cache: MemoryCache, manager: SoftwareManager, screen_size, config: dict,
context: ApplicationContext, http_client: HttpClient, logger: logging.Logger, tray_icon=None):
super(ManageWindow, self).__init__()
self.i18n = i18n
@@ -62,7 +61,7 @@ class ManageWindow(QWidget):
self.pkgs = [] # packages current loaded in the table
self.pkgs_available = [] # all packages loaded in memory
self.pkgs_installed = [] # cached installed packages
self.display_limit = config.max_displayed
self.display_limit = config['ui']['table']['max_displayed']
self.icon_cache = icon_cache
self.screen_size = screen_size
self.config = config
@@ -208,7 +207,9 @@ class ManageWindow(QWidget):
self.layout.addWidget(self.toolbar)
self.table_apps = AppsTable(self, self.icon_cache, disk_cache=self.config.disk_cache, download_icons=self.config.download_icons)
self.table_apps = AppsTable(self, self.icon_cache,
disk_cache=bool(self.config['disk_cache']['enabled']),
download_icons=bool(self.config['download']['icons']))
self.table_apps.change_headers_policy()
self.layout.addWidget(self.table_apps)
@@ -260,7 +261,7 @@ class ManageWindow(QWidget):
self.thread_apply_filters.signal_table.connect(self._update_table_and_upgrades)
self.signal_table_update.connect(self.thread_apply_filters.stop_waiting)
self.thread_install = InstallPackage(manager=self.manager, disk_cache=self.config.disk_cache, icon_cache=self.icon_cache, i18n=self.i18n)
self.thread_install = InstallPackage(manager=self.manager, disk_cache=bool(self.config['disk_cache']['enabled']), icon_cache=self.icon_cache, i18n=self.i18n)
self._bind_async_action(self.thread_install, finished_call=self._finish_install)
self.thread_animate_progress = AnimateProgress()
@@ -308,7 +309,7 @@ class ManageWindow(QWidget):
self.types_changed = False
self.dialog_about = None
self.first_refresh = config.suggestions
self.first_refresh = bool(config['suggestions']['enabled'])
self.thread_warnings = ListWarnings(man=manager, i18n=i18n)
self.thread_warnings.signal_warnings.connect(self._show_warnings)
@@ -533,6 +534,9 @@ class ManageWindow(QWidget):
only_pkg_type = len([p for p in self.pkgs if p.model.get_type() == pkgv.model.get_type()]) >= 2
self.recent_uninstall = True
self.refresh_apps(pkg_types={pkgv.model.__class__} if only_pkg_type else None)
if self.tray_icon:
self.tray_icon.verify_updates()
else:
if self._can_notify_user():
util.notify_user('{}: {}'.format(pkgv.model.name, self.i18n['notification.uninstall.failed']))
@@ -540,7 +544,7 @@ class ManageWindow(QWidget):
self.checkbox_console.setChecked(True)
def _can_notify_user(self):
return self.config.system_notifications and (self.isHidden() or self.isMinimized())
return bool(self.config['system']['notifications']) and (self.isHidden() or self.isMinimized())
def _finish_downgrade(self, res: dict):
self.finish_action()