From 889e1f9ea28adbad40f5ad61c1c66ca1a3014594 Mon Sep 17 00:00:00 2001 From: Kai Herlemann <43746520+KaiHerlemann@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:12:08 +0800 Subject: [PATCH] Implement a no_delete flag See: https://github.com/pimutils/vdirsyncer/pull/1090 --- AUTHORS.rst | 1 + CHANGELOG.rst | 1 + tests/system/utils/test_main.py | 2 +- vdirsyncer/storage/base.py | 12 +++++++++++- vdirsyncer/sync/__init__.py | 4 +++- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index ad1b232..a298bb8 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -7,6 +7,7 @@ In alphabetical order: - Christian Geier - Clément Mondon - Corey Hinshaw +- Kai Herlemann - Hugo Osvaldo Barrera - Julian Mehne - Malte Kiefer diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 569d76c..da711e8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,6 +12,7 @@ may want to subscribe to `GitHub's tag feed Version 0.19.3 ============== +- Added a no_delete option to the storage configuration. :gh:`1090` - Fix crash when running ``vdirsyncer repair`` on a collection. :gh:`1019` - Add an option to request vCard v4.0. :gh:`1066` diff --git a/tests/system/utils/test_main.py b/tests/system/utils/test_main.py index 9177daf..0d31aee 100644 --- a/tests/system/utils/test_main.py +++ b/tests/system/utils/test_main.py @@ -22,7 +22,7 @@ def test_get_storage_init_args(): from vdirsyncer.storage.memory import MemoryStorage all, required = utils.get_storage_init_args(MemoryStorage) - assert all == {"fileext", "collection", "read_only", "instance_name"} + assert all == {"fileext", "collection", "read_only", "instance_name", "no_delete"} assert not required diff --git a/vdirsyncer/storage/base.py b/vdirsyncer/storage/base.py index bd1fdc6..dc27b1c 100644 --- a/vdirsyncer/storage/base.py +++ b/vdirsyncer/storage/base.py @@ -67,6 +67,10 @@ class Storage(metaclass=StorageMeta): # The machine-readable name of this collection. collection = None + #A value of False means storage does not support delete requests. A + #value of True mean the storage supports it. + no_delete = False + # A value of True means the storage does not support write-methods such as # upload, update and delete. A value of False means the storage does # support those methods. @@ -75,13 +79,19 @@ class Storage(metaclass=StorageMeta): # The attribute values to show in the representation of the storage. _repr_attributes: list[str] = [] - def __init__(self, instance_name=None, read_only=None, collection=None): + def __init__(self, instance_name=None, read_only=None, no_delete=None, collection=None): if read_only is None: read_only = self.read_only if self.read_only and not read_only: raise exceptions.UserError("This storage can only be read-only.") self.read_only = bool(read_only) + if no_delete is None: + no_delete = self.no_delete + if self.no_delete and not no_delete: + raise exceptions.UserError("Nothing can be deleted in this storage.") + self.no_delete = bool(no_delete) + if collection and instance_name: instance_name = f"{instance_name}/{collection}" self.instance_name = instance_name diff --git a/vdirsyncer/sync/__init__.py b/vdirsyncer/sync/__init__.py index c84f977..b719c4d 100644 --- a/vdirsyncer/sync/__init__.py +++ b/vdirsyncer/sync/__init__.py @@ -243,7 +243,9 @@ class Delete(Action): async def _run_impl(self, a, b): meta = self.dest.status.get_new(self.ident) - if not self.dest.storage.read_only: + if self.dest.storage.read_only or self.dest.storage.no_delete: + sync_logger.debug(f"Skipping deletion of item {self.ident} from {self.dest.storage}") + else: sync_logger.info(f"Deleting item {self.ident} from {self.dest.storage}") await self.dest.storage.delete(meta.href, meta.etag)