[improvement][ui] uninstallation does not refresh the table if it succeeds

This commit is contained in:
Vinicius Moreira
2020-06-16 11:41:06 -03:00
parent 81ddae5cbd
commit eee9e9abf8
11 changed files with 196 additions and 100 deletions

View File

@@ -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()

View File

@@ -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()

View File

@@ -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):

View File

@@ -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())