From f6bf5bc1eece993f9f7d7eea7358269fcb8ba5e4 Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Thu, 9 May 2024 11:54:27 +0200 Subject: [PATCH 01/13] Check if Include folders/files do exists (in case they are removed) Solution b) when start taking a snapshot the include list should be checked of existence first and warn about missings. reference: https://github.com/bit-team/backintime/issues/1586 --- CHANGES | 1 + common/backintime.py | 10 ++++++++++ common/po/pt_BR.po | 8 ++++++++ common/snapshots.py | 19 +++++++++++++++++++ qt/app.py | 15 +++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/CHANGES b/CHANGES index b49573925..6e53decac 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ Back In Time Version 1.4.4-dev (development of upcoming release) +* Fix bug: Check if Include folders/files do exists (in case they are removed) (1586) (@rafaelhdr) * Feature: Support SSH proxy (jump) host (#1688) (@cgrinham, Christie Grinham) * Removed: Context menu in LogViewDialog (#1578) * Refactor: Replace Config.user() with getpass.getuser() (#1694) diff --git a/common/backintime.py b/common/backintime.py index bd21b07b9..e6214a91f 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -48,6 +48,14 @@ parsers = {} +def warningOnTakeSnapshot(config): + hasMissing, missing = snapshots.hasMissing(config.include()) + if hasMissing: + msgMissing = ', '.join(missing) + msg = f'{_("The following folders are missing")}: {msgMissing}' + logger.warning(msg) + return True + def takeSnapshotAsync(cfg, checksum = False): """ Fork a new backintime process with 'backup' command which will @@ -56,6 +64,7 @@ def takeSnapshotAsync(cfg, checksum = False): Args: cfg (config.Config): config that should be used """ + warningOnTakeSnapshot(cfg) cmd = [] if cfg.ioniceOnUser(): cmd.extend(('ionice', '-c2', '-n7')) @@ -94,6 +103,7 @@ def takeSnapshot(cfg, force = True): Returns: bool: ``True`` if there was an error """ + warningOnTakeSnapshot(cfg) tools.envLoad(cfg.cronEnvFile()) ret = snapshots.Snapshots(cfg).backup(force) return ret diff --git a/common/po/pt_BR.po b/common/po/pt_BR.po index 707873a03..4c483ed55 100644 --- a/common/po/pt_BR.po +++ b/common/po/pt_BR.po @@ -1724,6 +1724,14 @@ msgstr "AVISO" msgid "Exclude {path} from future snapshots?" msgstr "Excluir {path} de snapshots futuros?" +#: qt/app.py:1189 +msgid "The following folders are missing" +msgstr "As seguintes pastas estão faltando" + +#: qt/app.py:1189 +msgid "Do you want to proceed?" +msgstr "Deseja prosseguir?" + #~ msgid " and add your user to group 'fuse'" #~ msgstr " e adicionar seu usuário para grupo 'fuse'" diff --git a/common/snapshots.py b/common/snapshots.py index 60d71c831..aab784980 100644 --- a/common/snapshots.py +++ b/common/snapshots.py @@ -3104,6 +3104,25 @@ def lastSnapshot(cfg): return sids[0] +def hasMissing(included): + """ + Check if there are missing files or folders in a snapshot. + + Args: + included (list): list of tuples (item, info) + + Returns: + tuple: (bool, str) where bool is ``True`` if there are + missing files or folders and str is a message + describing the missing files or folders + """ + notFound = [] + for path, info in included: + if not os.path.exists(path): + notFound.append(path) + return bool(notFound), notFound + + if __name__ == '__main__': config = config.Config() snapshots = Snapshots(config) diff --git a/qt/app.py b/qt/app.py index 07a3831d8..70a55dd9f 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1182,11 +1182,26 @@ def updateTimeLine(self, refreshSnapshotsList = True): item = self.timeLine.addSnapshot(sid) self.timeLine.checkSelection() + def validateOnTakeSnapshot(self): + hasMissing, missing = snapshots.hasMissing(self.config.include()) + if hasMissing: + msgMissing = '\n'.join(missing) + msg = f'{_("The following folders are missing")}:\n\n{msgMissing}\n\n{_("Do you want to proceed?")}' + answer = messagebox.warningYesNo(self, msg) + return answer == QMessageBox.StandardButton.Yes + return True + def btnTakeSnapshotClicked(self): + proceed = self.validateOnTakeSnapshot() + if not proceed: + return backintime.takeSnapshotAsync(self.config) self.updateTakeSnapshot(True) def btnTakeSnapshotChecksumClicked(self): + proceed = self.validateOnTakeSnapshot() + if not proceed: + return backintime.takeSnapshotAsync(self.config, checksum = True) self.updateTakeSnapshot(True) From d4556caa1887162f71be9e931b792c59adf0206b Mon Sep 17 00:00:00 2001 From: Rafael Date: Thu, 9 May 2024 22:19:36 +0200 Subject: [PATCH 02/13] Update CHANGES Co-authored-by: buhtz --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 6e53decac..0dcca030a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,7 @@ Back In Time Version 1.4.4-dev (development of upcoming release) -* Fix bug: Check if Include folders/files do exists (in case they are removed) (1586) (@rafaelhdr) +* Fix bug: Check if Include folders/files do exists (in case they are removed) (#1586) (@rafaelhdr) * Feature: Support SSH proxy (jump) host (#1688) (@cgrinham, Christie Grinham) * Removed: Context menu in LogViewDialog (#1578) * Refactor: Replace Config.user() with getpass.getuser() (#1694) From 5f3a8c72f6509a15935d4a15dfd7b43e3d36604c Mon Sep 17 00:00:00 2001 From: Rafael Date: Thu, 9 May 2024 22:21:23 +0200 Subject: [PATCH 03/13] PEP8 convention Co-authored-by: buhtz --- common/backintime.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/common/backintime.py b/common/backintime.py index e6214a91f..7bce87eee 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -48,12 +48,14 @@ parsers = {} -def warningOnTakeSnapshot(config): - hasMissing, missing = snapshots.hasMissing(config.include()) - if hasMissing: - msgMissing = ', '.join(missing) - msg = f'{_("The following folders are missing")}: {msgMissing}' +def warning_on_take_snapshot(config): + has_missing, missing = snapshots.has_missing(config.include()) + + if has_missing: + msg = ', '.join(missing) + msg = f'The following folders are missing: {msg}' logger.warning(msg) + return True def takeSnapshotAsync(cfg, checksum = False): From e07d5a1ea400864dcfb2ce2cd1b64670e6a5f4ff Mon Sep 17 00:00:00 2001 From: Rafael Date: Thu, 9 May 2024 22:21:40 +0200 Subject: [PATCH 04/13] PEP8 convention Co-authored-by: buhtz --- common/backintime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/backintime.py b/common/backintime.py index 7bce87eee..4b12f8c1d 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -66,7 +66,7 @@ def takeSnapshotAsync(cfg, checksum = False): Args: cfg (config.Config): config that should be used """ - warningOnTakeSnapshot(cfg) + warning_on_take_snapshot(cfg) cmd = [] if cfg.ioniceOnUser(): cmd.extend(('ionice', '-c2', '-n7')) From ce4d7616761a5a100efeb699d96a92cca9135d6b Mon Sep 17 00:00:00 2001 From: Rafael Date: Thu, 9 May 2024 22:21:59 +0200 Subject: [PATCH 05/13] PEP8 convention Co-authored-by: buhtz --- common/backintime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/backintime.py b/common/backintime.py index 4b12f8c1d..12d7e6a2b 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -105,7 +105,7 @@ def takeSnapshot(cfg, force = True): Returns: bool: ``True`` if there was an error """ - warningOnTakeSnapshot(cfg) + warning_on_take_snapshot(cfg) tools.envLoad(cfg.cronEnvFile()) ret = snapshots.Snapshots(cfg).backup(force) return ret From 27fe2da3257c575afedbf7bf36c8a9c08d08d7f0 Mon Sep 17 00:00:00 2001 From: Rafael Date: Thu, 9 May 2024 22:42:01 +0200 Subject: [PATCH 06/13] refactor code from review refactor btn snapshot & improve translate message Co-authored-by: buhtz --- qt/app.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/qt/app.py b/qt/app.py index 70a55dd9f..5c03ef180 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1186,23 +1186,23 @@ def validateOnTakeSnapshot(self): hasMissing, missing = snapshots.hasMissing(self.config.include()) if hasMissing: msgMissing = '\n'.join(missing) - msg = f'{_("The following folders are missing")}:\n\n{msgMissing}\n\n{_("Do you want to proceed?")}' + msg = _('The following folders are missing: {folders} Do you want to proceed?'.format( + folders=f'\n{msgMissing}\n\n') answer = messagebox.warningYesNo(self, msg) return answer == QMessageBox.StandardButton.Yes return True def btnTakeSnapshotClicked(self): - proceed = self.validateOnTakeSnapshot() - if not proceed: - return - backintime.takeSnapshotAsync(self.config) - self.updateTakeSnapshot(True) + _take_snapshot_clicked(checksum=False) def btnTakeSnapshotChecksumClicked(self): - proceed = self.validateOnTakeSnapshot() - if not proceed: + _take_snapshot_clicked(checksum=True) + + def _take_snapshot_clicked(self, checksum): + if not self.validateOnTakeSnapshot(): return - backintime.takeSnapshotAsync(self.config, checksum = True) + + backintime.takeSnapshotAsync(self.config, checksum=checksum) self.updateTakeSnapshot(True) def btnStopTakeSnapshotClicked(self): From 27ac817b256d07a348047bac27745adb68493341 Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Thu, 9 May 2024 22:41:27 +0200 Subject: [PATCH 07/13] PEP8 snake case --- common/backintime.py | 6 +++--- common/po/pt_BR.po | 8 -------- common/snapshots.py | 8 ++++---- qt/app.py | 2 +- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/common/backintime.py b/common/backintime.py index 12d7e6a2b..e70c87ba7 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -49,9 +49,9 @@ parsers = {} def warning_on_take_snapshot(config): - has_missing, missing = snapshots.has_missing(config.include()) - - if has_missing: + missing = snapshots.has_missing(config.include()) + + if missing: msg = ', '.join(missing) msg = f'The following folders are missing: {msg}' logger.warning(msg) diff --git a/common/po/pt_BR.po b/common/po/pt_BR.po index 4c483ed55..707873a03 100644 --- a/common/po/pt_BR.po +++ b/common/po/pt_BR.po @@ -1724,14 +1724,6 @@ msgstr "AVISO" msgid "Exclude {path} from future snapshots?" msgstr "Excluir {path} de snapshots futuros?" -#: qt/app.py:1189 -msgid "The following folders are missing" -msgstr "As seguintes pastas estão faltando" - -#: qt/app.py:1189 -msgid "Do you want to proceed?" -msgstr "Deseja prosseguir?" - #~ msgid " and add your user to group 'fuse'" #~ msgstr " e adicionar seu usuário para grupo 'fuse'" diff --git a/common/snapshots.py b/common/snapshots.py index aab784980..492b2ee9f 100644 --- a/common/snapshots.py +++ b/common/snapshots.py @@ -3104,7 +3104,7 @@ def lastSnapshot(cfg): return sids[0] -def hasMissing(included): +def has_missing(included): """ Check if there are missing files or folders in a snapshot. @@ -3116,11 +3116,11 @@ def hasMissing(included): missing files or folders and str is a message describing the missing files or folders """ - notFound = [] + not_found = [] for path, info in included: if not os.path.exists(path): - notFound.append(path) - return bool(notFound), notFound + not_found.append(path) + return not_found if __name__ == '__main__': diff --git a/qt/app.py b/qt/app.py index 5c03ef180..c8907b3b0 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1183,7 +1183,7 @@ def updateTimeLine(self, refreshSnapshotsList = True): self.timeLine.checkSelection() def validateOnTakeSnapshot(self): - hasMissing, missing = snapshots.hasMissing(self.config.include()) + hasMissing, missing = snapshots.has_missing(self.config.include()) if hasMissing: msgMissing = '\n'.join(missing) msg = _('The following folders are missing: {folders} Do you want to proceed?'.format( From 4f36503fc02e51e8e17923561e4ce0bd6a40150f Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Thu, 9 May 2024 22:48:54 +0200 Subject: [PATCH 08/13] fixes missing self --- common/backintime.py | 2 -- qt/app.py | 12 ++++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/common/backintime.py b/common/backintime.py index e70c87ba7..87002c311 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -56,8 +56,6 @@ def warning_on_take_snapshot(config): msg = f'The following folders are missing: {msg}' logger.warning(msg) - return True - def takeSnapshotAsync(cfg, checksum = False): """ Fork a new backintime process with 'backup' command which will diff --git a/qt/app.py b/qt/app.py index c8907b3b0..2ea0828bb 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1183,20 +1183,20 @@ def updateTimeLine(self, refreshSnapshotsList = True): self.timeLine.checkSelection() def validateOnTakeSnapshot(self): - hasMissing, missing = snapshots.has_missing(self.config.include()) - if hasMissing: - msgMissing = '\n'.join(missing) + missing = snapshots.has_missing(self.config.include()) + if missing: + msg_missing = '\n'.join(missing) msg = _('The following folders are missing: {folders} Do you want to proceed?'.format( - folders=f'\n{msgMissing}\n\n') + folders=f'\n{msg_missing}\n\n')) answer = messagebox.warningYesNo(self, msg) return answer == QMessageBox.StandardButton.Yes return True def btnTakeSnapshotClicked(self): - _take_snapshot_clicked(checksum=False) + self._take_snapshot_clicked(checksum=False) def btnTakeSnapshotChecksumClicked(self): - _take_snapshot_clicked(checksum=True) + self._take_snapshot_clicked(checksum=True) def _take_snapshot_clicked(self, checksum): if not self.validateOnTakeSnapshot(): From 9cb83487540ff6bb69ffc43048976c31a603b164 Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Thu, 9 May 2024 22:58:16 +0200 Subject: [PATCH 09/13] PEP8 snake convention --- qt/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/app.py b/qt/app.py index 2ea0828bb..cc921c44d 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1182,7 +1182,7 @@ def updateTimeLine(self, refreshSnapshotsList = True): item = self.timeLine.addSnapshot(sid) self.timeLine.checkSelection() - def validateOnTakeSnapshot(self): + def validate_on_take_snapshot(self): missing = snapshots.has_missing(self.config.include()) if missing: msg_missing = '\n'.join(missing) @@ -1199,7 +1199,7 @@ def btnTakeSnapshotChecksumClicked(self): self._take_snapshot_clicked(checksum=True) def _take_snapshot_clicked(self, checksum): - if not self.validateOnTakeSnapshot(): + if not self.validate_on_take_snapshot(): return backintime.takeSnapshotAsync(self.config, checksum=checksum) From 7472f54d4df34789f3bd10cd1071a197c36be4f7 Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Thu, 9 May 2024 23:08:20 +0200 Subject: [PATCH 10/13] PEP8 blank lines ref: https://peps.python.org/pep-0008/#blank-lines --- common/backintime.py | 31 +++++++++++++++++++++++++++++++ qt/app.py | 5 +++++ 2 files changed, 36 insertions(+) diff --git a/common/backintime.py b/common/backintime.py index 87002c311..c57b17cef 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -48,6 +48,7 @@ parsers = {} + def warning_on_take_snapshot(config): missing = snapshots.has_missing(config.include()) @@ -56,6 +57,7 @@ def warning_on_take_snapshot(config): msg = f'The following folders are missing: {msg}' logger.warning(msg) + def takeSnapshotAsync(cfg, checksum = False): """ Fork a new backintime process with 'backup' command which will @@ -91,6 +93,7 @@ def takeSnapshotAsync(cfg, checksum = False): pass subprocess.Popen(cmd, env = env) + def takeSnapshot(cfg, force = True): """ Take a new snapshot. @@ -108,6 +111,7 @@ def takeSnapshot(cfg, force = True): ret = snapshots.Snapshots(cfg).backup(force) return ret + def _mount(cfg): """ Mount external filesystems. @@ -123,6 +127,7 @@ def _mount(cfg): else: cfg.setCurrentHashId(hash_id) + def _umount(cfg): """ Unmount external filesystems. @@ -135,6 +140,7 @@ def _umount(cfg): except MountException as ex: logger.error(str(ex)) + def createParsers(app_name = 'backintime'): """ Define parsers for commandline arguments. @@ -630,6 +636,7 @@ def join(args, subArgs): return args + def printHeader(): """ Print application name, version and legal notes. @@ -643,6 +650,7 @@ def printHeader(): print("under certain conditions; type `backintime --license' for details.") print('') + class PseudoAliasAction(argparse.Action): """ Translate '--COMMAND' into 'COMMAND' for backwards compatibility. @@ -669,6 +677,7 @@ def __call__(self, parser, namespace, values, option_string=None): setattr(namespace, 'replace', replace) setattr(namespace, 'alias', alias) + def aliasParser(args): """ Call commands which where given with leading -- for backwards @@ -686,6 +695,7 @@ def aliasParser(args): if 'func' in dir(newArgs): newArgs.func(newArgs) + def getConfig(args, check = True): """ Load config and change to profile selected on commandline. @@ -723,6 +733,7 @@ def getConfig(args, check = True): cfg.forceUseChecksum = args.checksum return cfg + def setQuiet(args): """ Redirect :py:data:`sys.stdout` to ``/dev/null`` if ``--quiet`` was set on @@ -744,6 +755,7 @@ def setQuiet(args): atexit.register(force_stdout.close) return force_stdout + class printLicense(argparse.Action): """ Print custom license @@ -756,6 +768,7 @@ def __call__(self, *args, **kwargs): print(license_path.read_text('utf-8')) sys.exit(RETURN_OK) + class printDiagnostics(argparse.Action): """ Print information that is helpful for the support team @@ -774,6 +787,7 @@ def __call__(self, *args, **kwargs): sys.exit(RETURN_OK) + def backup(args, force = True): """ Command for force taking a new snapshot. @@ -793,6 +807,7 @@ def backup(args, force = True): ret = takeSnapshot(cfg, force) sys.exit(int(ret)) + def backupJob(args): """ Command for taking a new snapshot in background. Mainly used for cronjobs. @@ -808,6 +823,7 @@ def backupJob(args): """ cli.BackupJobDaemon(backup, args).start() + def shutdown(args): """ Command for shutting down the computer after the current snapshot has @@ -852,6 +868,7 @@ def shutdown(args): sd.shutdown() sys.exit(RETURN_OK) + def snapshotsPath(args): """ Command for printing the full snapshot path of current profile. @@ -874,6 +891,7 @@ def snapshotsPath(args): print(msg.format(cfg.snapshotsFullPath()), file=force_stdout) sys.exit(RETURN_OK) + def snapshotsList(args): """ Command for printing a list of all snapshots in current profile. @@ -904,6 +922,7 @@ def snapshotsList(args): _umount(cfg) sys.exit(RETURN_OK) + def snapshotsListPath(args): """ Command for printing a list of all snapshots paths in current profile. @@ -934,6 +953,7 @@ def snapshotsListPath(args): _umount(cfg) sys.exit(RETURN_OK) + def lastSnapshot(args): """ Command for printing the very last snapshot in current profile. @@ -960,6 +980,7 @@ def lastSnapshot(args): _umount(cfg) sys.exit(RETURN_OK) + def lastSnapshotPath(args): """ Command for printing the path of the very last snapshot in @@ -988,6 +1009,7 @@ def lastSnapshotPath(args): _umount(cfg) sys.exit(RETURN_OK) + def unmount(args): """ Command for unmounting all filesystems. @@ -1005,6 +1027,7 @@ def unmount(args): _umount(cfg) sys.exit(RETURN_OK) + def benchmarkCipher(args): """ Command for transferring a file with scp to remote host with all @@ -1028,6 +1051,7 @@ def benchmarkCipher(args): logger.error("SSH is not configured for profile '%s'!" % cfg.profileName()) sys.exit(RETURN_ERR) + def pwCache(args): """ Command for starting password cache daemon. @@ -1058,6 +1082,7 @@ def pwCache(args): daemon.run() sys.exit(ret) + def decode(args): """ Command for decoding paths given paths with 'encfsctl'. @@ -1092,6 +1117,7 @@ def decode(args): _umount(cfg) sys.exit(RETURN_OK) + def remove(args, force = False): """ Command for removing snapshots. @@ -1112,6 +1138,7 @@ def remove(args, force = False): _umount(cfg) sys.exit(RETURN_OK) + def removeAndDoNotAskAgain(args): """ Command for removing snapshots without asking before remove @@ -1126,6 +1153,7 @@ def removeAndDoNotAskAgain(args): """ remove(args, True) + def smartRemove(args): """ Command for running Smart-Remove from Terminal. @@ -1159,6 +1187,7 @@ def smartRemove(args): logger.error('Smart Remove is not configured.') sys.exit(RETURN_NO_CFG) + def restore(args): """ Command for restoring files from snapshots. @@ -1188,6 +1217,7 @@ def restore(args): _umount(cfg) sys.exit(RETURN_OK) + def checkConfig(args): """ Command for checking the config file. @@ -1215,5 +1245,6 @@ def checkConfig(args): file = force_stdout) sys.exit(RETURN_ERR) + if __name__ == '__main__': startApp() diff --git a/qt/app.py b/qt/app.py index cc921c44d..c66616bbb 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1933,6 +1933,7 @@ def eventFilter(self, receiver, event): return super(ExtraMouseButtonEventFilter, self) \ .eventFilter(receiver, event) + class RemoveSnapshotThread(QThread): """ remove snapshots in background thread so GUI will not freeze @@ -1968,6 +1969,7 @@ def run(self): if self.config.inhibitCookie: self.config.inhibitCookie = tools.unInhibitSuspend(*self.config.inhibitCookie) + class FillTimeLineThread(QThread): """ add snapshot IDs to timeline in background @@ -1985,6 +1987,7 @@ def run(self): self.parent.snapshotsList.sort() + class SetupCron(QThread): """ Check crontab entries on startup. @@ -1996,6 +1999,7 @@ def __init__(self, parent): def run(self): self.config.setupCron() + def debugTrace(): """ Set a tracepoint in the Python debugger that works with Qt @@ -2004,6 +2008,7 @@ def debugTrace(): pyqtRemoveInputHook() set_trace() + if __name__ == '__main__': cfg = backintime.startApp('backintime-qt') From 45aa01111df97818517dd34290cba82129636f7a Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Mon, 20 May 2024 17:32:50 +0200 Subject: [PATCH 11/13] move warning about missing snapshots for after mounting --- common/backintime.py | 11 ----------- common/snapshots.py | 9 +++++++++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/common/backintime.py b/common/backintime.py index c57b17cef..c324d6673 100644 --- a/common/backintime.py +++ b/common/backintime.py @@ -49,15 +49,6 @@ parsers = {} -def warning_on_take_snapshot(config): - missing = snapshots.has_missing(config.include()) - - if missing: - msg = ', '.join(missing) - msg = f'The following folders are missing: {msg}' - logger.warning(msg) - - def takeSnapshotAsync(cfg, checksum = False): """ Fork a new backintime process with 'backup' command which will @@ -66,7 +57,6 @@ def takeSnapshotAsync(cfg, checksum = False): Args: cfg (config.Config): config that should be used """ - warning_on_take_snapshot(cfg) cmd = [] if cfg.ioniceOnUser(): cmd.extend(('ionice', '-c2', '-n7')) @@ -106,7 +96,6 @@ def takeSnapshot(cfg, force = True): Returns: bool: ``True`` if there was an error """ - warning_on_take_snapshot(cfg) tools.envLoad(cfg.cronEnvFile()) ret = snapshots.Snapshots(cfg).backup(force) return ret diff --git a/common/snapshots.py b/common/snapshots.py index 657aa20c0..333ff31d2 100644 --- a/common/snapshots.py +++ b/common/snapshots.py @@ -700,6 +700,14 @@ def remove(self, sid): return True + def _warning_on_take_snapshot(self, config): + missing = has_missing(config.include()) + + if missing: + msg = ', '.join(missing) + msg = f'The following folders are missing: {msg}' + logger.warning(msg) + # TODO Refactor: This functions is extremely difficult to understand: # - Nested "if"s # - Fuzzy names of classes, attributes and methods @@ -807,6 +815,7 @@ def backup(self, force = False): else: self.config.setCurrentHashId(hash_id) + self._warning_on_take_snapshot(self.config) include_folders = self.config.include() if not include_folders: From c2941baaadbb53d22837889feb90e9ab748e7831 Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Mon, 20 May 2024 17:56:12 +0200 Subject: [PATCH 12/13] display error message on include --- common/snapshots.py | 1 + 1 file changed, 1 insertion(+) diff --git a/common/snapshots.py b/common/snapshots.py index 333ff31d2..de9cf4b75 100644 --- a/common/snapshots.py +++ b/common/snapshots.py @@ -707,6 +707,7 @@ def _warning_on_take_snapshot(self, config): msg = ', '.join(missing) msg = f'The following folders are missing: {msg}' logger.warning(msg) + self.setTakeSnapshotMessage(1, msg) # TODO Refactor: This functions is extremely difficult to understand: # - Nested "if"s From bb5969cb359d0c71cdbecb3f941fe207bff3b949 Mon Sep 17 00:00:00 2001 From: Rafael Hurpia da Rocha <1108973+rafaelhdr@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:28:57 +0200 Subject: [PATCH 13/13] document and rename has_missing_includes --- common/snapshots.py | 19 +++++++++++++------ qt/app.py | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/common/snapshots.py b/common/snapshots.py index 1737520b2..d9a2aa27c 100644 --- a/common/snapshots.py +++ b/common/snapshots.py @@ -15,7 +15,6 @@ # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -import json import os from pathlib import Path import stat @@ -698,12 +697,20 @@ def remove(self, sid): return True - def _warning_on_take_snapshot(self, config): - missing = has_missing(config.include()) + def _check_included_sources_exist_on_take_snapshot(self, config): + """ + Check if files and/or folders in the include list exist on the source. + + If a file or folder does not exist, a warning message is logged. + + Args: + cfg (config.Config): config that should be used + """ + missing = has_missing_includes(config.include()) if missing: msg = ', '.join(missing) - msg = f'The following folders are missing: {msg}' + msg = f'The following **files/**folders are missing: {msg}' logger.warning(msg) self.setTakeSnapshotMessage(1, msg) @@ -815,7 +822,7 @@ def backup(self, force=False): else: self.config.setCurrentHashId(hash_id) - self._warning_on_take_snapshot(self.config) + self._check_included_sources_exist_on_take_snapshot(self.config) include_folders = self.config.include() if not include_folders: @@ -3097,7 +3104,7 @@ def lastSnapshot(cfg): return sids[0] -def has_missing(included): +def has_missing_includes(included): """ Check if there are missing files or folders in a snapshot. diff --git a/qt/app.py b/qt/app.py index fe306eb57..6e1285d3c 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1212,7 +1212,7 @@ def updateTimeLine(self, refreshSnapshotsList=True): self.timeLine.checkSelection() def validate_on_take_snapshot(self): - missing = snapshots.has_missing(self.config.include()) + missing = snapshots.has_missing_includes(self.config.include()) if missing: msg_missing = '\n'.join(missing) msg = _('The following folders are missing: {folders} Do you want to proceed?'.format(