diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bcdfaeb..9ab26ed7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Improvements - General - handling http redirect errors + - memory usage improvements when retrieving available custom actions - AppImage - not enabled for non-x86_64 systems diff --git a/bauh/api/abstract/controller.py b/bauh/api/abstract/controller.py index d270340c..31dfeab6 100644 --- a/bauh/api/abstract/controller.py +++ b/bauh/api/abstract/controller.py @@ -4,7 +4,7 @@ import shutil from abc import ABC, abstractmethod from enum import Enum from pathlib import Path -from typing import List, Set, Type, Tuple, Optional +from typing import List, Set, Type, Tuple, Optional, Generator import yaml @@ -382,11 +382,11 @@ class SoftwareManager(ABC): """ pass - def get_custom_actions(self) -> List[CustomSoftwareAction]: + def gen_custom_actions(self) -> Generator[CustomSoftwareAction, None, None]: """ - :return: custom actions + :return: generates available custom actions """ - pass + yield from () def fill_sizes(self, pkgs: List[SoftwarePackage]): pass diff --git a/bauh/gems/appimage/controller.py b/bauh/gems/appimage/controller.py index 12849d65..dbc2962d 100644 --- a/bauh/gems/appimage/controller.py +++ b/bauh/gems/appimage/controller.py @@ -9,7 +9,7 @@ import traceback from datetime import datetime from math import floor from pathlib import Path -from typing import Set, Type, List, Tuple, Optional +from typing import Set, Type, List, Tuple, Optional, Iterable, Generator from colorama import Fore from packaging.version import parse as parse_version @@ -78,7 +78,7 @@ class AppImageManager(SoftwareManager): self.logger = context.logger self.file_downloader = context.file_downloader self.configman = AppImageConfigManager() - self.custom_actions = [CustomSoftwareAction(i18n_label_key='appimage.custom_action.install_file', + self.custom_actions = (CustomSoftwareAction(i18n_label_key='appimage.custom_action.install_file', i18n_status_key='appimage.custom_action.install_file.status', manager=self, manager_method='install_file', @@ -90,7 +90,7 @@ class AppImageManager(SoftwareManager): manager_method='update_database', icon_path=resource.get_path('img/appimage.svg', ROOT_DIR), requires_root=False, - requires_internet=True)] + requires_internet=True)) self.custom_app_actions = [CustomSoftwareAction(i18n_label_key='appimage.custom_action.manual_update', i18n_status_key='appimage.custom_action.manual_update.status', manager_method='update_file', @@ -862,8 +862,9 @@ class AppImageManager(SoftwareManager): except: return False, [traceback.format_exc()] - def get_custom_actions(self) -> List[CustomSoftwareAction]: - return self.custom_actions + def gen_custom_actions(self) -> Generator[CustomSoftwareAction, None, None]: + for action in self.custom_actions: + yield action def get_upgrade_requirements(self, pkgs: List[AppImage], root_password: str, watcher: ProcessWatcher) -> UpgradeRequirements: to_update = [] diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 251f4a51..ba463ae6 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -12,7 +12,7 @@ from math import floor from pathlib import Path from pwd import getpwnam from threading import Thread -from typing import List, Set, Type, Tuple, Dict, Iterable, Optional, Collection +from typing import List, Set, Type, Tuple, Dict, Iterable, Optional, Collection, Generator import requests from dateutil.parser import parse as parse_date @@ -3040,24 +3040,20 @@ class ArchManager(SoftwareManager): except PackageNotFoundException: pass # when nothing is returned, the upgrade is called off by the UI - def get_custom_actions(self) -> List[CustomSoftwareAction]: - actions = [] - + def gen_custom_actions(self) -> Generator[CustomSoftwareAction, None, None]: arch_config = self.configman.get_config() if pacman.is_mirrors_available(): - actions.append(self.custom_actions['ref_mirrors']) + yield self.custom_actions['ref_mirrors'] - actions.append(self.custom_actions['ref_dbs']) - actions.append(self.custom_actions['clean_cache']) + yield self.custom_actions['ref_dbs'] + yield self.custom_actions['clean_cache'] if bool(arch_config['repositories']): - actions.append(self.custom_actions['sys_up']) + yield self.custom_actions['sys_up'] if pacman.is_snapd_installed(): - actions.append(self.custom_actions['setup_snapd']) - - return actions + yield self.custom_actions['setup_snapd'] def fill_sizes(self, pkgs: List[ArchPackage]): installed, new, all_names, installed_names = [], [], [], [] diff --git a/bauh/gems/web/controller.py b/bauh/gems/web/controller.py index d43f8193..3512ed6a 100644 --- a/bauh/gems/web/controller.py +++ b/bauh/gems/web/controller.py @@ -9,7 +9,7 @@ import traceback from math import floor from pathlib import Path from threading import Thread -from typing import List, Type, Set, Tuple, Optional, Dict +from typing import List, Type, Set, Tuple, Optional, Dict, Generator import requests import yaml @@ -74,7 +74,7 @@ class WebApplicationManager(SoftwareManager): self.suggestions = {} self.configman = WebConfigManager() self.idxman = SearchIndexManager(logger=context.logger) - self.custom_actions = [ + self.custom_actions = ( CustomSoftwareAction(i18n_label_key='web.custom_action.install_app', i18n_status_key='web.custom_action.install_app.status', manager=self, @@ -89,7 +89,7 @@ class WebApplicationManager(SoftwareManager): icon_path=resource.get_path('img/web.svg', ROOT_DIR), requires_root=False, refresh=False) - ] + ) def _get_lang_header(self) -> str: try: @@ -1170,5 +1170,6 @@ class WebApplicationManager(SoftwareManager): except: return False, [traceback.format_exc()] - def get_custom_actions(self) -> List[CustomSoftwareAction]: - return self.custom_actions + def gen_custom_actions(self) -> Generator[CustomSoftwareAction, None, None]: + for action in self.custom_actions: + yield action diff --git a/bauh/view/core/controller.py b/bauh/view/core/controller.py index ac889b10..1842345c 100755 --- a/bauh/view/core/controller.py +++ b/bauh/view/core/controller.py @@ -4,7 +4,7 @@ import time import traceback from subprocess import Popen, STDOUT from threading import Thread -from typing import List, Set, Type, Tuple, Dict, Optional +from typing import List, Set, Type, Tuple, Dict, Optional, Generator, Callable from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext, UpgradeRequirements, \ UpgradeRequirement, TransactionResult, SoftwareAction @@ -54,20 +54,21 @@ class GenericSoftwareManager(SoftwareManager): self.settings_manager = settings_manager self.http_client = context.http_client self.configman = CoreConfigManager() - self.extra_actions = [CustomSoftwareAction(i18n_label_key='action.reset', + self.extra_actions = (CustomSoftwareAction(i18n_label_key='action.reset', i18n_status_key='action.reset.status', manager_method='reset', manager=self, icon_path=resource.get_path('img/logo.svg'), requires_root=False, - refresh=False)] - self.dynamic_extra_actions = {CustomSoftwareAction(i18n_label_key='action.backups', - i18n_status_key='action.backups.status', - manager_method='launch_timeshift', - manager=self, - icon_path='timeshift', - requires_root=False, - refresh=False): self.is_backups_action_available} + refresh=False),) + self.dynamic_extra_actions: Dict[CustomSoftwareAction, Callable[[dict], bool]] = { + CustomSoftwareAction(i18n_label_key='action.backups', + i18n_status_key='action.backups.status', + manager_method='launch_timeshift', + manager=self, + icon_path='timeshift', + requires_root=False, + refresh=False): self.is_backups_action_available} def _is_timeshift_launcher_available(self) -> bool: return bool(shutil.which('timeshift-launcher')) @@ -611,8 +612,7 @@ class GenericSoftwareManager(SoftwareManager): return True - def get_custom_actions(self) -> List[CustomSoftwareAction]: - actions = [] + def gen_custom_actions(self) -> Generator[CustomSoftwareAction, None, None]: if self.managers: working_managers = [] @@ -624,20 +624,17 @@ class GenericSoftwareManager(SoftwareManager): working_managers.sort(key=lambda m: m.__class__.__name__) for man in working_managers: - man_actions = man.get_custom_actions() - - if man_actions: - actions.extend(man_actions) + for action in man.gen_custom_actions(): + yield action app_config = self.configman.get_config() for action, available in self.dynamic_extra_actions.items(): if available(app_config): - actions.append(action) + yield action - actions.extend(self.extra_actions) - - return actions + for action in self.extra_actions: + yield action def _fill_sizes(self, man: SoftwareManager, pkgs: List[SoftwarePackage]): ti = time.time() diff --git a/bauh/view/qt/window.py b/bauh/view/qt/window.py index f7268e57..babc10f7 100755 --- a/bauh/view/qt/window.py +++ b/bauh/view/qt/window.py @@ -373,7 +373,7 @@ class ManageWindow(QWidget): self.container_bottom.layout().addWidget(bt_themes) self.comp_manager.register_component(BT_THEMES, bt_themes) - self.custom_actions = manager.get_custom_actions() + self.custom_actions = [a for a in manager.gen_custom_actions()] bt_custom_actions = IconButton(action=self.show_custom_actions, i18n=self.i18n, tooltip=self.i18n['manage_window.bt_custom_actions.tip']) @@ -460,7 +460,7 @@ class ManageWindow(QWidget): self.comp_manager.register_group(GROUP_LOWER_BTS, False, BT_SUGGESTIONS, BT_THEMES, BT_CUSTOM_ACTIONS, BT_SETTINGS, BT_ABOUT) def update_custom_actions(self): - self.custom_actions = self.manager.get_custom_actions() + self.custom_actions = [a for a in self.manager.gen_custom_actions()] def _update_process_progress(self, val: int): if self.progress_controll_enabled: