diff --git a/Backupper.py b/Backupper.py
index 767f7c8..511b826 100644
--- a/Backupper.py
+++ b/Backupper.py
@@ -572,6 +572,7 @@ def _generate_tree(
directories_to_parse_queue,
parsed_queue,
skipped_entries_abs,
+ self._config_manager.get_config("follow_symlinks"),
self._stats_tree_parsed_dirs,
self._stats_tree_parsed_files,
control_value,
diff --git a/ConfigManager.py b/ConfigManager.py
index bcd2473..bbb252f 100644
--- a/ConfigManager.py
+++ b/ConfigManager.py
@@ -26,6 +26,7 @@
"version": __version__,
"input_paths": [],
"save_to": "",
+ "follow_symlinks": False,
"delete_data": True,
"delete_skipped": False,
"create_empty_dirs": True,
diff --git a/GUIHandler.py b/GUIHandler.py
index 9984492..4c58075 100644
--- a/GUIHandler.py
+++ b/GUIHandler.py
@@ -149,6 +149,7 @@ def __init__(
self.cb_delete_data.setChecked(self._config_manager.get_config("delete_data"))
self.cb_delete_skipped.setChecked(self._config_manager.get_config("delete_skipped"))
self.cb_delete_skipped.setEnabled(self._config_manager.get_config("delete_data"))
+ self.cb_follow_symlinks.setChecked(self._config_manager.get_config("follow_symlinks"))
self.cb_create_empty_dirs.setChecked(self._config_manager.get_config("create_empty_dirs"))
self.cb_generate_tree.setChecked(self._config_manager.get_config("generate_tree"))
self.cob_checksum_alg.setCurrentText(self._config_manager.get_config("checksum_alg"))
@@ -162,6 +163,9 @@ def __init__(
# Connect updaters
self.le_save_to.textChanged.connect(lambda: self._config_manager.set_config("save_to", self.le_save_to.text()))
+ self.cb_follow_symlinks.clicked.connect(
+ lambda: self._config_manager.set_config("follow_symlinks", self.cb_follow_symlinks.isChecked())
+ )
self.cb_delete_data.clicked.connect(
lambda: self._config_manager.set_config("delete_data", self.cb_delete_data.isChecked())
)
diff --git a/gui.ui b/gui.ui
index 1bc7d14..675439a 100644
--- a/gui.ui
+++ b/gui.ui
@@ -7,8 +7,8 @@
0
0
- 502
- 608
+ 474
+ 757
@@ -28,17 +28,20 @@
+
+ 9
+
- 12
+ 9
- 12
+ 9
- 12
+ 9
- 6
+ 9
-
@@ -74,8 +77,8 @@
0
0
- 474
- 137
+ 448
+ 112
@@ -140,6 +143,33 @@
+ -
+
+
-
+
+
+ Follow symbolic links when parsing files
+
+
+ Follow symlinks
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
-
-
diff --git a/tree_parser.py b/tree_parser.py
index 9f48ba1..bd6fe5e 100644
--- a/tree_parser.py
+++ b/tree_parser.py
@@ -40,6 +40,7 @@ def tree_parser(
directories_to_parse_queue: multiprocessing.Queue,
parsed_queue: multiprocessing.Queue,
skipped_entries_abs: List[str],
+ follow_symlinks: bool,
stats_tree_parsed_dirs: multiprocessing.Value,
stats_tree_parsed_files: multiprocessing.Value,
control_value: multiprocessing.Value or None = None,
@@ -55,6 +56,7 @@ def tree_parser(
parsed_queue (multiprocessing.Queue): parsing results as tuples
(relative path, root dir path, PATH_..., is empty directory)
skipped_entries_abs (List[str]): list of normalized absolute paths to skip,
+ follow_symlinks (bool): True to follow symlinks, false to ignore them
stats_tree_parsed_dirs (multiprocessing.Value): counter of total successfully parsed directories
stats_tree_parsed_files (multiprocessing.Value): counter of total successfully parsed files
control_value (multiprocessing.Value or None, optional): value (int) to pause / cancel process
@@ -135,7 +137,7 @@ def tree_parser(
while True:
# Try to get next path
try:
- dir_or_file = next(parent_dir_abs_generator)
+ dir_or_file = next(parent_dir_abs_generator).is_symlink
# No more paths -> exit
except StopIteration:
@@ -149,6 +151,10 @@ def tree_parser(
# Parse it
try:
+ # Ignore symlinks
+ if dir_or_file.is_symlink() and not follow_symlinks:
+ continue
+
# Ignore if found in skipped paths
if os.path.normpath(str(dir_or_file)) in skipped_entries_abs:
continue