From e5f5681bf70053d7eaec6cf8ac9471a6c1ca561e Mon Sep 17 00:00:00 2001 From: Eduardo Robles Elvira Date: Thu, 1 Aug 2013 16:55:58 +0200 Subject: [PATCH] allow also filtering on the extraction of backup tar files --- deltatar/deltatar.py | 8 ++++- deltatar/tarfile.py | 5 ++- testing/test_deltatar.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 075fc6b..e867053 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -575,8 +575,12 @@ class DeltaTar(object): password=self.password, new_volume_handler=new_volume_handler) os.chdir(target_path) - # TODO: fillo ha tering here - tarobj.extractall() + + def filter(cls, path): + return cls.filter_path(path, '.') + filter = partial(filter, self) + + tarobj.extractall(filter=filter) os.chdir(cwd) tarobj.close() else: diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index 779bc60..3842394 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -2444,7 +2444,7 @@ class TarFile(object): self.closed = True raise - def extractall(self, path=".", members=None): + def extractall(self, path=".", members=None, filter=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory @@ -2460,6 +2460,9 @@ class TarFile(object): if self.volume_number > 0 and tarinfo.ismultivol(): continue + if filter and not filter(tarinfo.path): + continue + if tarinfo.isdir(): # Extract directories with a safe mode. directories.append(tarinfo) diff --git a/testing/test_deltatar.py b/testing/test_deltatar.py index 0d5abd9..b75694f 100644 --- a/testing/test_deltatar.py +++ b/testing/test_deltatar.py @@ -479,6 +479,81 @@ class DeltaTarTest(BaseTest): '/test/test2' ]) + def test_restore_tar_basic_filtering(self): + ''' + Creates a backup, and then filter when doing the tar based restore. + ''' + deltatar = DeltaTar(mode=self.MODE, password=self.PASSWORD, + logger=self.consoleLogger) + + # create first backup + deltatar.create_full_backup( + source_path="source_dir", + backup_path="backup_dir") + + assert os.path.exists("backup_dir") + shutil.rmtree("source_dir") + + deltatar.included_files = ["/test", "/small"] + deltatar.excluded_files = ["/test/huge"] + + tar_filename = deltatar.volume_name_func('backup_dir', True, 0) + tar_path = os.path.join("backup_dir", tar_filename) + + deltatar.restore_backup(target_path="source_dir", + backup_tar_path=tar_path) + + assert os.path.exists("./source_dir/small") + assert os.path.exists("./source_dir/test") + assert os.path.exists("./source_dir/test/huge2") + assert os.path.exists("./source_dir/test/test2") + + assert not os.path.exists("./source_dir/test/huge") + assert not os.path.exists("./source_dir/big") + + def test_restore_tar_filter_func(self): + ''' + Creates a backup, and then filter when doing the tar based restore, + using the filter function. + ''' + visited_paths = [] + def filter_func(visited_paths, path): + if path not in visited_paths: + visited_paths.append(path) + return True + + filter_func = partial(filter_func, visited_paths) + deltatar = DeltaTar(mode=self.MODE, password=self.PASSWORD, + logger=self.consoleLogger) + + # create first backup + deltatar.create_full_backup( + source_path="source_dir", + backup_path="backup_dir") + + assert os.path.exists("backup_dir") + shutil.rmtree("source_dir") + + index_filename = deltatar.index_name_func(True) + index_path = os.path.join("backup_dir", index_filename) + + deltatar.included_files = ["/test", "/small"] + deltatar.excluded_files = ["/test/huge"] + deltatar.filter_func = filter_func + + tar_filename = deltatar.volume_name_func('backup_dir', True, 0) + tar_path = os.path.join("backup_dir", tar_filename) + + deltatar.restore_backup(target_path="source_dir", + backup_tar_path=tar_path) + assert set(visited_paths) == set([ + '/small', + '/test', + '/test/huge2', + '/test/test2' + ]) + + class DeltaTar2Test(DeltaTarTest): ''' -- 1.7.1