aboutsummaryrefslogtreecommitdiff
path: root/bindings
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2018-02-04 15:33:34 -0500
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>2018-02-04 15:33:34 -0500
commitd9be1028d47cb7e98b474df420858a690798810b (patch)
treefb37f83ca098129a5301ef141dc6a5007a0972a9 /bindings
parenta8fb877ad7e960d69ec10887ff79e24bb99c587c (diff)
parent3c4e64d976eb561ac5157df1bbe5882e3e65b583 (diff)
Merge tag 'debian/0.26-1' into debian/stretch-backports
notmuch Debian 0.26-1 upload (same as 0.26)
Diffstat (limited to 'bindings')
-rw-r--r--bindings/python/.gitignore2
-rw-r--r--bindings/python/README2
-rw-r--r--bindings/python/debian/changelog5
-rw-r--r--bindings/python/debian/compat1
-rw-r--r--bindings/python/debian/control18
-rw-r--r--bindings/python/debian/copyright42
-rw-r--r--bindings/python/debian/docs1
-rwxr-xr-xbindings/python/debian/rules4
-rw-r--r--bindings/python/docs/source/database.rst8
-rw-r--r--bindings/python/notmuch/database.py174
-rw-r--r--bindings/python/notmuch/directory.py2
-rw-r--r--bindings/python/notmuch/globals.py10
-rw-r--r--bindings/python/notmuch/message.py10
-rw-r--r--bindings/python/notmuch/version.py2
-rw-r--r--bindings/ruby/.gitignore6
-rw-r--r--bindings/ruby/database.c2
16 files changed, 199 insertions, 90 deletions
diff --git a/bindings/python/.gitignore b/bindings/python/.gitignore
index da0732e9..601acdd7 100644
--- a/bindings/python/.gitignore
+++ b/bindings/python/.gitignore
@@ -1,4 +1,4 @@
*.py[co]
/docs/build
/docs/html
-build/
+/build/
diff --git a/bindings/python/README b/bindings/python/README
index fe7a2181..5bf076d2 100644
--- a/bindings/python/README
+++ b/bindings/python/README
@@ -3,7 +3,7 @@ notmuch -- The python interface to notmuch
This module makes the functionality of the notmuch library
(`https://notmuchmail.org`_) available to python. Successful import of
-this modul depends on a libnotmuch.so|dll being available on the
+this module depends on a libnotmuch.so|dll being available on the
user's system.
If you have downloaded the full source tarball, you can create the
diff --git a/bindings/python/debian/changelog b/bindings/python/debian/changelog
deleted file mode 100644
index 39ac7bb0..00000000
--- a/bindings/python/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-cnotmuch (0.2.1-1) karmic; urgency=low
-
- * Initial release
-
- -- Sebastian Spaeth <Sebastian@SSpaeth.de> Tue, 30 Mar 2010 11:31:39 +0200
diff --git a/bindings/python/debian/compat b/bindings/python/debian/compat
deleted file mode 100644
index 7f8f011e..00000000
--- a/bindings/python/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-7
diff --git a/bindings/python/debian/control b/bindings/python/debian/control
deleted file mode 100644
index 5135f1bb..00000000
--- a/bindings/python/debian/control
+++ /dev/null
@@ -1,18 +0,0 @@
-Source: cnotmuch
-Section: python
-Priority: extra
-Maintainer: Sebastian Spaeth <Sebastian@SSpaeth.de>
-Build-Depends: debhelper (>= 7.3.0), python-support (>= 0.5.3)
-Build-Depends-Indep: python (>= 2.5), python-support
-Standards-Version: 3.8.1
-Homepage: http://pypi.python.org/pypi/cnotmuch
-
-Package: cnotmuch
-Architecture: all
-XB-Python-Version: ${python:Versions}
-Depends: ${misc:Depends},${python:Depends}, notmuch (> 0.0+201001211401)
-Description: Interface to the notmuch mail search and index library
- The cnotmuch module provides an interface to the notmuch functionality,
- directly interfacing with a shared notmuch library.
- Notmuch provides a maildatabase that allows for extremely quick searching and
- filtering of your email according to various criteria.
diff --git a/bindings/python/debian/copyright b/bindings/python/debian/copyright
deleted file mode 100644
index d762cb93..00000000
--- a/bindings/python/debian/copyright
+++ /dev/null
@@ -1,42 +0,0 @@
-This package was debianized by:
-
- Sebastian Spaeth <Sebastian@SSpaeth.de> on Tue, 30 Mar 2010 10:02:22 +0200
-
-It was downloaded from:
-
- http://pypi.python.org/packages/source/c/cnotmuch/cnotmuch-0.2.1.tar.gz
-
-Upstream Author(s):
-
- Sebastian Spaeth <Sebastian@SSpaeth.de>
-
-Copyright:
-
- Copyright (C) 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
-
-License:
-
- This package is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This package is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this package; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-On Debian systems, the complete text of the GNU General
-Public License version 2 can be found in `/usr/share/common-licenses/GPL-2'.
-
-The Debian packaging is:
-
- Copyright (C) 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
-
-and is licensed under the GPL version 3,
-see `/usr/share/common-licenses/GPL-3'.
-
diff --git a/bindings/python/debian/docs b/bindings/python/debian/docs
deleted file mode 100644
index e845566c..00000000
--- a/bindings/python/debian/docs
+++ /dev/null
@@ -1 +0,0 @@
-README
diff --git a/bindings/python/debian/rules b/bindings/python/debian/rules
deleted file mode 100755
index 2d33f6ac..00000000
--- a/bindings/python/debian/rules
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/make -f
-
-%:
- dh $@
diff --git a/bindings/python/docs/source/database.rst b/bindings/python/docs/source/database.rst
index 5f1cdc14..660de91d 100644
--- a/bindings/python/docs/source/database.rst
+++ b/bindings/python/docs/source/database.rst
@@ -25,7 +25,7 @@
.. automethod:: get_directory
- .. automethod:: add_message
+ .. automethod:: index_file
.. automethod:: remove_message
@@ -37,6 +37,12 @@
.. automethod:: create_query
+ .. automethod:: get_config
+
+ .. automethod:: get_configs
+
+ .. automethod:: set_config
+
.. attribute:: Database.MODE
Defines constants that are used as the mode in which to open a database.
diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py
index 8f918069..a1ae14fc 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -19,14 +19,17 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
import os
import codecs
+import warnings
from ctypes import c_char_p, c_void_p, c_uint, byref, POINTER
from .compat import SafeConfigParser
from .globals import (
nmlib,
Enum,
_str,
+ NotmuchConfigListP,
NotmuchDatabaseP,
NotmuchDirectoryP,
+ NotmuchIndexoptsP,
NotmuchMessageP,
NotmuchTagsP,
)
@@ -71,6 +74,9 @@ class Database(object):
MODE = Enum(['READ_ONLY', 'READ_WRITE'])
"""Constants: Mode in which to open the database"""
+ DECRYPTION_POLICY = Enum(['FALSE', 'TRUE', 'AUTO', 'NOSTASH'])
+ """Constants: policies for decrypting messages during indexing"""
+
"""notmuch_database_get_directory"""
_get_directory = nmlib.notmuch_database_get_directory
_get_directory.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(NotmuchDirectoryP)]
@@ -285,7 +291,7 @@ class Database(object):
"""Does this database need to be upgraded before writing to it?
If this function returns `True` then no functions that modify the
- database (:meth:`add_message`,
+ database (:meth:`index_file`,
:meth:`Message.add_tag`, :meth:`Directory.set_mtime`,
etc.) will work unless :meth:`upgrade` is called successfully first.
@@ -311,7 +317,7 @@ class Database(object):
"""
self._assert_db_is_initialized()
status = Database._upgrade(self._db, None, None)
- #TODO: catch exceptions, document return values and etc
+ # TODO: catch exceptions, document return values and etc
return status
_begin_atomic = nmlib.notmuch_database_begin_atomic
@@ -399,12 +405,25 @@ class Database(object):
# return the Directory, init it with the absolute path
return Directory(abs_dirpath, dir_p, self)
- _add_message = nmlib.notmuch_database_add_message
- _add_message.argtypes = [NotmuchDatabaseP, c_char_p,
+ _get_default_indexopts = nmlib.notmuch_database_get_default_indexopts
+ _get_default_indexopts.argtypes = [NotmuchDatabaseP]
+ _get_default_indexopts.restype = NotmuchIndexoptsP
+
+ _indexopts_set_decrypt_policy = nmlib.notmuch_indexopts_set_decrypt_policy
+ _indexopts_set_decrypt_policy.argtypes = [NotmuchIndexoptsP, c_uint]
+ _indexopts_set_decrypt_policy.restype = None
+
+ _indexopts_destroy = nmlib.notmuch_indexopts_destroy
+ _indexopts_destroy.argtypes = [NotmuchIndexoptsP]
+ _indexopts_destroy.restype = None
+
+ _index_file = nmlib.notmuch_database_index_file
+ _index_file.argtypes = [NotmuchDatabaseP, c_char_p,
+ c_void_p,
POINTER(NotmuchMessageP)]
- _add_message.restype = c_uint
+ _index_file.restype = c_uint
- def add_message(self, filename, sync_maildir_flags=False):
+ def index_file(self, filename, sync_maildir_flags=False, decrypt_policy=None):
"""Adds a new message to the database
:param filename: should be a path relative to the path of the
@@ -425,6 +444,23 @@ class Database(object):
API. You might want to look into the underlying method
:meth:`Message.maildir_flags_to_tags`.
+ :param decrypt_policy: If the message contains any encrypted
+ parts, and decrypt_policy is set to
+ :attr:`DECRYPTION_POLICY`.TRUE, notmuch will try to
+ decrypt the message and index the cleartext, stashing any
+ discovered session keys. If it is set to
+ :attr:`DECRYPTION_POLICY`.FALSE, it will never try to
+ decrypt during indexing. If it is set to
+ :attr:`DECRYPTION_POLICY`.AUTO, then it will try to use
+ any stashed session keys it knows about, but will not try
+ to access the user's secret keys.
+ :attr:`DECRYPTION_POLICY`.NOSTASH behaves the same as
+ :attr:`DECRYPTION_POLICY`.TRUE except that no session keys
+ are stashed in the database. If decrypt_policy is set to
+ None (the default), then the database itself will decide
+ whether to decrypt, based on the `index.decrypt`
+ configuration setting (see notmuch-config(1)).
+
:returns: On success, we return
1) a :class:`Message` object that can be used for things
@@ -455,7 +491,15 @@ class Database(object):
"""
self._assert_db_is_initialized()
msg_p = NotmuchMessageP()
- status = self._add_message(self._db, _str(filename), byref(msg_p))
+ indexopts = c_void_p(None)
+ if decrypt_policy is not None:
+ indexopts = self._get_default_indexopts(self._db)
+ self._indexopts_set_decrypt_policy(indexopts, decrypt_policy)
+
+ status = self._index_file(self._db, _str(filename), indexopts, byref(msg_p))
+
+ if indexopts:
+ self._indexopts_destroy(indexopts)
if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
raise NotmuchError(status)
@@ -467,6 +511,14 @@ class Database(object):
msg.maildir_flags_to_tags()
return (msg, status)
+ def add_message(self, filename, sync_maildir_flags=False):
+ """Deprecated alias for :meth:`index_file`
+ """
+ warnings.warn(
+ "This function is deprecated and will be removed in the future, use index_file.", DeprecationWarning)
+
+ return self.index_file(filename, sync_maildir_flags=sync_maildir_flags)
+
_remove_message = nmlib.notmuch_database_remove_message
_remove_message.argtypes = [NotmuchDatabaseP, c_char_p]
_remove_message.restype = c_uint
@@ -624,3 +676,111 @@ class Database(object):
raise NotmuchError(message="No DB path specified"
" and no user default found")
return config.get('database', 'path')
+
+ """notmuch_database_get_config"""
+ _get_config = nmlib.notmuch_database_get_config
+ _get_config.argtypes = [NotmuchDatabaseP, c_char_p, POINTER(c_char_p)]
+ _get_config.restype = c_uint
+
+ def get_config(self, key):
+ """Return the value of the given config key.
+
+ Note that only config values that are stored in the database are
+ searched and returned. The config file is not read.
+
+ :param key: the config key under which a value should be looked up, it
+ should probably be in the form "section.key"
+ :type key: str
+ :returns: the config value or the empty string if no value is present
+ for that key
+ :rtype: str
+ :raises: :exc:`NotmuchError` in case of failure.
+
+ """
+ self._assert_db_is_initialized()
+ return_string = c_char_p()
+ status = self._get_config(self._db, _str(key), byref(return_string))
+ if status != STATUS.SUCCESS:
+ raise NotmuchError(status)
+ return return_string.value.decode('utf-8')
+
+ """notmuch_database_get_config_list"""
+ _get_config_list = nmlib.notmuch_database_get_config_list
+ _get_config_list.argtypes = [NotmuchDatabaseP, c_char_p,
+ POINTER(NotmuchConfigListP)]
+ _get_config_list.restype = c_uint
+
+ _config_list_valid = nmlib.notmuch_config_list_valid
+ _config_list_valid.argtypes = [NotmuchConfigListP]
+ _config_list_valid.restype = bool
+
+ _config_list_key = nmlib.notmuch_config_list_key
+ _config_list_key.argtypes = [NotmuchConfigListP]
+ _config_list_key.restype = c_char_p
+
+ _config_list_value = nmlib.notmuch_config_list_value
+ _config_list_value.argtypes = [NotmuchConfigListP]
+ _config_list_value.restype = c_char_p
+
+ _config_list_move_to_next = nmlib.notmuch_config_list_move_to_next
+ _config_list_move_to_next.argtypes = [NotmuchConfigListP]
+ _config_list_move_to_next.restype = None
+
+ _config_list_destroy = nmlib.notmuch_config_list_destroy
+ _config_list_destroy.argtypes = [NotmuchConfigListP]
+ _config_list_destroy.restype = None
+
+ def get_configs(self, prefix=''):
+ """Return a generator of key, value pairs where the start of key
+ matches the given prefix
+
+ Note that only config values that are stored in the database are
+ searched and returned. The config file is not read. If no `prefix` is
+ given all config values are returned.
+
+ This could be used to get all named queries into a dict for example::
+
+ queries = {k[6:]: v for k, v in db.get_configs('query.')}
+
+ :param prefix: a string by which the keys should be selected
+ :type prefix: str
+ :yields: all key-value pairs where `prefix` matches the beginning
+ of the key
+ :ytype: pairs of str
+ :raises: :exc:`NotmuchError` in case of failure.
+
+ """
+ self._assert_db_is_initialized()
+ config_list_p = NotmuchConfigListP()
+ status = self._get_config_list(self._db, _str(prefix),
+ byref(config_list_p))
+ if status != STATUS.SUCCESS:
+ raise NotmuchError(status)
+ while self._config_list_valid(config_list_p):
+ key = self._config_list_key(config_list_p).decode('utf-8')
+ value = self._config_list_value(config_list_p).decode('utf-8')
+ yield key, value
+ self._config_list_move_to_next(config_list_p)
+
+ """notmuch_database_set_config"""
+ _set_config = nmlib.notmuch_database_set_config
+ _set_config.argtypes = [NotmuchDatabaseP, c_char_p, c_char_p]
+ _set_config.restype = c_uint
+
+ def set_config(self, key, value):
+ """Set a config value in the notmuch database.
+
+ If an empty string is provided as `value` the `key` is unset!
+
+ :param key: the key to set
+ :type key: str
+ :param value: the value to store under `key`
+ :type value: str
+ :returns: None
+ :raises: :exc:`NotmuchError` in case of failure.
+
+ """
+ self._assert_db_is_initialized()
+ status = self._set_config(self._db, _str(key), _str(value))
+ if status != STATUS.SUCCESS:
+ raise NotmuchError(status)
diff --git a/bindings/python/notmuch/directory.py b/bindings/python/notmuch/directory.py
index 7f86b1ac..b30c9e35 100644
--- a/bindings/python/notmuch/directory.py
+++ b/bindings/python/notmuch/directory.py
@@ -93,7 +93,7 @@ class Directory(object):
* Read the mtime of a directory from the filesystem
- * Call :meth:`Database.add_message` for all mail files in
+ * Call :meth:`Database.index_file` for all mail files in
the directory
* Call notmuch_directory_set_mtime with the mtime read from the
diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index b1eec2cf..97413996 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -88,3 +88,13 @@ NotmuchDirectoryP = POINTER(NotmuchDirectoryS)
class NotmuchFilenamesS(Structure):
pass
NotmuchFilenamesP = POINTER(NotmuchFilenamesS)
+
+
+class NotmuchConfigListS(Structure):
+ pass
+NotmuchConfigListP = POINTER(NotmuchConfigListS)
+
+
+class NotmuchIndexoptsS(Structure):
+ pass
+NotmuchIndexoptsP = POINTER(NotmuchIndexoptsS)
diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py
index fc177eb2..d5b98e4f 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -41,6 +41,7 @@ from .tag import Tags
from .filenames import Filenames
import email
+import sys
class Message(Python3StringMixIn):
@@ -566,7 +567,7 @@ class Message(Python3StringMixIn):
logical OR operator.)
As a convenience, you can set the sync_maildir_flags parameter in
- :meth:`Database.add_message` to implicitly call this.
+ :meth:`Database.index_file` to implicitly call this.
:returns: a :class:`STATUS`. In short, you want to see
notmuch.STATUS.SUCCESS here. See there for details."""
@@ -587,8 +588,11 @@ class Message(Python3StringMixIn):
def get_message_parts(self):
"""Output like notmuch show"""
- fp = open(self.get_filename())
- email_msg = email.message_from_file(fp)
+ fp = open(self.get_filename(), 'rb')
+ if sys.version_info[0] < 3:
+ email_msg = email.message_from_file(fp)
+ else:
+ email_msg = email.message_from_binary_file(fp)
fp.close()
out = []
diff --git a/bindings/python/notmuch/version.py b/bindings/python/notmuch/version.py
index 62dd1f19..bc246330 100644
--- a/bindings/python/notmuch/version.py
+++ b/bindings/python/notmuch/version.py
@@ -1,3 +1,3 @@
# this file should be kept in sync with ../../../version
-__VERSION__ = '0.25'
+__VERSION__ = '0.26'
SOVERSION = '5'
diff --git a/bindings/ruby/.gitignore b/bindings/ruby/.gitignore
index d682798a..c57ae63f 100644
--- a/bindings/ruby/.gitignore
+++ b/bindings/ruby/.gitignore
@@ -1,7 +1,7 @@
# .gitignore for bindings/ruby
# Generated files
-Makefile
-mkmf.log
-notmuch.so
+/Makefile
+/mkmf.log
+/notmuch.so
*.o
diff --git a/bindings/ruby/database.c b/bindings/ruby/database.c
index 12e6bab7..416eb709 100644
--- a/bindings/ruby/database.c
+++ b/bindings/ruby/database.c
@@ -291,7 +291,7 @@ notmuch_rb_database_add_message (VALUE self, VALUE pathv)
SafeStringValue (pathv);
path = RSTRING_PTR (pathv);
- ret = notmuch_database_add_message (db, path, &message);
+ ret = notmuch_database_index_file (db, path, NULL, &message);
notmuch_rb_status_raise (ret);
return rb_assoc_new (Data_Wrap_Struct (notmuch_rb_cMessage, NULL, NULL, message),
(ret == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) ? Qtrue : Qfalse);