]> git.notmuchmail.org Git - notmuch/blobdiff - bindings/python-cffi/notmuch2/_database.py
python/notmuch2: add bindings for the database config strings
[notmuch] / bindings / python-cffi / notmuch2 / _database.py
index a15c4d0324576261c89a71d59de5edd217314b91..3c06402dcc35ed356850bc2d5c2cff59f5542094 100644 (file)
@@ -7,6 +7,7 @@ import pathlib
 import weakref
 
 import notmuch2._base as base
+import notmuch2._config as config
 import notmuch2._capi as capi
 import notmuch2._errors as errors
 import notmuch2._message as message
@@ -45,6 +46,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.
 
@@ -255,7 +263,7 @@ class Database(base.NotmuchObject):
 
         This is returned as a :class:`pathlib.Path` instance.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         try:
             return self._cache_path
@@ -270,7 +278,7 @@ class Database(base.NotmuchObject):
 
         This is a positive integer.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         try:
             return self._cache_version
@@ -289,7 +297,7 @@ class Database(base.NotmuchObject):
 
         A read-only database will never be upgradable.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_database_needs_upgrade(self._db_p)
         return bool(ret)
@@ -313,7 +321,7 @@ class Database(base.NotmuchObject):
            not imply durability, it only ensures the changes are
            performed atomically.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ctx = AtomicContext(self, '_db_p')
         return ctx
@@ -323,7 +331,7 @@ class Database(base.NotmuchObject):
 
         Returned as a ``(revision, uuid)`` namedtuple.
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         raw_uuid = capi.ffi.new('char**')
         rev = capi.lib.notmuch_database_get_revision(self._db_p, raw_uuid)
@@ -332,7 +340,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 ObjectDestroyedError: 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 +364,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
@@ -365,14 +388,14 @@ class Database(base.NotmuchObject):
            READ_ONLY mode.
         :raises UpgradeRequiredError: The database must be upgraded
            first.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         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:
@@ -404,7 +427,7 @@ class Database(base.NotmuchObject):
            READ_ONLY mode.
         :raises UpgradeRequiredError: The database must be upgraded
            first.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         if not hasattr(os, 'PathLike') and isinstance(filename, pathlib.Path):
             filename = bytes(filename)
@@ -436,7 +459,7 @@ class Database(base.NotmuchObject):
         :raises OutOfMemoryError: When there is no memory to allocate
            the message instance.
         :raises XapianError: A Xapian exception ocurred.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         msg_pp = capi.ffi.new('notmuch_message_t **')
         ret = capi.lib.notmuch_database_find_message(self._db_p,
@@ -467,7 +490,7 @@ class Database(base.NotmuchObject):
         :raises OutOfMemoryError: When there is no memory to allocate
            the message instance.
         :raises XapianError: A Xapian exception ocurred.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         if not hasattr(os, 'PathLike') and isinstance(filename, pathlib.Path):
             filename = bytes(filename)
@@ -500,7 +523,7 @@ class Database(base.NotmuchObject):
 
         :rtype: ImmutableTagSet
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         try:
             ref = self._cached_tagset
@@ -514,6 +537,28 @@ class Database(base.NotmuchObject):
             self._cached_tagset = weakref.ref(tagset)
         return tagset
 
+    @property
+    def config(self):
+        """Return a mutable mapping with the settings stored in this database.
+
+        This returns an mutable dict-like object implementing the
+        collections.abc.MutableMapping Abstract Base Class.
+
+        :rtype: Config
+
+        :raises ObjectDestroyedError: if used after destroyed.
+        """
+        try:
+            ref = self._cached_config
+        except AttributeError:
+            config_mapping = None
+        else:
+            config_mapping = ref()
+        if config_mapping is None:
+            config_mapping = config.ConfigMapping(self, '_db_p')
+            self._cached_config = weakref.ref(config_mapping)
+        return config_mapping
+
     def _create_query(self, query, *,
                       omit_excluded=EXCLUDE.TRUE,
                       sort=SORT.UNSORTED,  # Check this default
@@ -548,7 +593,7 @@ class Database(base.NotmuchObject):
 
         :raises OutOfMemoryError: if no memory is available to
            allocate the query.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         query = self._create_query(query,
                                    omit_excluded=omit_excluded,
@@ -565,7 +610,7 @@ class Database(base.NotmuchObject):
         :returns: An iterator over the messages found.
         :rtype: MessageIter
 
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         query = self._create_query(query,
                                    omit_excluded=omit_excluded,
@@ -613,7 +658,7 @@ class AtomicContext:
        section is not active.  When it is raised at exit time the
        atomic section is still active and you may need to try using
        :meth:`force_end`.
-    :raises ObjectDestroyedError: if used after destoryed.
+    :raises ObjectDestroyedError: if used after destroyed.
     """
 
     def __init__(self, db, ptr_name):
@@ -653,7 +698,7 @@ class AtomicContext:
            not ended.
         :raises UnbalancedAtomicError: If the database was currently
            not in an atomic section.
-        :raises ObjectDestroyedError: if used after destoryed.
+        :raises ObjectDestroyedError: if used after destroyed.
         """
         ret = capi.lib.notmuch_database_end_atomic(self._ptr())
         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
@@ -703,3 +748,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 ObjectDestroyedError: 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)