From 6a3077f9dc9b28716ed729fd51f0c3bf7e83973d Mon Sep 17 00:00:00 2001 From: chrisblech Date: Mon, 1 Jan 2024 16:55:31 +0100 Subject: [PATCH] add `pre_deletion_hook` closes https://github.com/pimutils/vdirsyncer/issues/1107 --- docs/config.rst | 3 +++ vdirsyncer/storage/filesystem.py | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/docs/config.rst b/docs/config.rst index fd982fb..e204d69 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -378,6 +378,7 @@ Local fileext = "..." #encoding = "utf-8" #post_hook = null + #pre_deletion_hook = null #fileignoreext = ".tmp" Can be used with `khal `_. See :doc:`vdir` for @@ -399,6 +400,8 @@ Local :param post_hook: A command to call for each item creation and modification. The command will be called with the path of the new/updated file. + :param pre_deletion_hook: A command to call for each item deletion. + The command will be called with the path of the deleted file. :param fileeignoreext: The file extention to ignore. It is only useful if fileext is set to the empty string. The default is ``.tmp``. diff --git a/vdirsyncer/storage/filesystem.py b/vdirsyncer/storage/filesystem.py index 0be62b4..8de243b 100644 --- a/vdirsyncer/storage/filesystem.py +++ b/vdirsyncer/storage/filesystem.py @@ -29,6 +29,7 @@ class FilesystemStorage(Storage): fileext, encoding="utf-8", post_hook=None, + pre_deletion_hook=None, fileignoreext=".tmp", **kwargs, ): @@ -40,6 +41,7 @@ class FilesystemStorage(Storage): self.fileext = fileext self.fileignoreext = fileignoreext self.post_hook = post_hook + self.pre_deletion_hook = pre_deletion_hook @classmethod async def discover(cls, path, **kwargs): @@ -166,6 +168,9 @@ class FilesystemStorage(Storage): actual_etag = get_etag_from_file(fpath) if etag != actual_etag: raise exceptions.WrongEtagError(etag, actual_etag) + if self.pre_deletion_hook: + self._run_pre_deletion_hook(fpath) + os.remove(fpath) def _run_post_hook(self, fpath): @@ -175,6 +180,13 @@ class FilesystemStorage(Storage): except OSError as e: logger.warning(f"Error executing external hook: {str(e)}") + def _run_pre_deletion_hook(self, fpath): + logger.info(f"Calling pre_deletion_hook={self.pre_deletion_hook} with argument={fpath}") + try: + subprocess.call([self.pre_deletion_hook, fpath]) + except OSError as e: + logger.warning(f"Error executing external hook: {str(e)}") + async def get_meta(self, key): fpath = os.path.join(self.path, key) try: