From c16a7509bdb7c85555bf5346aab0bf73f73de44d Mon Sep 17 00:00:00 2001 From: Tomasz Kontusz Date: Tue, 16 Jun 2020 18:21:24 +0200 Subject: [PATCH] Fix parsing "changed link" lines (#510) * Fix parsing "changed link" lines * Move borg diff parser test to test_archives.py --- src/vorta/views/diff_result.py | 109 +++++++++++++++++---------------- tests/test_archives.py | 12 ++++ 2 files changed, 69 insertions(+), 52 deletions(-) diff --git a/src/vorta/views/diff_result.py b/src/vorta/views/diff_result.py index 8af1053b..b9dc1c37 100644 --- a/src/vorta/views/diff_result.py +++ b/src/vorta/views/diff_result.py @@ -19,58 +19,7 @@ class DiffResult(DiffResultBase, DiffResultUI): super().__init__() self.setupUi(self) - files_with_attributes = [] - nested_file_list = nested_dict() - - def parse_line(line): - if line: - line_split = line.split() - else: - return 0, "", "", "" - - if line_split[0] == 'added' or line_split[0] == 'removed': - change_type = line_split[0] - if line_split[1] in ['directory', 'link']: - size = 0 - full_path = re.search(r'^\w+ \w+ +(.*)', line).group(1) - else: - significand = line_split[1] - unit = line_split[2] - size = calc_size(significand, unit) - full_path = re.search(r'^\w+ +\S+ \w?B (.*)', line).group(1) - else: - size_change = re.search(r' *[\+-]?(\d+\.*\d*) (\w?B) +[\+-]?.+\w?B ', line) - if size_change: - significand = size_change.group(1) - unit = size_change.group(2) - size = calc_size(significand, unit) - full_path_index = size_change.end(0) - else: - size = 0 - - permission_change = re.search(r' *(\[.{24}\]) ', line) - if permission_change: - change_type = permission_change.group(1) - full_path_index = permission_change.end(0) - else: - change_type = "modified" - - if size_change and permission_change: - full_path_index = max(size_change.end(0), permission_change.end(0)) - full_path = line[full_path_index:] - - dir, name = os.path.split(full_path) - - # add to nested dict of folders to find nested dirs. - d = get_dict_from_list(nested_file_list, dir.split('/')) - if name not in d: - d[name] = {} - - return size, change_type, name, dir - - for line in fs_data.split('\n'): - files_with_attributes.append(parse_line(line)) - + files_with_attributes, nested_file_list = parse_diff_lines(fs_data.split('\n')) model = DiffTree(files_with_attributes, nested_file_list) view = self.treeView @@ -88,6 +37,62 @@ class DiffResult(DiffResultBase, DiffResultUI): self.okButton.clicked.connect(self.accept) +def parse_diff_lines(diff_lines): + files_with_attributes = [] + nested_file_list = nested_dict() + + def parse_line(line): + if line: + line_split = line.split() + else: + return 0, "", "", "" + + if line_split[0] in {'added', 'removed', 'changed'}: + change_type = line_split[0] + if line_split[1] in ['directory', 'link']: + size = 0 + full_path = re.search(r'^\w+ \w+ +(.*)', line).group(1) + else: + significand = line_split[1] + unit = line_split[2] + size = calc_size(significand, unit) + full_path = re.search(r'^\w+ +\S+ \w?B (.*)', line).group(1) + else: + size_change = re.search(r' *[\+-]?(\d+\.*\d*) (\w?B) +[\+-]?.+\w?B ', line) + if size_change: + significand = size_change.group(1) + unit = size_change.group(2) + size = calc_size(significand, unit) + full_path_index = size_change.end(0) + else: + size = 0 + + permission_change = re.search(r' *(\[.{24}\]) ', line) + if permission_change: + change_type = permission_change.group(1) + full_path_index = permission_change.end(0) + else: + change_type = "modified" + + if size_change and permission_change: + full_path_index = max(size_change.end(0), permission_change.end(0)) + full_path = line[full_path_index:] + + dir, name = os.path.split(full_path) + + # add to nested dict of folders to find nested dirs. + d = get_dict_from_list(nested_file_list, dir.split('/')) + if name not in d: + d[name] = {} + + return size, change_type, name, dir + + for line in diff_lines: + files_with_attributes.append(parse_line(line)) + + return (files_with_attributes, nested_file_list) + + def calc_size(significand, unit): if unit == 'B': return int(significand) diff --git a/tests/test_archives.py b/tests/test_archives.py index 0a448c13..e1cf1df6 100644 --- a/tests/test_archives.py +++ b/tests/test_archives.py @@ -1,5 +1,6 @@ import psutil from collections import namedtuple +import pytest from PyQt5 import QtCore from vorta.models import BackupProfileModel, ArchiveModel import vorta.borg @@ -165,3 +166,14 @@ def test_archive_diff(qapp, qtbot, mocker, borg_json_output, monkeypatch): assert tab._resultwindow.archiveNameLabel_1.text() == 'test-archive' tab._resultwindow.accept() + + +@pytest.mark.parametrize('line, expected', [ + ('changed link some/changed/link', + (0, 'changed', 'link', 'some/changed')), + (' +77.8 kB -77.8 kB some/changed/file', + (77800, 'modified', 'file', 'some/changed')), +]) +def test_archive_diff_parser(line, expected): + files_with_attributes, nested_file_list = vorta.views.diff_result.parse_diff_lines([line]) + assert files_with_attributes == [expected]