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 65CC46DE0B25 for ; Wed, 29 Nov 2017 00:03:21 -0800 (PST) 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 2sRZpqbaz6Ge for ; Wed, 29 Nov 2017 00:03:20 -0800 (PST) Received: from eternauta.sindominio.net (eternauta.sindominio.net [80.81.122.47]) by arlo.cworth.org (Postfix) with ESMTPS id 1EF626DE0B14 for ; Wed, 29 Nov 2017 00:03:20 -0800 (PST) Received: from localhost (localhost.localdomain [127.0.0.1]) by lesnaus.sindominio.net (Postfix) with ESMTP id 2F6BE404F04; Wed, 29 Nov 2017 09:03:18 +0100 (CET) Received: from eternauta.sindominio.net ([127.0.0.1]) by localhost (lesnaus.sindominio.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id a_rm8CflEKmG; Wed, 29 Nov 2017 09:03:15 +0100 (CET) Received: from localhost (localhost.localdomain [127.0.0.1]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lesnaus.sindominio.net (Postfix) with ESMTPSA id BA874402D97; Wed, 29 Nov 2017 09:03:14 +0100 (CET) From: Ruben Pollan To: notmuch@notmuchmail.org Subject: [PATCH] python: add bindings for notmuch_message_get_propert(y/ies) Date: Wed, 29 Nov 2017 09:03:08 +0100 Message-Id: <20171129080308.21137-1-meskio@sindominio.net> X-Mailer: git-send-email 2.15.0 In-Reply-To: <151194252933.14333.11265370454778979590@localhost> References: <151194252933.14333.11265370454778979590@localhost> X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.23 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: Wed, 29 Nov 2017 08:03:21 -0000 Message.get_property (prop) returns a string with the value of the property and Message.get_properties (prop, exact=False) returns a list [(key, value)] --- bindings/python/notmuch/globals.py | 5 +++ bindings/python/notmuch/message.py | 81 +++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py index 71426c84..801062dc 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 d5b98e4f..2025f979 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,54 @@ 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, prop, byref(value)) + if status != 0: + raise NotmuchError(status) + + return value.value + + def get_properties(self, prop="", exact=False): + """ Get the properties for *message*, returning + notmuch_message_properties_t object which can be used to iterate + over all properties. + + :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. + :returns: A dictionary with the property names and values {key: value} + :raises: :exc:`NotInitializedError` if message has not been + initialized + """ + if not self._msg: + raise NotInitializedError() + + properties_dict = {} + properties = Message._get_properties(self._msg, prop, exact) + while Message._properties_valid(properties): + key = Message._properties_key(properties) + value = Message._properties_value(properties) + if key not in properties_dict: + properties_dict[key] = [] + properties_dict[key].append(value) + Message._properties_move_to_next(properties) + + return properties_dict + def freeze(self): """Freezes the current state of 'message' within the database -- 2.15.0