From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 769D66DE00C6 for ; Tue, 1 May 2018 08:28:42 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: -0.006 X-Spam-Level: X-Spam-Status: No, score=-0.006 tagged_above=-999 required=5 tests=[AWL=0.005, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 69GexisNBakY for ; Tue, 1 May 2018 08:28:41 -0700 (PDT) Received: from anarres.sindominio.net (anarres.sindominio.net [88.99.208.38]) by arlo.cworth.org (Postfix) with ESMTPS id B846D6DE00B4 for ; Tue, 1 May 2018 08:28:40 -0700 (PDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by lesnaus.sindominio.net (Postfix) with ESMTP id 514591E43CB2; Tue, 1 May 2018 17:28:39 +0200 (CEST) Received: from anarres.sindominio.net ([127.0.0.1]) by localhost (lesnaus.sindominio.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QxrODa9KJ-rz; Tue, 1 May 2018 17:28:37 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lesnaus.sindominio.net (Postfix) with ESMTPSA id 816871E43C9F; Tue, 1 May 2018 17:28:36 +0200 (CEST) From: Ruben Pollan To: notmuch@notmuchmail.org Subject: [PATCH] python: add bindings for notmuch_message_get_propert(y/ies) Date: Tue, 1 May 2018 17:28:15 +0200 Message-Id: <20180501152815.20687-1-meskio@sindominio.net> X-Mailer: git-send-email 2.16.1 In-Reply-To: <152518827012.10626.6946716348121434660@localhost> References: <152518827012.10626.6946716348121434660@localhost> X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 May 2018 15:28:42 -0000 Message.get_property (prop) returns a string with the value of the property and Message.get_properties (prop, exact=False) yields key, value pairs --- bindings/python/docs/source/message.rst | 4 ++ bindings/python/notmuch/globals.py | 5 +++ bindings/python/notmuch/message.py | 80 ++++++++++++++++++++++++++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/bindings/python/docs/source/message.rst b/bindings/python/docs/source/message.rst index 1a6cc3d5..b0033924 100644 --- a/bindings/python/docs/source/message.rst +++ b/bindings/python/docs/source/message.rst @@ -33,6 +33,10 @@ .. automethod:: get_tags + .. automethod:: get_property + + .. automethod:: get_properties + .. automethod:: maildir_flags_to_tags .. automethod:: tags_to_maildir_flags diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py index 97413996..11e328b7 100644 --- a/bindings/python/notmuch/globals.py +++ b/bindings/python/notmuch/globals.py @@ -75,6 +75,11 @@ class NotmuchMessageS(Structure): NotmuchMessageP = POINTER(NotmuchMessageS) +class NotmuchMessagePropertiesS(Structure): + pass +NotmuchMessagePropertiesP = POINTER(NotmuchMessagePropertiesS) + + class NotmuchTagsS(Structure): pass NotmuchTagsP = POINTER(NotmuchTagsS) diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py index 1b1f2174..cc945037 100644 --- a/bindings/python/notmuch/message.py +++ b/bindings/python/notmuch/message.py @@ -19,7 +19,7 @@ Copyright 2010 Sebastian Spaeth """ -from ctypes import c_char_p, c_long, c_uint, c_int +from ctypes import c_char_p, c_long, c_uint, c_int, POINTER, byref from datetime import date from .globals import ( nmlib, @@ -29,6 +29,7 @@ from .globals import ( NotmuchTagsP, NotmuchMessageP, NotmuchMessagesP, + NotmuchMessagePropertiesP, NotmuchFilenamesP, ) from .errors import ( @@ -113,6 +114,36 @@ class Message(Python3StringMixIn): _maildir_flags_to_tags.argtypes = [NotmuchMessageP] _maildir_flags_to_tags.restype = c_int + """notmuch_message_get_property""" + _get_property = nmlib.notmuch_message_get_property + _get_property.argtypes = [NotmuchMessageP, c_char_p, POINTER(c_char_p)] + _get_property.restype = c_int + + """notmuch_message_get_properties""" + _get_properties = nmlib.notmuch_message_get_properties + _get_properties.argtypes = [NotmuchMessageP, c_char_p, c_int] + _get_properties.restype = NotmuchMessagePropertiesP + + """notmuch_message_properties_valid""" + _properties_valid = nmlib.notmuch_message_properties_valid + _properties_valid.argtypes = [NotmuchMessagePropertiesP] + _properties_valid.restype = bool + + """notmuch_message_properties_value""" + _properties_value = nmlib.notmuch_message_properties_value + _properties_value.argtypes = [NotmuchMessagePropertiesP] + _properties_value.restype = c_char_p + + """notmuch_message_properties_key""" + _properties_key = nmlib.notmuch_message_properties_key + _properties_key.argtypes = [NotmuchMessagePropertiesP] + _properties_key.restype = c_char_p + + """notmuch_message_properties_move_to_next""" + _properties_move_to_next = nmlib.notmuch_message_properties_move_to_next + _properties_move_to_next.argtypes = [NotmuchMessagePropertiesP] + _properties_move_to_next.restype = None + #Constants: Flags that can be set/get with set_flag FLAG = Enum(['MATCH']) @@ -433,6 +464,53 @@ class Message(Python3StringMixIn): _freeze.argtypes = [NotmuchMessageP] _freeze.restype = c_uint + def get_property(self, prop): + """ Retrieve the value for a single property key + + :param prop: The name of the property to get. + :returns: String with the property value or None if there is no such + key. In the case of multiple values for the given key, the + first one is retrieved. + :raises: :exc:`NotInitializedError` if message has not been + initialized + """ + if not self._msg: + raise NotInitializedError() + + value = c_char_p() + status = Message._get_property(self._msg, _str(prop), byref(value)) + if status != 0: + raise NotmuchError(status) + + return value.value.decode('utf-8') + + def get_properties(self, prop="", exact=False): + """ Get the properties of the message, returning a generator of + name, value pairs. + + The generator will yield once per value. There might be more than one + value on each name, so the generator might yield the same name several + times. + + :param prop: The name of the property to get. Otherwise it will return + the full list of properties of the message. + :param exact: if True, require exact match with key. Otherwise + treat as prefix. + :yields: Each property values as a pair of `name, value` + :ytype: pairs of str + :raises: :exc:`NotInitializedError` if message has not been + initialized + """ + if not self._msg: + raise NotInitializedError() + + properties = Message._get_properties(self._msg, _str(prop), exact) + while Message._properties_valid(properties): + key = Message._properties_key(properties) + value = Message._properties_value(properties) + yield key, value + Message._properties_move_to_next(properties) + def freeze(self): """Freezes the current state of 'message' within the database -- 2.16.1