aboutsummaryrefslogtreecommitdiffhomepage
path: root/bindings
diff options
context:
space:
mode:
authorGravatar Sebastian Spaeth <Sebastian@SSpaeth.de>2011-06-02 08:56:03 +0200
committerGravatar Sebastian Spaeth <Sebastian@SSpaeth.de>2011-06-02 09:03:18 +0200
commitb31247c354b54a3cbeb1c7f9df830e16f7c921d9 (patch)
treea7293c6e59274348809cc43e6bd855967e333306 /bindings
parente2afcd2594add5186234124dd38b4b2aeabca5bd (diff)
bindings/python: Implement Message().get_filenames()
Message().get_filenames() will return a generator that allows to iterator over the recorded filenames for a certain Message. Do ntoe that as all generators, these are one-time use only. You will have to reget them to perform various actions. So this works:: len(Message().get_filenames()) list(Message().get_filenames()) for n in Message().get_filenames(): print n But this won't:: names = Message().get_filenames() len(names) #uses up the iterator list(names) #outch, already used up... Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Diffstat (limited to 'bindings')
-rw-r--r--bindings/python/notmuch/filename.py108
-rw-r--r--bindings/python/notmuch/message.py18
2 files changed, 126 insertions, 0 deletions
diff --git a/bindings/python/notmuch/filename.py b/bindings/python/notmuch/filename.py
new file mode 100644
index 00000000..20b90e98
--- /dev/null
+++ b/bindings/python/notmuch/filename.py
@@ -0,0 +1,108 @@
+"""
+This file is part of notmuch.
+
+Notmuch 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 3 of the License, or (at your
+option) any later version.
+
+Notmuch 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 notmuch. If not, see <http://www.gnu.org/licenses/>.
+
+Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
+"""
+from ctypes import c_char_p
+from notmuch.globals import nmlib, STATUS, NotmuchError
+
+#------------------------------------------------------------------------------
+class Filenames(object):
+ """Represents a list of filenames as returned by notmuch
+
+ This object contains the Filenames iterator. The main function is as_generator() which will return a generator so we can do a Filenamesth an iterator over a list of notmuch filenames. Do
+ note that the underlying library only provides a one-time iterator
+ (it cannot reset the iterator to the start). Thus iterating over
+ the function will "exhaust" the list of tags, and a subsequent
+ iteration attempt will raise a :exc:`NotmuchError`
+ STATUS.NOT_INITIALIZED. Also note, that any function that uses
+ iteration (nearly all) will also exhaust the tags. So both::
+
+ for name in filenames: print name
+
+ as well as::
+
+ number_of_names = len(names)
+
+ and even a simple::
+
+ #str() iterates over all tags to construct a space separated list
+ print(str(filenames))
+
+ will "exhaust" the Filenames. However, you can use
+ :meth:`Message.get_filenames` repeatedly to get fresh Filenames
+ objects to perform various actions on filenames.
+ """
+
+ #notmuch_filenames_get
+ _get = nmlib.notmuch_filenames_get
+ _get.restype = c_char_p
+
+ def __init__(self, files_p, parent):
+ """
+ :param files_p: A pointer to an underlying *notmuch_tags_t*
+ structure. These are not publically exposed, so a user
+ will almost never instantiate a :class:`Tags` object
+ herself. They are usually handed back as a result,
+ e.g. in :meth:`Database.get_all_tags`. *tags_p* must be
+ valid, we will raise an :exc:`NotmuchError`
+ (STATUS.NULL_POINTER) if it is `None`.
+ :type files_p: :class:`ctypes.c_void_p`
+ :param parent: The parent object (ie :class:`Message` these
+ filenames are derived from, and saves a
+ reference to it, so we can automatically delete the db object
+ once all derived objects are dead.
+ """
+ if files_p is None:
+ NotmuchError(STATUS.NULL_POINTER)
+
+ self._files = files_p
+ #save reference to parent object so we keep it alive
+ self._parent = parent
+
+ def as_generator(self):
+ """Return generator of Filenames
+
+ This is the main function that will usually be used by the
+ user."""
+ if self._files is None:
+ raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+ if not nmlib.notmuch_filenames_valid(self._files):
+ self._files = None
+ return
+
+ file = Filenames._get (self._files)
+ nmlib.notmuch_filenames_move_to_next(self._files)
+ yield file
+
+ def __str__(self):
+ """Represent Filenames() as newline-separated list of full paths
+
+ .. note:: As this iterates over the filenames, we will not be
+ able to iterate over them again (as in retrieve them)! If
+ the tags have been exhausted already, this will raise a
+ :exc:`NotmuchError` STATUS.NOT_INITIALIZED on subsequent
+ attempts. However, you can use
+ :meth:`Message.get_filenames` repeatedly to perform
+ various actions on filenames.
+ """
+ return "\n".join(self)
+
+ def __del__(self):
+ """Close and free the notmuch filenames"""
+ if self._files is not None:
+ nmlib.notmuch_filenames_destroy (self._files)
diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py
index ac85cbb4..340c0b8b 100644
--- a/bindings/python/notmuch/message.py
+++ b/bindings/python/notmuch/message.py
@@ -23,6 +23,7 @@ from ctypes import c_char_p, c_void_p, c_long, c_uint
from datetime import date
from notmuch.globals import nmlib, STATUS, NotmuchError, Enum
from notmuch.tag import Tags
+from notmuch.filename import Filenames
import sys
import email
import types
@@ -244,6 +245,10 @@ class Message(object):
_get_filename = nmlib.notmuch_message_get_filename
_get_filename.restype = c_char_p
+ """return all filenames for a message"""
+ _get_filenames = nmlib.notmuch_message_get_filenames
+ _get_filenames.restype = c_void_p
+
"""notmuch_message_get_flag"""
_get_flag = nmlib.notmuch_message_get_flag
_get_flag.restype = c_uint
@@ -400,6 +405,19 @@ class Message(object):
raise NotmuchError(STATUS.NOT_INITIALIZED)
return Message._get_filename(self._msg)
+ def get_filenames(self):
+ """Get all filenames for the email corresponding to 'message'
+
+ Returns a Filenames() generator with all absolute filepaths for
+ messages recorded to have the same Message-ID. These files must
+ not necessarily have identical content."""
+ if self._msg is None:
+ raise NotmuchError(STATUS.NOT_INITIALIZED)
+
+ files_p = Message._get_filenames(self._msg)
+
+ return Filenames(files_p, self).as_generator()
+
def get_flag(self, flag):
"""Checks whether a specific flag is set for this message