diff options
| author | Daniel Kahn Gillmor <dkg@fifthhorseman.net> | 2018-02-04 15:33:34 -0500 |
|---|---|---|
| committer | Daniel Kahn Gillmor <dkg@fifthhorseman.net> | 2018-02-04 15:33:34 -0500 |
| commit | d9be1028d47cb7e98b474df420858a690798810b (patch) | |
| tree | fb37f83ca098129a5301ef141dc6a5007a0972a9 /bindings/python | |
| parent | a8fb877ad7e960d69ec10887ff79e24bb99c587c (diff) | |
| parent | 3c4e64d976eb561ac5157df1bbe5882e3e65b583 (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/python')
| -rw-r--r-- | bindings/python/.gitignore | 2 | ||||
| -rw-r--r-- | bindings/python/README | 2 | ||||
| -rw-r--r-- | bindings/python/debian/changelog | 5 | ||||
| -rw-r--r-- | bindings/python/debian/compat | 1 | ||||
| -rw-r--r-- | bindings/python/debian/control | 18 | ||||
| -rw-r--r-- | bindings/python/debian/copyright | 42 | ||||
| -rw-r--r-- | bindings/python/debian/docs | 1 | ||||
| -rwxr-xr-x | bindings/python/debian/rules | 4 | ||||
| -rw-r--r-- | bindings/python/docs/source/database.rst | 8 | ||||
| -rw-r--r-- | bindings/python/notmuch/database.py | 174 | ||||
| -rw-r--r-- | bindings/python/notmuch/directory.py | 2 | ||||
| -rw-r--r-- | bindings/python/notmuch/globals.py | 10 | ||||
| -rw-r--r-- | bindings/python/notmuch/message.py | 10 | ||||
| -rw-r--r-- | bindings/python/notmuch/version.py | 2 |
14 files changed, 195 insertions, 86 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' |
