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
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.
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
This is a positive integer.
- :raises ObjectDestroyedError: if used after destoryed.
+ :raises ObjectDestroyedError: if used after destroyed.
"""
try:
return self._cache_version
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)
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
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)
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
: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
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:
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)
: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,
: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)
:rtype: ImmutableTagSet
- :raises ObjectDestroyedError: if used after destoryed.
+ :raises ObjectDestroyedError: if used after destroyed.
"""
try:
ref = self._cached_tagset
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
: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,
: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,
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):
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:
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)