From 8c465f0afe435dd2e36050ed3c2bced8c2af79b1 Mon Sep 17 00:00:00 2001 From: tcely Date: Fri, 28 Feb 2025 22:51:52 -0500 Subject: [PATCH] Handle more cases This should now handle: - adding a sub-directory - removing a sub-directory --- tubesync/sync/signals.py | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/tubesync/sync/signals.py b/tubesync/sync/signals.py index 594a82a8..a2ad1cb6 100644 --- a/tubesync/sync/signals.py +++ b/tubesync/sync/signals.py @@ -1,4 +1,5 @@ from pathlib import Path +from tempfile import TemporaryDirectory from django.conf import settings from django.db.models.signals import pre_save, post_save, pre_delete, post_delete from django.dispatch import receiver @@ -29,15 +30,35 @@ def source_pre_save(sender, instance, **kwargs): return existing_dirpath = existing_source.directory_path.resolve(strict=True) new_dirpath = instance.directory_path.resolve(strict=False) - rename_source_directory = ( - existing_dirpath != new_dirpath and - not new_dirpath.exists() - ) - if rename_source_directory: - tmp_dirpath = existing_dirpath.parent / ('.tmp.' + existing_dirpath.name) - existing_dirpath.rename(tmp_dirpath) - mkdir_p(new_dirpath.parent) - tmp_dirpath.rename(new_dirpath) + if existing_dirpath != new_dirpath: + path_name = lambda p: p.name + relative_dir = existing_source.directory + rd_parents = Path(relative_dir).parents + rd_parents_set = set(map(path_name, rd_parents)) + ad_parents = existing_dirpath.parents + ad_parents_set = set(map(path_name, ad_parents)) + # the names in the relative path are also in the absolute path + parents_count = len(ad_parents_set.intersection(rd_parents_set)) + work_directory = existing_dirpath + while parents_count > 0: + work_directory = work_directory.parent + parents_count -= 1 + with TemporaryDirectory(suffix='.'+new_dirpath.name, prefix='.tmp.', dir=work_directory) as tmp_dir: + tmp_dirpath = Path(tmp_dir) + existed = None + if new_dirpath.exists(): + existed = tmp_dirpath / 'existed' + new_dirpath.rename(existed) + previous = tmp_dirpath / 'previous' + existing_dirpath.rename(previous) + mkdir_p(new_dirpath.parent) + previous.rename(new_dirpath) + if existed and existed.is_dir(): + existed.rename(new_dirpath / '.existed') + # TODO: merge the contents of the directories + pass + elif existed: + existed.rename(new_dirpath / '.existed') recreate_index_source_task = ( existing_source.name != instance.name or existing_source.index_schedule != instance.index_schedule