From 1e072204cd1963fbf684cdc9c92092efb2d44924 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Sun, 17 Nov 2019 20:24:46 +0100 Subject: [PATCH] Move from _add_message to _index_file API This moves away from the deprecated notmuch_database_add_message API and instead uses the notmuch_database_index_file API. This means instroducing a class to manage the index options and bumping the library version requirement to 5.1. --- bindings/python-cffi/notmuch2/_build.py | 26 ++++++- bindings/python-cffi/notmuch2/_database.py | 88 +++++++++++++++++++++- 2 files changed, 107 insertions(+), 7 deletions(-) diff --git a/bindings/python-cffi/notmuch2/_build.py b/bindings/python-cffi/notmuch2/_build.py index 3ba3e558..5e1fcac1 100644 --- a/bindings/python-cffi/notmuch2/_build.py +++ b/bindings/python-cffi/notmuch2/_build.py @@ -12,6 +12,9 @@ ffibuilder.set_source( #if LIBNOTMUCH_MAJOR_VERSION < 5 #error libnotmuch version not supported by notmuch2 python bindings #endif + #if LIBNOTMUCH_MINOR_VERSION < 1 + #ERROR libnotmuch version < 5.1 not supported + #endif """, include_dirs=['../../lib'], library_dirs=['../../lib'], @@ -68,6 +71,12 @@ ffibuilder.cdef( NOTMUCH_EXCLUDE_FALSE, NOTMUCH_EXCLUDE_ALL } notmuch_exclude_t; + typedef enum { + NOTMUCH_DECRYPT_FALSE, + NOTMUCH_DECRYPT_TRUE, + NOTMUCH_DECRYPT_AUTO, + NOTMUCH_DECRYPT_NOSTASH, + } notmuch_decryption_policy_t; // These are fully opaque types for us, we only ever use pointers. typedef struct _notmuch_database notmuch_database_t; @@ -81,6 +90,7 @@ ffibuilder.cdef( typedef struct _notmuch_directory notmuch_directory_t; typedef struct _notmuch_filenames notmuch_filenames_t; typedef struct _notmuch_config_list notmuch_config_list_t; + typedef struct _notmuch_indexopts notmuch_indexopts_t; const char * notmuch_status_to_string (notmuch_status_t status); @@ -118,9 +128,10 @@ ffibuilder.cdef( notmuch_database_get_revision (notmuch_database_t *notmuch, const char **uuid); notmuch_status_t - notmuch_database_add_message (notmuch_database_t *database, - const char *filename, - notmuch_message_t **message); + notmuch_database_index_file (notmuch_database_t *database, + const char *filename, + notmuch_indexopts_t *indexopts, + notmuch_message_t **message); notmuch_status_t notmuch_database_remove_message (notmuch_database_t *database, const char *filename); @@ -294,6 +305,15 @@ ffibuilder.cdef( notmuch_filenames_move_to_next (notmuch_filenames_t *filenames); void notmuch_filenames_destroy (notmuch_filenames_t *filenames); + notmuch_indexopts_t * + notmuch_database_get_default_indexopts (notmuch_database_t *db); + notmuch_status_t + notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts, + notmuch_decryption_policy_t decrypt_policy); + notmuch_decryption_policy_t + notmuch_indexopts_get_decrypt_policy (const notmuch_indexopts_t *indexopts); + void + notmuch_indexopts_destroy (notmuch_indexopts_t *options); """ ) diff --git a/bindings/python-cffi/notmuch2/_database.py b/bindings/python-cffi/notmuch2/_database.py index a15c4d03..a1c624a7 100644 --- a/bindings/python-cffi/notmuch2/_database.py +++ b/bindings/python-cffi/notmuch2/_database.py @@ -45,6 +45,13 @@ class QueryExclude(enum.Enum): ALL = capi.lib.NOTMUCH_EXCLUDE_ALL +class DecryptionPolicy(enum.Enum): + FALSE = capi.lib.NOTMUCH_DECRYPT_FALSE + TRUE = capi.lib.NOTMUCH_DECRYPT_TRUE + AUTO = capi.lib.NOTMUCH_DECRYPT_AUTO + NOSTASH = capi.lib.NOTMUCH_DECRYPT_NOSTASH + + class Database(base.NotmuchObject): """Toplevel access to notmuch. @@ -332,7 +339,17 @@ class Database(base.NotmuchObject): def get_directory(self, path): raise NotImplementedError - def add(self, filename, *, sync_flags=False): + def default_indexopts(self): + """Returns default index options for the database. + + :raises ObjectDestoryedError: if used after destroyed. + + :returns: :class:`IndexOptions`. + """ + opts = capi.lib.notmuch_database_get_default_indexopts(self._db_p) + return IndexOptions(self, opts) + + def add(self, filename, *, sync_flags=False, indexopts=None): """Add a message to the database. Add a new message to the notmuch database. The message is @@ -346,6 +363,11 @@ class Database(base.NotmuchObject): :param sync_flags: Whether to sync the known maildir flags to notmuch tags. See :meth:`Message.flags_to_tags` for details. + :type sync_flags: bool + :param indexopts: The indexing options, see + :meth:`default_indexopts`. Leave as `None` to use the + default options configured in the database. + :type indexopts: :class:`IndexOptions` or `None` :returns: A tuple where the first item is the newly inserted messages as a :class:`Message` instance, and the second @@ -370,9 +392,9 @@ class Database(base.NotmuchObject): if not hasattr(os, 'PathLike') and isinstance(filename, pathlib.Path): filename = bytes(filename) msg_pp = capi.ffi.new('notmuch_message_t **') - ret = capi.lib.notmuch_database_add_message(self._db_p, - os.fsencode(filename), - msg_pp) + opts_p = indexopts._opts_p if indexopts else capi.ffi.NULL + ret = capi.lib.notmuch_database_index_file( + self._db_p, os.fsencode(filename), opts_p, msg_pp) ok = [capi.lib.NOTMUCH_STATUS_SUCCESS, capi.lib.NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID] if ret not in ok: @@ -703,3 +725,61 @@ class DbRevision: def __repr__(self): return 'DbRevision(rev={self.rev}, uuid={self.uuid})'.format(self=self) + + +class IndexOptions(base.NotmuchObject): + """Indexing options. + + This represents the indexing options which can be used to index a + message. See :meth:`Database.default_indexopts` to create an + instance of this. It can be used e.g. when indexing a new message + using :meth:`Database.add`. + """ + _opts_p = base.MemoryPointer() + + def __init__(self, parent, opts_p): + self._parent = parent + self._opts_p = opts_p + + @property + def alive(self): + if not self._parent.alive: + return False + try: + self._opts_p + except errors.ObjectDestroyedError: + return False + else: + return True + + def _destroy(self): + if self.alive: + capi.lib.notmuch_indexopts_destroy(self._opts_p) + self._opts_p = None + + @property + def decrypt_policy(self): + """The decryption policy. + + This is an enum from the :class:`DecryptionPolicy`. See the + `index.decrypt` section in :man:`notmuch-config` for details + on the options. **Do not set this to + :attr:`DecryptionPolicy.TRUE`** without considering the + security of your index. + + You can change this policy by assigning a new + :class:`DecryptionPolicy` to this property. + + :raises ObjectDestoryedError: if used after destroyed. + + :returns: A :class:`DecryptionPolicy` enum instance. + """ + raw = capi.lib.notmuch_indexopts_get_decrypt_policy(self._opts_p) + return DecryptionPolicy(raw) + + @decrypt_policy.setter + def decrypt_policy(self, val): + ret = capi.lib.notmuch_indexopts_set_decrypt_policy( + self._opts_p, val.value) + if ret != capi.lib.NOTMUCH_STATUS_SUCCESS: + raise errors.NotmuchError(ret, msg) -- 2.43.0