diff --git a/CHANGELOG.md b/CHANGELOG.md index 498c05bb..fa3a6a27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - General - code refactoring - backup: - - single mode: only removing self generated snapshots (now the snapshots are associated with the comment "") [#244](https://github.com/vinifmor/bauh/issues/244) + - single mode: now supports two remove methods [#244](https://github.com/vinifmor/bauh/issues/244) + - self: it removes only self generated backups/snapshots (default) + - all: it removes all existing backup/snapshots on the disc + +

+ +

- Arch - text length of some popups reduced diff --git a/README.md b/README.md index 778acb8d..faa24bac 100644 --- a/README.md +++ b/README.md @@ -444,6 +444,7 @@ backup: upgrade: null # defines if the backup should be performed before upgrading a package. Allowed values: null (a dialog will be displayed asking if a snapshot should be generated), true: generates the backup without asking. false: disables the backup for this operation downgrade: null # defines if the backup should be performed before downgrading a package. Allowed values: null (a dialog will be displayed asking if a snapshot should be generated), true: generates the backup without asking. false: disables the backup for this operation type: rsync # defines the Timeshift backup mode -> 'rsync' (default) or 'btrfs' + remove_method: self # define which backups should be removed in the 'only_one' mode. 'self': only self generated copies. 'all': all existing backups on the disc. boot: load_apps: true # if the installed applications or suggestions should be loaded on the management panel after the initialization process. Default: true. ``` diff --git a/bauh/commons/view_utils.py b/bauh/commons/view_utils.py index 1ade21ae..3d0791f0 100644 --- a/bauh/commons/view_utils.py +++ b/bauh/commons/view_utils.py @@ -1,13 +1,12 @@ -from typing import List, Tuple, Optional +from typing import Tuple, Optional, Iterable from bauh.api.abstract.view import SelectViewType, InputOption, SingleSelectComponent - SIZE_UNITS = ((1, 'B'), (1024, 'Kb'), (1048576, 'Mb'), (1073741824, 'Gb'), (1099511627776, 'Tb'), (1125899906842624, 'Pb')) -def new_select(label: str, tip: str, id_: str, opts: List[Tuple[Optional[str], object, Optional[str]]], value: object, max_width: int, +def new_select(label: str, tip: Optional[str], id_: str, opts: Iterable[Tuple[Optional[str], object, Optional[str]]], value: object, max_width: int, type_: SelectViewType = SelectViewType.RADIO, capitalize_label: bool = True): inp_opts = [InputOption(label=o[0].capitalize(), value=o[1], tooltip=o[2]) for o in opts] def_opt = [o for o in inp_opts if o.value == value] diff --git a/bauh/view/core/config.py b/bauh/view/core/config.py index a9fa7e91..e9c7c5d8 100644 --- a/bauh/view/core/config.py +++ b/bauh/view/core/config.py @@ -3,6 +3,9 @@ from bauh.commons.config import YAMLConfigManager FILE_PATH = f'{CONFIG_DIR}/config.yml' +BACKUP_DEFAULT_REMOVE_METHOD = 'self' +BACKUP_REMOVE_METHODS = {BACKUP_DEFAULT_REMOVE_METHOD, 'all'} + class CoreConfigManager(YAMLConfigManager): @@ -63,7 +66,8 @@ class CoreConfigManager(YAMLConfigManager): 'downgrade': None, 'upgrade': None, 'mode': 'incremental', - 'type': 'rsync' + 'type': 'rsync', + 'remove_method': 'self' }, 'boot': { 'load_apps': True diff --git a/bauh/view/core/settings.py b/bauh/view/core/settings.py index 88820a55..561bf12c 100644 --- a/bauh/view/core/settings.py +++ b/bauh/view/core/settings.py @@ -16,7 +16,7 @@ from bauh.api.abstract.view import ViewComponent, TabComponent, InputOption, Tex FileChooserComponent, RangeInputComponent from bauh.commons.view_utils import new_select from bauh.view.core import timeshift -from bauh.view.core.config import CoreConfigManager +from bauh.view.core.config import CoreConfigManager, BACKUP_REMOVE_METHODS, BACKUP_DEFAULT_REMOVE_METHOD from bauh.view.core.downloader import AdaptableFileDownloader from bauh.view.util import translation from bauh.view.util.translation import I18n @@ -327,7 +327,7 @@ class GenericSettingsManager: sub_comps = [FormComponent([select_locale, select_store_pwd, select_sysnotify, select_load_apps, select_sugs, inp_sugs, inp_reboot], spaces=False)] return TabComponent(self.i18n['core.config.tab.general'].capitalize(), PanelComponent(sub_comps), None, 'core.gen') - def _gen_bool_component(self, label: str, tooltip: str, value: bool, id_: str, max_width: int = 200) -> SingleSelectComponent: + def _gen_bool_component(self, label: str, tooltip: Optional[str], value: bool, id_: str, max_width: int = 200) -> SingleSelectComponent: opts = [InputOption(label=self.i18n['yes'].capitalize(), value=True), InputOption(label=self.i18n['no'].capitalize(), value=False)] @@ -397,6 +397,7 @@ class GenericSettingsManager: core_config['backup']['enabled'] = bkp_form.get_component('enabled').get_selected() core_config['backup']['mode'] = bkp_form.get_component('mode').get_selected() core_config['backup']['type'] = bkp_form.get_component('type').get_selected() + core_config['backup']['remove_method'] = bkp_form.get_component('remove_method').get_selected() core_config['backup']['install'] = bkp_form.get_component('install').get_selected() core_config['backup']['uninstall'] = bkp_form.get_component('uninstall').get_selected() core_config['backup']['upgrade'] = bkp_form.get_component('upgrade').get_selected() @@ -580,5 +581,25 @@ class GenericSettingsManager: max_width=default_width, id_='type') - sub_comps = [FormComponent([enabled_opt, mode, type_, install_mode, uninstall_mode, upgrade_mode, downgrade_mode], spaces=False)] + remove_method = core_config['backup']['remove_method'] + + if not remove_method or remove_method not in BACKUP_REMOVE_METHODS: + remove_method = BACKUP_DEFAULT_REMOVE_METHOD + + remove_i18n = 'core.config.backup.remove_method' + remove_opts = ((self.i18n[f'{remove_i18n}.{m}'], m, self.i18n[f'{remove_i18n}.{m}.tip']) + for m in sorted(BACKUP_REMOVE_METHODS)) + + remove_label = f'{self.i18n[remove_i18n]} ({self.i18n["core.config.backup.mode"]} ' \ + f'"{self.i18n["core.config.backup.mode.only_one"].capitalize()}")' + + sel_remove = new_select(label=remove_label, + tip=None, + value=remove_method, + opts=remove_opts, + max_width=default_width, + capitalize_label=False, + id_='remove_method') + + sub_comps = [FormComponent([enabled_opt, type_, mode, sel_remove, install_mode, uninstall_mode, upgrade_mode, downgrade_mode], spaces=False)] return TabComponent(self.i18n['core.config.tab.backup'].capitalize(), PanelComponent(sub_comps), None, 'core.bkp') diff --git a/bauh/view/qt/thread.py b/bauh/view/qt/thread.py index 495ddf55..42a65d8b 100644 --- a/bauh/view/qt/thread.py +++ b/bauh/view/qt/thread.py @@ -26,7 +26,7 @@ from bauh.commons.internet import InternetChecker from bauh.commons.system import ProcessHandler, SimpleProcess from bauh.commons.view_utils import get_human_size_str from bauh.view.core import timeshift -from bauh.view.core.config import CoreConfigManager +from bauh.view.core.config import CoreConfigManager, BACKUP_REMOVE_METHODS, BACKUP_DEFAULT_REMOVE_METHOD from bauh.view.qt import commons from bauh.view.qt.commons import sort_packages from bauh.view.qt.view_model import PackageView, PackageViewStatus @@ -140,26 +140,36 @@ class AsyncAction(QThread, ProcessWatcher): handler = ProcessHandler(self) if app_config['backup']['mode'] == 'only_one': - previous_snapshots = tuple(timeshift.read_created_snapshots(root_password)) + remove_method = app_config['backup']['remove_method'] - if previous_snapshots: - substatus = f"[{self.i18n['core.config.tab.backup'].lower()}] {self.i18n['action.backup.substatus.delete']}" - self.change_substatus(substatus) + if remove_method not in BACKUP_REMOVE_METHODS: + remove_method = BACKUP_DEFAULT_REMOVE_METHOD - delete_failed = False - for snapshot in reversed(previous_snapshots): - deleted, _ = handler.handle_simple(timeshift.delete(snapshot, root_password)) + delete_failed = False - if not deleted: - delete_failed = True + if remove_method == 'self': + previous_snapshots = tuple(timeshift.read_created_snapshots(root_password)) - if delete_failed and not self.request_confirmation(title=self.i18n['core.config.tab.backup'], - body=f"{self.i18n['action.backup.error.delete']}. " - f"{self.i18n['action.backup.error.proceed']}", - confirmation_label=self.i18n['yes'].capitalize(), - deny_label=self.i18n['no'].capitalize()): - self.change_substatus('') - return False + if previous_snapshots: + substatus = f"[{self.i18n['core.config.tab.backup'].lower()}] {self.i18n['action.backup.substatus.delete']}" + self.change_substatus(substatus) + + for snapshot in reversed(previous_snapshots): + deleted, _ = handler.handle_simple(timeshift.delete(snapshot, root_password)) + + if not deleted: + delete_failed = True + else: + deleted, _ = handler.handle_simple(timeshift.delete_all_snapshots(root_password)) + delete_failed = not deleted + + if delete_failed and not self.request_confirmation(title=self.i18n['core.config.tab.backup'], + body=f"{self.i18n['action.backup.error.delete']}. " + f"{self.i18n['action.backup.error.proceed']}", + confirmation_label=self.i18n['yes'].capitalize(), + deny_label=self.i18n['no'].capitalize()): + self.change_substatus('') + return False self.change_substatus('[{}] {}'.format(self.i18n['core.config.tab.backup'].lower(), self.i18n['action.backup.substatus.create'])) created, _ = handler.handle_simple(timeshift.create_snapshot(root_password, app_config['backup']['type'])) diff --git a/bauh/view/resources/locale/ca b/bauh/view/resources/locale/ca index 854eebf2..59944115 100644 --- a/bauh/view/resources/locale/ca +++ b/bauh/view/resources/locale/ca @@ -211,6 +211,11 @@ core.config.backup.mode.incremental=Incremental core.config.backup.mode.incremental.tip=A new system backup will be generated containing only the changed files since the latest copy. core.config.backup.mode.only_one=Single core.config.backup.mode.only_one.tip=Only one system backup will be kept. Pre-existing backups will be erased. +core.config.backup.remove_method=Remove +core.config.backup.remove_method.self=Only generated +core.config.backup.remove_method.self.tip=It removes only the self generated backups +core.config.backup.remove_method.all=All +core.config.backup.remove_method.all.tip=It removes all existing backups on the disc core.config.backup.uninstall=Before uninstalling core.config.backup.upgrade=Before upgrading core.config.boot.load_apps=Load apps after startup diff --git a/bauh/view/resources/locale/de b/bauh/view/resources/locale/de index 551a2385..b08ec3bf 100644 --- a/bauh/view/resources/locale/de +++ b/bauh/view/resources/locale/de @@ -210,6 +210,11 @@ core.config.backup.mode.incremental=Incremental core.config.backup.mode.incremental.tip=A new system backup will be generated containing only the changed files since the latest copy. core.config.backup.mode.only_one=Single core.config.backup.mode.only_one.tip=Only one system backup will be kept. Pre-existing backups will be erased. +core.config.backup.remove_method=Remove +core.config.backup.remove_method.self=Only generated +core.config.backup.remove_method.self.tip=It removes only the self generated backups +core.config.backup.remove_method.all=All +core.config.backup.remove_method.all.tip=It removes all existing backups on the disc core.config.backup.uninstall=Before uninstalling core.config.backup.upgrade=Before upgrading core.config.boot.load_apps=Load apps after startup diff --git a/bauh/view/resources/locale/en b/bauh/view/resources/locale/en index 537d7aa4..f68805bb 100644 --- a/bauh/view/resources/locale/en +++ b/bauh/view/resources/locale/en @@ -211,6 +211,11 @@ core.config.backup.mode.incremental=Incremental core.config.backup.mode.only_one.tip=Only one system backup will be kept. Pre-existing backups will be erased. core.config.backup.mode.only_one=Single core.config.backup.mode=Mode +core.config.backup.remove_method=Remove +core.config.backup.remove_method.self=Only generated +core.config.backup.remove_method.self.tip=It removes only the self generated backups +core.config.backup.remove_method.all=All +core.config.backup.remove_method.all.tip=It removes all existing backups on the disc core.config.backup.uninstall=Before uninstalling core.config.backup.upgrade=Before upgrading core.config.backup=Enabled diff --git a/bauh/view/resources/locale/es b/bauh/view/resources/locale/es index 2312ba60..73d9e6c1 100644 --- a/bauh/view/resources/locale/es +++ b/bauh/view/resources/locale/es @@ -211,6 +211,11 @@ core.config.backup.mode.incremental=Incremental core.config.backup.mode.incremental.tip=Se generará una nueva copia de seguridad del sistema que contenga solo los archivos modificados desde la última copia. core.config.backup.mode.only_one=Única core.config.backup.mode.only_one.tip=Solo se guardará una copia de seguridad del sistema. Las copias preexistentes serán borradas. +core.config.backup.remove_method=Eliminar +core.config.backup.remove_method.self=Solo generadas +core.config.backup.remove_method.self.tip=Elimina solo las copias generadas por la aplicación +core.config.backup.remove_method.all=Todas +core.config.backup.remove_method.all.tip=Elimina todas las copias de seguridad existentes en el disco core.config.backup.uninstall=Antes de desinstalar core.config.backup.upgrade=Antes de actualizar core.config.boot.load_apps=Cargar aplicaciones al inicio diff --git a/bauh/view/resources/locale/fr b/bauh/view/resources/locale/fr index 1aa701fe..3065098f 100644 --- a/bauh/view/resources/locale/fr +++ b/bauh/view/resources/locale/fr @@ -209,6 +209,11 @@ core.config.backup.mode.incremental=Incrémental core.config.backup.mode.only_one.tip=Une seule sauvegarde sera conservée. Les précédantes seront écrasées core.config.backup.mode.only_one=Seul core.config.backup.mode=Mode +core.config.backup.remove_method=Remove +core.config.backup.remove_method.self=Only generated +core.config.backup.remove_method.self.tip=It removes only the self generated backups +core.config.backup.remove_method.all=All +core.config.backup.remove_method.all.tip=It removes all existing backups on the disc core.config.backup.uninstall=Avant de désinstaller core.config.backup.upgrade=Avant de mettre à jour core.config.backup=Activé diff --git a/bauh/view/resources/locale/it b/bauh/view/resources/locale/it index 4c28603f..c629bbd7 100644 --- a/bauh/view/resources/locale/it +++ b/bauh/view/resources/locale/it @@ -210,6 +210,11 @@ core.config.backup.mode.incremental=Incremental core.config.backup.mode.incremental.tip=A new system backup will be generated containing only the changed files since the latest copy. core.config.backup.mode.only_one=Single core.config.backup.mode.only_one.tip=Only one system backup will be kept. Pre-existing backups will be erased. +core.config.backup.remove_method=Remove +core.config.backup.remove_method.self=Only generated +core.config.backup.remove_method.self.tip=It removes only the self generated backups +core.config.backup.remove_method.all=All +core.config.backup.remove_method.all.tip=It removes all existing backups on the disc core.config.backup.uninstall=Before uninstalling core.config.backup.upgrade=Before upgrading core.config.boot.load_apps=Load apps after startup diff --git a/bauh/view/resources/locale/pt b/bauh/view/resources/locale/pt index 25a6276f..aa011ea6 100644 --- a/bauh/view/resources/locale/pt +++ b/bauh/view/resources/locale/pt @@ -209,6 +209,11 @@ core.config.backup.mode.incremental=Incremental core.config.backup.mode.only_one.tip=Somente uma cópia de segurança do sistema será mantida. Pré-existentes serão apagadas core.config.backup.mode.only_one=Única core.config.backup.mode=Modo +core.config.backup.remove_method=Remover +core.config.backup.remove_method.self=Somente geradas +core.config.backup.remove_method.self.tip=Remove somente as cópia geradas pela aplicação +core.config.backup.remove_method.all=Todas +core.config.backup.remove_method.all.tip=Remove todas as cópias existentes no disco core.config.backup.uninstall=Antes de desinstalar core.config.backup.upgrade=Antes de atualizar core.config.backup=Habilitada diff --git a/bauh/view/resources/locale/ru b/bauh/view/resources/locale/ru index b0234230..89c13d63 100644 --- a/bauh/view/resources/locale/ru +++ b/bauh/view/resources/locale/ru @@ -210,6 +210,11 @@ core.config.backup.mode.incremental=Incremental core.config.backup.mode.incremental.tip=A new system backup will be generated containing only the changed files since the latest copy. core.config.backup.mode.only_one=Single core.config.backup.mode.only_one.tip=Only one system backup will be kept. Pre-existing backups will be erased. +core.config.backup.remove_method=Remove +core.config.backup.remove_method.self=Only generated +core.config.backup.remove_method.self.tip=It removes only the self generated backups +core.config.backup.remove_method.all=All +core.config.backup.remove_method.all.tip=It removes all existing backups on the disc core.config.backup.uninstall=Before uninstalling core.config.backup.upgrade=Before upgrading core.config.boot.load_apps=Load apps after startup diff --git a/bauh/view/resources/locale/tr b/bauh/view/resources/locale/tr index f8e92e3a..e09c5703 100644 --- a/bauh/view/resources/locale/tr +++ b/bauh/view/resources/locale/tr @@ -209,6 +209,11 @@ core.config.backup.mode.incremental=Artan core.config.backup.mode.only_one.tip=Yalnızca bir sistem yedeklemesi tutulur. Önceden var olan yedeklemeler silinecek. core.config.backup.mode.only_one=Tekil core.config.backup.mode=Mod +core.config.backup.remove_method=Remove +core.config.backup.remove_method.self=Only generated +core.config.backup.remove_method.self.tip=It removes only the self generated backups +core.config.backup.remove_method.all=All +core.config.backup.remove_method.all.tip=It removes all existing backups on the disc core.config.backup.uninstall=Önce kaldırılıyor core.config.backup.upgrade=Önce yükseltiliyor core.config.backup=Etkin