[debian] initial Debian package management support

This commit is contained in:
Vinicius Moreira
2022-03-10 17:11:19 -03:00
parent 9d88355b5c
commit f6c8ad9553
70 changed files with 4011 additions and 45 deletions

140
bauh/gems/debian/gui.py Normal file
View File

@@ -0,0 +1,140 @@
from operator import attrgetter
from typing import Collection, Optional, Tuple, List
from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.view import InputOption, MultipleSelectComponent, TextComponent
from bauh.commons.html import bold
from bauh.commons.system import get_human_size_str
from bauh.gems.debian import DEBIAN_ICON_PATH
from bauh.gems.debian.model import DebianPackage
from bauh.view.util.translation import I18n
class DebianViewBridge:
def __init__(self, screen_width: int, screen_heigth: int, i18n: I18n):
self._i18n = i18n
self._width = screen_width
self._height = screen_heigth
def _map_to_install(self, pkgs: Optional[Collection[DebianPackage]]) -> Optional[Tuple[List[InputOption], str, str]]:
if pkgs:
download_size, install_size = 0, 0
views = []
for p in pkgs:
if p.compressed_size is not None and p.compressed_size >= 0:
compressed = get_human_size_str(p.compressed_size)
download_size += p.compressed_size
else:
compressed = '?'
if p.transaction_size is not None:
install_size += p.transaction_size
uncompressed = get_human_size_str(p.transaction_size)
else:
uncompressed = '?'
views.append(InputOption(label=f"{p.name} ({compressed} | {uncompressed})",
value=p.name, read_only=True, icon_path=DEBIAN_ICON_PATH,
tooltip=p.description if p.description else '?'))
dsize = get_human_size_str(download_size) if download_size > 0 else '?'
isize = get_human_size_str(install_size) if install_size > 0 else '?'
return views, dsize, isize
def _map_to_remove(self, pkgs: Optional[Collection[DebianPackage]]) -> Optional[Tuple[List[InputOption], str]]:
if pkgs:
freed_space = 0
views = []
for p in pkgs:
if p.transaction_size is not None:
size = p.transaction_size * (-1 if p.transaction_size < 0 else 1)
freed_space += size
uncompressed = get_human_size_str(size)
else:
uncompressed = '?'
views.append(InputOption(label=f"{p.name} (-{uncompressed})",
value=p.name, read_only=True, icon_path=DEBIAN_ICON_PATH,
tooltip=p.description if p.description else '?'))
return views, f'-{get_human_size_str(freed_space)}' if freed_space > 0 else '?'
def confirm_transaction(self, to_install: Optional[Collection[DebianPackage]],
removal: Optional[Collection[DebianPackage]],
watcher: ProcessWatcher) -> bool:
components = []
to_remove_data = self._map_to_remove(removal)
text_width, select_width = 672, 595
if to_remove_data:
to_remove_data[0].sort(key=attrgetter('label'))
lb_rem = self._i18n['debian.transaction.to_remove'].format(no=bold(str(len(to_remove_data[0]))),
fspace=bold(to_remove_data[1]))
components.append(TextComponent(html=lb_rem, min_width=text_width))
components.append(MultipleSelectComponent(id_='rem', options=to_remove_data[0], label=None,
default_options={*to_remove_data[0]},
max_width=select_width))
to_install_data = self._map_to_install(to_install)
if to_install_data:
to_install_data[0].sort(key=attrgetter('label'))
lb_deps = self._i18n['debian.transaction.to_install'].format(no=bold(str(len(to_install_data[0]))),
dsize=bold(to_install_data[1]),
isize=bold(to_install_data[2]))
components.append(TextComponent(html=f'<br/>{lb_deps}', min_width=text_width))
components.append(MultipleSelectComponent(id_='inst', label='', options=to_install_data[0],
default_options={*to_install_data[0]},
max_width=select_width))
return watcher.request_confirmation(title=self._i18n['debian.transaction.title'],
components=components,
confirmation_label=self._i18n['popup.button.continue'],
deny_label=self._i18n['popup.button.cancel'],
body=None,
min_width=text_width,
min_height=54)
def confirm_removal(self, source_pkg: str, dependencies: Collection[DebianPackage], watcher: ProcessWatcher) -> bool:
dep_views = []
freed_space = 0
for p in sorted(dependencies, key=attrgetter('name')):
if p.transaction_size is not None:
size = p.transaction_size * (-1 if p.transaction_size < 0 else 1)
freed_space += size
size_str = get_human_size_str(size)
else:
size_str = '?'
dep_views.append(InputOption(label=f"{p.name}: -{size_str}", value=p.name, read_only=True,
icon_path=DEBIAN_ICON_PATH, tooltip=p.description))
deps_container = MultipleSelectComponent(id_='deps', label='', options=dep_views, default_options={*dep_views},
max_width=537)
freed_space_str = bold('-' + get_human_size_str(freed_space))
body_text = TextComponent(html=self._i18n['debian.remove_deps'].format(no=bold(str(len(dependencies))),
pkg=bold(source_pkg),
fspace=freed_space_str),
min_width=653)
return watcher.request_confirmation(title=self._i18n['debian.transaction.title'],
components=[body_text, deps_container],
confirmation_label=self._i18n['popup.button.continue'],
deny_label=self._i18n['popup.button.cancel'],
body=None)
def confirm_purge(self, pkg_name: str, watcher: ProcessWatcher) -> bool:
msg = self._i18n['debian.action.purge.confirmation'].format(pkg=bold(pkg_name))
return watcher.request_confirmation(title=self._i18n['debian.action.purge'],
body=msg,
confirmation_label=self._i18n['popup.button.continue'])