+ def add_tag(self, tag):
+ """Add a tag to the given message
+
+ Adds a tag to the current message. The maximal tag length is defined in
+ the notmuch library and is currently 200 bytes.
+
+ :param tag: String with a 'tag' to be added.
+ :returns: STATUS.SUCCESS if the tag was successfully added.
+ Raises an exception otherwise.
+ :exception: :exc:`NotmuchError`. They have the following meaning:
+
+ STATUS.NULL_POINTER
+ The 'tag' argument is NULL
+ STATUS.TAG_TOO_LONG
+ The length of 'tag' is too long
+ (exceeds Message.NOTMUCH_TAG_MAX)
+ STATUS.READ_ONLY_DATABASE
+ Database was opened in read-only mode so message cannot be
+ modified.
+ STATUS.NOT_INITIALIZED
+ The message has not been initialized.
+ """
+ if self._msg is None:
+ raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+ status = nmlib.notmuch_message_add_tag (self._msg, tag)
+
+ if STATUS.SUCCESS == status:
+ # return on success
+ return status
+
+ raise NotmuchError(status)
+
+ def remove_tag(self, tag):
+ """Removes a tag from the given message
+
+ If the message has no such tag, this is a non-operation and
+ will report success anyway.
+
+ :param tag: String with a 'tag' to be removed.
+ :returns: STATUS.SUCCESS if the tag was successfully removed or if
+ the message had no such tag.
+ Raises an exception otherwise.
+ :exception: :exc:`NotmuchError`. They have the following meaning:
+
+ STATUS.NULL_POINTER
+ The 'tag' argument is NULL
+ STATUS.TAG_TOO_LONG
+ The length of 'tag' is too long
+ (exceeds NOTMUCH_TAG_MAX)
+ STATUS.READ_ONLY_DATABASE
+ Database was opened in read-only mode so message cannot
+ be modified.
+ STATUS.NOT_INITIALIZED
+ The message has not been initialized.
+ """
+ if self._msg is None:
+ raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+ status = nmlib.notmuch_message_remove_tag(self._msg, tag)
+
+ if STATUS.SUCCESS == status:
+ # return on success
+ return status
+
+ raise NotmuchError(status)
+
+ def remove_all_tags(self):
+ """Removes all tags from the given message.
+
+ See :meth:`freeze` for an example showing how to safely
+ replace tag values.
+
+ :returns: STATUS.SUCCESS if the tags were successfully removed.
+ Raises an exception otherwise.
+ :exception: :exc:`NotmuchError`. They have the following meaning:
+
+ STATUS.READ_ONLY_DATABASE
+ Database was opened in read-only mode so message cannot
+ be modified.
+ STATUS.NOT_INITIALIZED
+ The message has not been initialized.
+ """
+ if self._msg is None:
+ raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+ status = nmlib.notmuch_message_remove_all_tags(self._msg)
+
+ if STATUS.SUCCESS == status:
+ # return on success
+ return status
+
+ raise NotmuchError(status)
+
+ def freeze(self):
+ """Freezes the current state of 'message' within the database
+
+ This means that changes to the message state, (via :meth:`add_tag`,
+ :meth:`remove_tag`, and :meth:`remove_all_tags`), will not be
+ committed to the database until the message is :meth:`thaw`ed.
+
+ Multiple calls to freeze/thaw are valid and these calls will
+ "stack". That is there must be as many calls to thaw as to freeze
+ before a message is actually thawed.
+
+ The ability to do freeze/thaw allows for safe transactions to
+ change tag values. For example, explicitly setting a message to
+ have a given set of tags might look like this::
+
+ msg.freeze()
+ msg.remove_all_tags()
+ for tag in new_tags:
+ msg.add_tag(tag)
+ msg.thaw()
+
+ With freeze/thaw used like this, the message in the database is
+ guaranteed to have either the full set of original tag values, or
+ the full set of new tag values, but nothing in between.
+
+ Imagine the example above without freeze/thaw and the operation
+ somehow getting interrupted. This could result in the message being
+ left with no tags if the interruption happened after
+ :meth:`remove_all_tags` but before :meth:`add_tag`.
+
+ :returns: STATUS.SUCCESS if the message was successfully frozen.
+ Raises an exception otherwise.
+ :exception: :exc:`NotmuchError`. They have the following meaning:
+
+ STATUS.READ_ONLY_DATABASE
+ Database was opened in read-only mode so message cannot
+ be modified.
+ STATUS.NOT_INITIALIZED
+ The message has not been initialized.
+ """
+ if self._msg is None:
+ raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+ status = nmlib.notmuch_message_freeze(self._msg)
+
+ if STATUS.SUCCESS == status:
+ # return on success
+ return status
+
+ raise NotmuchError(status)
+
+ def thaw(self):
+ """Thaws the current 'message'
+
+ Thaw the current 'message', synchronizing any changes that may have
+ occurred while 'message' was frozen into the notmuch database.
+
+ See :meth:`freeze` for an example of how to use this
+ function to safely provide tag changes.
+
+ Multiple calls to freeze/thaw are valid and these calls with
+ "stack". That is there must be as many calls to thaw as to freeze
+ before a message is actually thawed.
+
+ :returns: STATUS.SUCCESS if the message was successfully frozen.
+ Raises an exception otherwise.
+ :exception: :exc:`NotmuchError`. They have the following meaning:
+
+ STATUS.UNBALANCED_FREEZE_THAW
+ An attempt was made to thaw an unfrozen message.
+ That is, there have been an unbalanced number of calls
+ to :meth:`freeze` and :meth:`thaw`.
+ STATUS.NOT_INITIALIZED
+ The message has not been initialized.
+ """
+ if self._msg is None:
+ raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+ status = nmlib.notmuch_message_thaw(self._msg)
+
+ if STATUS.SUCCESS == status:
+ # return on success
+ return status
+
+ raise NotmuchError(status)
+
+
+ def __str__(self):
+ """A message() is represented by a 1-line summary"""
+ msg = {}
+ msg['from'] = self.get_header('from')
+ msg['tags'] = str(self.get_tags())
+ msg['date'] = date.fromtimestamp(self.get_date())
+ return "%(from)s (%(date)s) (%(tags)s)" % (msg)
+
+ def format_as_text(self):
+ """Output like notmuch show (Not implemented)"""
+ return str(self)
+