mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-09 05:14:16 +02:00
[improvement][ui] uninstallation does not refresh the table if it succeeds
This commit is contained in:
@@ -285,20 +285,43 @@ class GenericSoftwareManager(SoftwareManager):
|
||||
|
||||
return True
|
||||
|
||||
def uninstall(self, app: SoftwarePackage, root_password: str, handler: ProcessWatcher) -> bool:
|
||||
man = self._get_manager_for(app)
|
||||
|
||||
if man:
|
||||
return man.uninstall(app, root_password, handler)
|
||||
|
||||
def _fill_post_transaction_status(self, pkg: SoftwarePackage, installed: bool):
|
||||
pkg.installed = installed
|
||||
|
||||
pkg.update = False
|
||||
|
||||
if pkg.latest_version:
|
||||
pkg.version = pkg.latest_version
|
||||
|
||||
def _update_post_transaction_status(self, res: TransactionResult):
|
||||
if res.success:
|
||||
if res.installed:
|
||||
for p in res.installed:
|
||||
self._fill_post_transaction_status(p, True)
|
||||
if res.removed:
|
||||
for p in res.removed:
|
||||
self._fill_post_transaction_status(p, False)
|
||||
|
||||
def uninstall(self, pkg: SoftwarePackage, root_password: str, handler: ProcessWatcher, disk_loader: DiskCacheLoader = None) -> TransactionResult:
|
||||
man = self._get_manager_for(pkg)
|
||||
|
||||
if man:
|
||||
ti = time.time()
|
||||
disk_loader = self.disk_loader_factory.new()
|
||||
disk_loader.start()
|
||||
self.logger.info("Uninstalling {}".format(pkg.name))
|
||||
try:
|
||||
res = man.uninstall(pkg, root_password, handler, disk_loader)
|
||||
disk_loader.stop_working()
|
||||
disk_loader.join()
|
||||
self._update_post_transaction_status(res)
|
||||
return res
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return TransactionResult(success=False, installed=[], removed=[])
|
||||
finally:
|
||||
tf = time.time()
|
||||
self.logger.info('Uninstallation of {}'.format(pkg) + 'took {0:.2f} minutes'.format((tf - ti) / 60))
|
||||
|
||||
def install(self, app: SoftwarePackage, root_password: str, disk_loader: DiskCacheLoader, handler: ProcessWatcher) -> TransactionResult:
|
||||
man = self._get_manager_for(app)
|
||||
|
||||
@@ -311,15 +334,7 @@ class GenericSoftwareManager(SoftwareManager):
|
||||
res = man.install(app, root_password, disk_loader, handler)
|
||||
disk_loader.stop_working()
|
||||
disk_loader.join()
|
||||
|
||||
if res.success:
|
||||
if res.installed:
|
||||
for p in res.installed:
|
||||
self._fill_post_transaction_status(p, True)
|
||||
if res.removed:
|
||||
for p in res.removed:
|
||||
self._fill_post_transaction_status(p, False)
|
||||
|
||||
self._update_post_transaction_status(res)
|
||||
return res
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -194,11 +194,11 @@ class AppsTable(QTableWidget):
|
||||
|
||||
self._update_row(pkg, change_update_col=change_update_col)
|
||||
|
||||
def _uninstall_app(self, app_v: PackageView):
|
||||
def _uninstall(self, pkg: PackageView):
|
||||
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(pkg)))),
|
||||
i18n=self.i18n):
|
||||
self.window.uninstall_app(app_v)
|
||||
self.window.uninstall_package(pkg)
|
||||
|
||||
def _bold(self, text: str) -> str:
|
||||
return '<span style="font-weight: bold">{}</span>'.format(text)
|
||||
@@ -284,7 +284,7 @@ class AppsTable(QTableWidget):
|
||||
if change_update_col:
|
||||
col_update = None
|
||||
|
||||
if update_check_enabled and not pkg.model.is_update_ignored() and pkg.model.update:
|
||||
if update_check_enabled and pkg.model.installed and not pkg.model.is_update_ignored() and pkg.model.update:
|
||||
col_update = QToolBar()
|
||||
col_update.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
col_update.addWidget(UpdateToggleButton(pkg=pkg,
|
||||
@@ -323,7 +323,7 @@ class AppsTable(QTableWidget):
|
||||
if pkg.model.installed:
|
||||
if pkg.model.can_be_uninstalled():
|
||||
def uninstall():
|
||||
self._uninstall_app(pkg)
|
||||
self._uninstall(pkg)
|
||||
|
||||
style = 'color: {c}; font-size: 10px; font-weight: bold;'.format(c=BROWN)
|
||||
item = self._gen_row_button(self.i18n['uninstall'].capitalize(), style, uninstall)
|
||||
@@ -408,7 +408,7 @@ class AppsTable(QTableWidget):
|
||||
item.setText(name)
|
||||
|
||||
icon_path = pkg.model.get_disk_icon_path()
|
||||
if pkg.model.supports_disk_cache() and icon_path:
|
||||
if pkg.model.installed and pkg.model.supports_disk_cache() and icon_path:
|
||||
if icon_path.startswith('/') and os.path.isfile(icon_path):
|
||||
with open(icon_path, 'rb') as f:
|
||||
icon_bytes = f.read()
|
||||
|
||||
@@ -496,34 +496,42 @@ class RefreshApps(AsyncAction):
|
||||
self.pkg_types = None
|
||||
|
||||
|
||||
class UninstallApp(AsyncAction):
|
||||
class UninstallPackage(AsyncAction):
|
||||
|
||||
def __init__(self, manager: SoftwareManager, icon_cache: MemoryCache, i18n: I18n, app: PackageView = None):
|
||||
super(UninstallApp, self).__init__()
|
||||
self.app = app
|
||||
def __init__(self, manager: SoftwareManager, icon_cache: MemoryCache, i18n: I18n, pkg: PackageView = None):
|
||||
super(UninstallPackage, self).__init__()
|
||||
self.pkg = pkg
|
||||
self.manager = manager
|
||||
self.icon_cache = icon_cache
|
||||
self.root_pwd = None
|
||||
self.i18n = i18n
|
||||
|
||||
def run(self):
|
||||
if self.app:
|
||||
if self.app.model.supports_backup():
|
||||
if self.pkg:
|
||||
if self.pkg.model.supports_backup():
|
||||
if not self.request_backup(read_config(), 'uninstall', self.i18n, self.root_pwd):
|
||||
self.notify_finished(False)
|
||||
self.app = None
|
||||
self.pkg = None
|
||||
self.root_pwd = None
|
||||
return
|
||||
|
||||
success = self.manager.uninstall(self.app.model, self.root_pwd, self)
|
||||
try:
|
||||
res = self.manager.uninstall(self.pkg.model, self.root_pwd, self, None)
|
||||
|
||||
if success:
|
||||
self.icon_cache.delete(self.app.model.icon_url)
|
||||
self.manager.clean_cache_for(self.app.model)
|
||||
if res.success and res.removed:
|
||||
for p in res.removed:
|
||||
if p.icon_url:
|
||||
self.icon_cache.delete(p.icon_url)
|
||||
|
||||
self.notify_finished(self.app if success else None)
|
||||
self.app = None
|
||||
self.root_pwd = None
|
||||
self.manager.clean_cache_for(p)
|
||||
|
||||
self.notify_finished({'success': res.success, 'removed': res.removed, 'pkg': self.pkg})
|
||||
except:
|
||||
traceback.print_exc()
|
||||
self.notify_finished({'success': False, 'removed': None, 'pkg': self.pkg})
|
||||
finally:
|
||||
self.pkg = None
|
||||
self.root_pwd = None
|
||||
|
||||
|
||||
class DowngradeApp(AsyncAction):
|
||||
|
||||
@@ -32,7 +32,7 @@ from bauh.view.qt.info import InfoDialog
|
||||
from bauh.view.qt.root import ask_root_password
|
||||
from bauh.view.qt.screenshots import ScreenshotsDialog
|
||||
from bauh.view.qt.settings import SettingsWindow
|
||||
from bauh.view.qt.thread import UpgradeSelected, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \
|
||||
from bauh.view.qt.thread import UpgradeSelected, RefreshApps, UninstallPackage, DowngradeApp, GetAppInfo, \
|
||||
GetAppHistory, SearchPackages, InstallPackage, AnimateProgress, NotifyPackagesReady, FindSuggestions, \
|
||||
ListWarnings, \
|
||||
AsyncAction, LaunchApp, ApplyFilters, CustomSoftwareAction, GetScreenshots, CustomAction, NotifyInstalledLoaded, \
|
||||
@@ -303,7 +303,7 @@ class ManageWindow(QWidget):
|
||||
|
||||
self.thread_update = self._bind_async_action(UpgradeSelected(self.manager, self.i18n), finished_call=self._finish_upgrade_selected)
|
||||
self.thread_refresh = self._bind_async_action(RefreshApps(self.manager), finished_call=self._finish_refresh_apps, only_finished=True)
|
||||
self.thread_uninstall = self._bind_async_action(UninstallApp(self.manager, self.icon_cache, self.i18n), finished_call=self._finish_uninstall)
|
||||
self.thread_uninstall = self._bind_async_action(UninstallPackage(self.manager, self.icon_cache, self.i18n), finished_call=self._finish_uninstall)
|
||||
self.thread_get_info = self._bind_async_action(GetAppInfo(self.manager), finished_call=self._finish_get_info)
|
||||
self.thread_get_history = self._bind_async_action(GetAppHistory(self.manager, self.i18n), finished_call=self._finish_get_history)
|
||||
self.thread_search = self._bind_async_action(SearchPackages(self.manager), finished_call=self._finish_search, only_finished=True)
|
||||
@@ -520,7 +520,7 @@ class ManageWindow(QWidget):
|
||||
self.ref_checkbox_only_apps.setVisible(True)
|
||||
self.input_search.setText('')
|
||||
self.input_name_filter.setText('')
|
||||
self._begin_action(self.i18n['manage_window.status.installed'], keep_bt_installed=False, clear_filters=not self.recent_uninstall)
|
||||
self._begin_action(self.i18n['manage_window.status.installed'], keep_bt_installed=False)
|
||||
self.thread_load_installed.start()
|
||||
|
||||
def _finish_loading_installed(self):
|
||||
@@ -606,7 +606,7 @@ class ManageWindow(QWidget):
|
||||
|
||||
self.ref_checkbox_updates.setVisible(False)
|
||||
self.ref_checkbox_only_apps.setVisible(False)
|
||||
self._begin_action(self.i18n['manage_window.status.refreshing'], keep_bt_installed=False, clear_filters=not self.recent_uninstall)
|
||||
self._begin_action(self.i18n['manage_window.status.refreshing'], keep_bt_installed=False)
|
||||
|
||||
self.thread_refresh.pkg_types = pkg_types
|
||||
self.thread_refresh.start()
|
||||
@@ -616,7 +616,7 @@ class ManageWindow(QWidget):
|
||||
self._handle_console_option(False)
|
||||
self.ref_checkbox_updates.setVisible(False)
|
||||
self.ref_checkbox_only_apps.setVisible(False)
|
||||
self._begin_action(self.i18n['manage_window.status.suggestions'], keep_bt_installed=False, clear_filters=not self.recent_uninstall)
|
||||
self._begin_action(self.i18n['manage_window.status.suggestions'], keep_bt_installed=False)
|
||||
self.thread_suggestions.filter_installed = True
|
||||
self.thread_suggestions.start()
|
||||
|
||||
@@ -626,21 +626,20 @@ class ManageWindow(QWidget):
|
||||
|
||||
self.ref_checkbox_only_apps.setVisible(bool(res['installed']))
|
||||
self.ref_bt_upgrade.setVisible(True)
|
||||
self.update_pkgs(res['installed'], as_installed=as_installed, types=res['types'], keep_filters=self.recent_uninstall and res['types'])
|
||||
self.update_pkgs(res['installed'], as_installed=as_installed, types=res['types'])
|
||||
self.load_suggestions = False
|
||||
self.recent_uninstall = False
|
||||
self.types_changed = False
|
||||
|
||||
def uninstall_app(self, app: PackageView):
|
||||
pwd, proceed = self._ask_root_password('uninstall', app)
|
||||
def uninstall_package(self, pkg: PackageView):
|
||||
pwd, proceed = self._ask_root_password('uninstall', pkg)
|
||||
|
||||
if not proceed:
|
||||
return
|
||||
|
||||
self._handle_console_option(True)
|
||||
self._begin_action('{} {}'.format(self.i18n['manage_window.status.uninstalling'], app.model.name), clear_filters=False)
|
||||
self._begin_action('{} {}'.format(self.i18n['manage_window.status.uninstalling'], pkg.model.name), clear_filters=False)
|
||||
|
||||
self.thread_uninstall.app = app
|
||||
self.thread_uninstall.pkg = pkg
|
||||
self.thread_uninstall.root_pwd = pwd
|
||||
self.thread_uninstall.start()
|
||||
|
||||
@@ -649,29 +648,64 @@ class ManageWindow(QWidget):
|
||||
self.thread_run_app.app = app
|
||||
self.thread_run_app.start()
|
||||
|
||||
def _finish_uninstall(self, pkgv: PackageView):
|
||||
self.finish_action()
|
||||
def _finish_uninstall(self, res: dict):
|
||||
self.finish_action(keep_filters=True)
|
||||
|
||||
if pkgv:
|
||||
if res['success']:
|
||||
src_pkg = res['pkg']
|
||||
if self._can_notify_user():
|
||||
util.notify_user('{} ({}) {}'.format(pkgv.model.name, pkgv.model.get_type(), self.i18n['uninstalled']))
|
||||
util.notify_user('{} ({}) {}'.format(src_pkg.model.name, src_pkg.model.get_type(), self.i18n['uninstalled']))
|
||||
|
||||
if not self.search_performed:
|
||||
only_pkg_type = len([p for p in self.pkgs if p.model.get_type() == pkgv.model.get_type()]) >= 2
|
||||
else:
|
||||
only_pkg_type = False
|
||||
if res['removed']:
|
||||
for list_idx, pkg_list in enumerate((self.pkgs_available, self.pkgs, self.pkgs_installed)):
|
||||
if pkg_list:
|
||||
removed_idxs = []
|
||||
for pkgv_idx, pkgv in enumerate(pkg_list):
|
||||
if len(removed_idxs) == len(res['removed']):
|
||||
break
|
||||
|
||||
for model in res['removed']:
|
||||
if pkgv.model == model:
|
||||
if list_idx == 0: # updates the model
|
||||
pkgv.model = model
|
||||
|
||||
if not self.search_performed or list_idx == 2: # always from the installed packages
|
||||
removed_idxs.append(pkgv_idx)
|
||||
|
||||
if self.search_performed and list_idx == 1: # only for displayed
|
||||
self.table_apps.update_package(pkgv)
|
||||
|
||||
break # as the model has been found, stops the loop
|
||||
|
||||
if removed_idxs:
|
||||
# updating the list
|
||||
removed_idxs.sort()
|
||||
for decrement, pkg_idx in enumerate(removed_idxs):
|
||||
del pkg_list[pkg_idx - decrement]
|
||||
|
||||
if list_idx == 1: # updates the rows if the current list reprents the displayed packages:
|
||||
for decrement, idx in enumerate(removed_idxs):
|
||||
self.table_apps.removeRow(idx - decrement)
|
||||
|
||||
for new_idx, pkgv in enumerate(self.pkgs): # updating the package indexes
|
||||
pkgv.table_index = new_idx
|
||||
|
||||
self.recent_uninstall = True
|
||||
self.refresh_packages(pkg_types={pkgv.model.__class__} if only_pkg_type else None)
|
||||
self.update_custom_actions()
|
||||
|
||||
notify_tray()
|
||||
else:
|
||||
if self._can_notify_user():
|
||||
util.notify_user('{}: {}'.format(pkgv.model.name, self.i18n['notification.uninstall.failed']))
|
||||
util.notify_user('{}: {}'.format(res['pkg'].model.name, self.i18n['notification.uninstall.failed']))
|
||||
|
||||
self.checkbox_console.setChecked(True)
|
||||
|
||||
for ref in (self.ref_combo_categories, self.ref_input_name_filter):
|
||||
if not ref.isVisible():
|
||||
ref.setVisible(True)
|
||||
|
||||
if self.combo_filter_type.count() > 2 and not self.ref_combo_filter_type.isVisible():
|
||||
self.ref_combo_filter_type.setVisible(True)
|
||||
|
||||
def _can_notify_user(self):
|
||||
return bool(self.config['system']['notifications']) and (self.isHidden() or self.isMinimized())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user