def prepare(cls, profile): ret = super().prepare(profile) if not ret['ok']: return ret else: ret['ok'] = False # Set back to false, so we can do our own checks here. cmd = ['borg', 'prune', '--list', '--info', '--log-json'] formatted_prune_prefix = format_archive_name(profile, profile.prune_prefix) pruning_opts = [ '--keep-hourly', str(profile.prune_hour), '--keep-daily', str(profile.prune_day), '--keep-weekly', str(profile.prune_week), '--keep-monthly', str(profile.prune_month), '--keep-yearly', str(profile.prune_year), '--prefix', formatted_prune_prefix ] if profile.prune_keep_within: pruning_opts += ['--keep-within', profile.prune_keep_within] cmd += pruning_opts cmd.append(f'{profile.repo.url}') ret['ok'] = True ret['cmd'] = cmd return ret
def save_archive_template(self, tpl, key): profile = self.profile() try: preview = 'Preview: ' + format_archive_name(profile, tpl) setattr(profile, key, tpl) profile.save() except Exception: preview = 'Error in archive name template.' if key == 'new_archive_name': self.archiveNamePreview.setText(preview) else: self.prunePrefixPreview.setText(preview)
def prepare(cls, profile): """ `borg create` is called from different places and needs some preparation. Centralize it here and return the required arguments to the caller. """ ret = super().prepare(profile) if not ret['ok']: return ret else: ret['ok'] = False # Set back to False, so we can do our own checks here. n_backup_folders = SourceFileModel.select().count() if n_backup_folders == 0: ret['message'] = trans_late('messages', 'Add some folders to back up first.') return ret network_status_monitor = get_network_status_monitor() current_wifi = network_status_monitor.get_current_wifi() if current_wifi is not None: wifi_is_disallowed = WifiSettingModel.select().where( (WifiSettingModel.ssid == current_wifi) & ( WifiSettingModel.allowed == False # noqa ) & (WifiSettingModel.profile == profile)) if wifi_is_disallowed.count() > 0 and profile.repo.is_remote_repo( ): ret['message'] = trans_late('messages', 'Current Wifi is not allowed.') return ret if profile.repo.is_remote_repo() and profile.dont_run_on_metered_networks \ and network_status_monitor.is_network_metered(): ret['message'] = trans_late( 'messages', 'Not running backup over metered connection.') return ret ret['profile'] = profile ret['repo'] = profile.repo # Run user-supplied pre-backup command if cls.pre_post_backup_cmd(ret) != 0: ret['message'] = trans_late( 'messages', 'Pre-backup command returned non-zero exit code.') return ret if not profile.repo.is_remote_repo() and not os.path.exists( profile.repo.url): ret['message'] = trans_late('messages', 'Repo folder not mounted or moved.') return ret if 'zstd' in profile.compression and not borg_compat.check('ZSTD'): ret['message'] = trans_late( 'messages', 'Your current Borg version does not support ZStd compression.') return ret cmd = [ 'borg', 'create', '--list', '--progress', '--info', '--log-json', '--json', '--filter=AM', '-C', profile.compression, ] # Add excludes # Partly inspired by borgmatic/borgmatic/borg/create.py if profile.exclude_patterns is not None: exclude_dirs = [] for p in profile.exclude_patterns.split('\n'): if p.strip(): expanded_directory = os.path.expanduser(p.strip()) exclude_dirs.append(expanded_directory) if exclude_dirs: pattern_file = tempfile.NamedTemporaryFile('w', delete=False) pattern_file.write('\n'.join(exclude_dirs)) pattern_file.flush() cmd.extend(['--exclude-from', pattern_file.name]) if profile.exclude_if_present is not None: for f in profile.exclude_if_present.split('\n'): if f.strip(): cmd.extend(['--exclude-if-present', f.strip()]) # Add repo url and source dirs. new_archive_name = format_archive_name(profile, profile.new_archive_name) cmd.append(f"{profile.repo.url}::{new_archive_name}") for f in SourceFileModel.select().where( SourceFileModel.profile == profile.id): cmd.append(f.dir) ret['message'] = trans_late('messages', 'Starting backup...') ret['ok'] = True ret['cmd'] = cmd return ret