2 This file is part of notmuch.
4 Notmuch is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation, either version 3 of the License, or (at your
7 option) any later version.
9 Notmuch is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with notmuch. If not, see <http://www.gnu.org/licenses/>.
17 Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
19 from ctypes import c_char_p
20 from notmuch.globals import (
32 class Filenames(Python3StringMixIn):
33 """Represents a list of filenames as returned by notmuch
35 This object contains the Filenames iterator. The main function is
36 as_generator() which will return a generator so we can do a Filenamesth an
37 iterator over a list of notmuch filenames. Do note that the underlying
38 library only provides a one-time iterator (it cannot reset the iterator to
39 the start). Thus iterating over the function will "exhaust" the list of
40 tags, and a subsequent iteration attempt will raise a
41 :exc:`NotInitializedError`. Also note, that any function that uses
42 iteration (nearly all) will also exhaust the tags. So both::
44 for name in filenames: print name
48 number_of_names = len(names)
52 #str() iterates over all tags to construct a space separated list
55 will "exhaust" the Filenames. However, you can use
56 :meth:`Message.get_filenames` repeatedly to get fresh Filenames
57 objects to perform various actions on filenames.
60 #notmuch_filenames_get
61 _get = nmlib.notmuch_filenames_get
62 _get.argtypes = [NotmuchFilenamesP]
63 _get.restype = c_char_p
65 def __init__(self, files_p, parent):
67 :param files_p: A pointer to an underlying *notmuch_tags_t*
68 structure. These are not publically exposed, so a user
69 will almost never instantiate a :class:`Tags` object
70 herself. They are usually handed back as a result,
71 e.g. in :meth:`Database.get_all_tags`. *tags_p* must be
72 valid, we will raise an :exc:`NullPointerError`
74 :type files_p: :class:`ctypes.c_void_p`
75 :param parent: The parent object (ie :class:`Message` these
76 filenames are derived from, and saves a
77 reference to it, so we can automatically delete the db object
78 once all derived objects are dead.
81 raise NullPointerError()
83 self._files_p = files_p
84 #save reference to parent object so we keep it alive
88 """ Make Filenames an iterator """
91 _valid = nmlib.notmuch_filenames_valid
92 _valid.argtypes = [NotmuchFilenamesP]
95 _move_to_next = nmlib.notmuch_filenames_move_to_next
96 _move_to_next.argtypes = [NotmuchFilenamesP]
97 _move_to_next.restype = None
100 if not self._files_p:
101 raise NotInitializedError()
103 if not self._valid(self._files_p):
107 file_ = Filenames._get(self._files_p)
108 self._move_to_next(self._files_p)
109 return file_.decode('utf-8', 'ignore')
110 next = __next__ # python2.x iterator protocol compatibility
112 def __unicode__(self):
113 """Represent Filenames() as newline-separated list of full paths
115 .. note:: As this iterates over the filenames, we will not be
116 able to iterate over them again (as in retrieve them)! If
117 the tags have been exhausted already, this will raise a
118 :exc:`NotInitializedError` on subsequent
119 attempts. However, you can use
120 :meth:`Message.get_filenames` repeatedly to perform
121 various actions on filenames.
123 return "\n".join(self)
125 _destroy = nmlib.notmuch_filenames_destroy
126 _destroy.argtypes = [NotmuchMessageP]
127 _destroy.restype = None
130 """Close and free the notmuch filenames"""
131 if self._files_p is not None:
132 self._destroy(self._files_p)
135 """len(:class:`Filenames`) returns the number of contained files
139 As this iterates over the files, we will not be able to
140 iterate over them again! So this will fail::
143 files = Database().get_directory('').get_child_files()
144 if len(files) > 0: # this 'exhausts' msgs
146 # NotmuchError(:attr:`STATUS`.NOT_INITIALIZED)
147 for file in files: print file
149 if not self._files_p:
150 raise NotInitializedError()
153 while self._valid(self._files_p):
154 self._move_to_next(self._files_p)