Skip to content

Commit

Permalink
0.10.2
Browse files Browse the repository at this point in the history
  • Loading branch information
vinifmor authored Apr 16, 2022
2 parents fae6785 + 4702148 commit d1ddacc
Show file tree
Hide file tree
Showing 67 changed files with 1,606 additions and 1,025 deletions.
66 changes: 66 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,72 @@ 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/).

## [0.10.2] 2022-04-16
### Improvements
- Arch
- install:
- missing dependencies dialog now displays the packages sizes and descriptions (only from repositories)
- optional packages installation dialog appearance (aligned with other dependencies dialogs)
- uninstall:
- displaying hard and unnecessary requirements versions and descriptions
- settings:
- displaying different tabs for general Arch configurations and AUR's

<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.10.2/arch_aur_tabs.png">
</p>

- Debian
- install: installation/download sizes order (to follow the upgrade dialog order)
- uninstall: dependencies dialog size
- settings: new property to enable "purge" as the default removal method

<p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.10.2/debian_purge_opt.png">
</p>

- Flatpak
- faster updates reading (threaded)

- General
- code refactoring

- UI
- update summary:
- displaying a '+' for positive sizes (previously the sign was only displayed for negative numbers) [#250](https://github.com/vinifmor/bauh/issues/250)
- changing some words and symbols to improve readability and cohesion [#250](https://github.com/vinifmor/bauh/issues/250)
- displaying update sizes as localized numbers [#250](https://github.com/vinifmor/bauh/issues/250)
- settings: some components' width reduced

- Web
- installation form width


### Fixes
- Arch:
- displaying already installed packages when suggesting optional dependencies (pacman >= 6.0)

- Debian
- install/upgrade: hanging when packages require manual configuration
- info: crashing when the package size has unexpected symbols [#251](https://github.com/vinifmor/bauh/issues/251)
- displaying wrong symbols among numbers in install/uninstall/upgrade outputs for systems without english encoding installed
- removing unused packages on any type of transaction (this is the default behaviour for aptitude)

- Flatpak
- some updates or download sizes not being displayed when there are new required runtimes for installed Flatpaks
- not displaying new required runtimes as updates (requires Flatpak >= 1.12)
- upgrade: informing the download size as the additional installation size
- random index out of bounds exception when reading updates

- General
- not properly converting bibyte (KiB, MiB, ...) and byte (kB, MB, ...) based sizes to bytes
- uninstall and downgrade logs are not available [#255](https://github.com/vinifmor/bauh/issues/255)

- UI
- not displaying the right unit symbol for byte based sizes (kB, MB, TB, ...) [#250](https://github.com/vinifmor/bauh/issues/250)
- some components do not properly adjust the text size [#253](https://github.com/vinifmor/bauh/issues/253)


## [0.10.1] 2022-03-31

### Features
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ prefer_repository_provider: true # when there is just one repository provider f
- `sync_pkgs.time`: time period (**in minutes**) in which the packages synchronization must be done on startup (default: `1440` -> 24 hours)
- `suggestions.exp`: it defines the period (**in hours**) in which the suggestions stored in disc will be considered up to date. Use 0 if you always want to update them.
- `pkg_sources.app`: it defines the application for managing the software sources. A `null` value detects one of the supported applications automatically.
- `remove.purge`: if the package configurations should be removed during the uninstallation process (purge). Default: false.

##### <a name="type_flatpak">Flatpak</a>

Expand Down
2 changes: 1 addition & 1 deletion bauh/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '0.10.1'
__version__ = '0.10.2'
__app_name__ = 'bauh'

import os
Expand Down
40 changes: 27 additions & 13 deletions bauh/api/abstract/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __hash__(self):

class UpgradeRequirement:

def __init__(self, pkg: SoftwarePackage, reason: str = None, required_size: int = None, extra_size: int = None, sorting_priority: int = 0):
def __init__(self, pkg: SoftwarePackage, reason: str = None, required_size: float = None, extra_size: float = None, sorting_priority: int = 0):
"""
:param pkg:
Expand Down Expand Up @@ -119,6 +119,29 @@ class SoftwareAction(Enum):
DOWNGRADE = 5


class SettingsController(ABC):

def save_settings(self, component: ViewComponent) -> Tuple[bool, Optional[List[str]]]:
"""
:return: a tuple with a bool informing if the settings were saved and a list of error messages
"""
pass


class SettingsView:

def __init__(self, controller: SettingsController, component: ViewComponent, label: Optional[str] = None,
icon_path: Optional[str] = None):

self.controller = controller
self.component = component
self.label = label
self.icon_path = icon_path

def save(self) -> Tuple[bool, Optional[List[str]]]:
return self.controller.save_settings(self.component)


class SoftwareManager(ABC):

"""
Expand Down Expand Up @@ -337,8 +360,7 @@ def list_warnings(self, internet_available: bool) -> Optional[List[str]]:
"""
pass

@abstractmethod
def list_suggestions(self, limit: int, filter_installed: bool) -> List[PackageSuggestion]:
def list_suggestions(self, limit: int, filter_installed: bool) -> Optional[List[PackageSuggestion]]:
"""
:param limit: max suggestions to be returned. If limit < 0, it should not be considered
:param filter_installed: if the installed suggestions should not be retrieved
Expand Down Expand Up @@ -379,17 +401,9 @@ def clear_data(self, logs: bool = True):
"""
pass

def get_settings(self, screen_width: int, screen_height: int) -> Optional[ViewComponent]:
"""
:param screen_width
:param screen_height
:return: a form abstraction with all available settings
"""
pass

def save_settings(self, component: ViewComponent) -> Tuple[bool, Optional[List[str]]]:
def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
"""
:return: a tuple with a bool informing if the settings were saved and a list of error messages
:return: panel abstractions with optional icon paths associated with
"""
pass

Expand Down
127 changes: 60 additions & 67 deletions bauh/api/abstract/view.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from abc import ABC
from enum import Enum
from typing import List, Set, Optional, Dict
from typing import List, Set, Optional, Dict, TypeVar, Type, Union, Tuple


class MessageType(Enum):
Expand All @@ -27,6 +27,42 @@ def add_observer(self, obs):
self.observers.append(obs)


V = TypeVar('V', bound=ViewComponent)


class ViewContainer(ViewComponent, ABC):
"""
Represents a GUI component composed by other components
"""

def __init__(self, components: Union[List[V], Tuple[V]],
id_: Optional[str] = None,
observers: Optional[List[ViewObserver]] = None):
super(ViewContainer, self).__init__(id_=id_, observers=observers)
self.components = components
self.component_map = {c.id: c for c in components if c.id is not None} if components else None

def get_component(self, id_: str, type_: Type[V] = ViewComponent) -> Optional[V]:
if self.component_map:
instance = self.component_map.get(id_)

if instance:
if isinstance(instance, type_):
return instance

raise Exception(f"The {ViewComponent.__class__.__name__} (id={id_}) is not an "
f"instance of '{type_.__name__}'")

def get_component_by_idx(self, idx: int, type_: Type[V]) -> Optional[V]:
if self.components and idx < len(self.components):
c = self.components[idx]
if isinstance(c, type_):
return c

raise Exception(f"The {ViewComponent.__class__.__name__} at index {idx} is not an "
f"instance of '{type_.__name__}'")


class SpacerComponent(ViewComponent):

def __init__(self):
Expand All @@ -35,7 +71,7 @@ def __init__(self):

class InputViewComponent(ViewComponent):
"""
Represents an component which needs a user interaction to provide its value
Represents a component which needs a user interaction to provide its value
"""


Expand Down Expand Up @@ -104,7 +140,8 @@ class MultipleSelectComponent(InputViewComponent):

def __init__(self, label: Optional[str], options: List[InputOption], default_options: Set[InputOption] = None,
max_per_line: int = 1, tooltip: str = None, spaces: bool = True, max_width: int = -1,
max_height: int = -1, id_: str = None, min_width: Optional[int] = None):
max_height: int = -1, id_: str = None, min_width: Optional[int] = None,
opt_max_width: Optional[int] = None):
super(MultipleSelectComponent, self).__init__(id_=id_)

if not options:
Expand All @@ -119,6 +156,7 @@ def __init__(self, label: Optional[str], options: List[InputOption], default_opt
self.min_width = min_width
self.max_width = max_width
self.max_height = max_height
self.opt_max_width = opt_max_width

def get_selected_values(self) -> list:
selected = []
Expand Down Expand Up @@ -202,45 +240,15 @@ def get_label(self) -> str:
return self.label.capitalize() if self.capitalize_label else self.label


class FormComponent(ViewComponent):
class FormComponent(ViewContainer):

def __init__(self, components: List[ViewComponent], label: str = None, spaces: bool = True, id_: str = None,
min_width: Optional[int] = None):
super(FormComponent, self).__init__(id_=id_)
super(FormComponent, self).__init__(id_=id_, components=components)
self.label = label
self.spaces = spaces
self.components = components
self.component_map = {c.id: c for c in components if c.id} if components else None
self.min_width = min_width

def get_component(self, id_: str) -> Optional[ViewComponent]:
if self.component_map:
return self.component_map.get(id_)

def get_single_select_component(self, id_: str) -> Optional[SingleSelectComponent]:
comp = self.get_component(id_)

if comp:
if not isinstance(comp, SingleSelectComponent):
raise Exception("'{}' is not a {}".format(id_, SingleSelectComponent.__class__.__name__))
return comp

def get_form_component(self, id_: str) -> Optional["FormComponent"]:
comp = self.get_component(id_)

if comp:
if not isinstance(comp, FormComponent):
raise Exception("'{}' is not a {}".format(id_, FormComponent.__class__.__name__))
return comp

def get_text_input(self, id_) -> Optional[TextInputComponent]:
comp = self.get_component(id_)

if comp:
if not isinstance(comp, TextInputComponent):
raise Exception("'{}' is not a {}".format(id_, TextInputComponent.__class__.__name__))
return comp


class FileChooserComponent(ViewComponent):

Expand Down Expand Up @@ -276,20 +284,27 @@ class TabComponent(ViewComponent):
def __init__(self, label: str, content: ViewComponent, icon_path: str = None, id_: str = None):
super(TabComponent, self).__init__(id_=id_)
self.label = label
self.content = content
self._content = content
self.icon_path = icon_path

def get_content(self, type_: Type[V] = ViewComponent) -> V:
if isinstance(self._content, type_):
return self._content

raise Exception(f"'content' is not an instance of '{type_.__name__}'")

class TabGroupComponent(ViewComponent):

class TabGroupComponent(ViewContainer):

def __init__(self, tabs: List[TabComponent], id_: str = None):
super(TabGroupComponent, self).__init__(id_=id_)
self.tabs = tabs
self.tab_map = {c.id: c for c in tabs if c.id} if tabs else None
super(TabGroupComponent, self).__init__(id_=id_, components=tabs)

def get_tab(self, id_: str) -> Optional[TabComponent]:
return self.get_component(id_, TabComponent)

def get_tab(self, id_: str) -> TabComponent:
if self.tab_map:
return self.tab_map.get(id_)
@property
def tabs(self) -> List[TabComponent]:
return self.components


class RangeInputComponent(InputViewComponent):
Expand All @@ -306,29 +321,7 @@ def __init__(self, id_: str, label: str, tooltip: str, min_value: int, max_value
self.max_width = max_width


class PanelComponent(ViewComponent):
class PanelComponent(ViewContainer):

def __init__(self, components: List[ViewComponent], id_: str = None):
super(PanelComponent, self).__init__(id_=id_)
self.components = components
self.component_map = {c.id: c for c in components if c.id is not None} if components else None

def get_component(self, id_: str) -> Optional[ViewComponent]:
if self.component_map:
return self.component_map.get(id_)

def get_form_component(self, id_: str) -> Optional[FormComponent]:
comp = self.get_component(id_)

if comp:
if not isinstance(comp, FormComponent):
raise Exception("'{}' is not a {}".format(id_, FormComponent.__class__.__name__))
return comp

def get_text_input(self, id_) -> Optional[TextInputComponent]:
comp = self.get_component(id_)

if comp:
if not isinstance(comp, TextInputComponent):
raise Exception("'{}' is not a {}".format(id_, TextInputComponent.__class__.__name__))
return comp
super(PanelComponent, self).__init__(id_=id_, components=components)
7 changes: 7 additions & 0 deletions bauh/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import faulthandler
import locale
import os
import sys
import traceback
Expand All @@ -25,6 +26,12 @@ def main(tray: bool = False):

logger = logs.new_logger(__app_name__, bool(args.logs))

try:
locale.setlocale(locale.LC_NUMERIC, '')
except:
logger.error("Could not set locale 'LC_NUMBERIC' to '' to display localized numbers")
traceback.print_exc()

if args.offline:
logger.warning("offline mode activated")

Expand Down
Loading

0 comments on commit d1ddacc

Please sign in to comment.