Re: [PATCH 9/9] add has: query prefix to search for specific properties
[notmuch-archives.git] / b1 / 2ef5b30e8385e63828fceffe09188bbfca5cde
1 Return-Path: <bgamari.foss@gmail.com>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id D7568431FC3\r
6         for <notmuch@notmuchmail.org>; Mon, 25 Jan 2010 19:53:30 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -2.027\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-2.027 tagged_above=-999 required=5\r
12         tests=[AWL=-0.917, BAYES_05=-1.11] autolearn=ham\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id bmfAL-OolLZt for <notmuch@notmuchmail.org>;\r
16         Mon, 25 Jan 2010 19:53:29 -0800 (PST)\r
17 Received: from mail-yx0-f204.google.com (mail-yx0-f204.google.com\r
18         [209.85.210.204])\r
19         by olra.theworths.org (Postfix) with ESMTP id 068CA431FAE\r
20         for <notmuch@notmuchmail.org>; Mon, 25 Jan 2010 19:53:28 -0800 (PST)\r
21 Received: by mail-yx0-f204.google.com with SMTP id 42so1974332yxe.22\r
22         for <notmuch@notmuchmail.org>; Mon, 25 Jan 2010 19:53:28 -0800 (PST)\r
23 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\r
24         h=domainkey-signature:received:received:from:to:cc:subject:date\r
25         :message-id:x-mailer:in-reply-to:references;\r
26         bh=fYxeyVqr19/DKNEP//OXIa00UVBMVlPYNkkjoP43pMA=;\r
27         b=vrLVhwFszHW//xOY9uwKJ193tdoKDeAcoZejTascX1X9QhsTIchHUSu5j83RSLEL6O\r
28         UMXnPMxGRmbMow/5H818ClutEVxUDYwAHcLB5qjJlAlGO17BckIX8u5fPZphJj4aQfdB\r
29         eN5DSbA/FUMAozFSz4d/TiuFBpFEGQCn8H+R0=\r
30 DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma;\r
31         h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;\r
32         b=j1FZ+hmaVxT8LcFg3l9hqYKKZKIjdYIC+X8+C0YWhdz84V3AA1u9a4aqxO3YFp1QIu\r
33         z2Su2JXB55JjDycVwrE+3MNQlfYGm5v7H8bgA3bgGGf4FKGcFAAHHYzJIwMuq/5Y+1qt\r
34         YOB63nn2ODxE7osH1UJaYWGL8tUlqsQn9bHJs=\r
35 Received: by 10.100.222.16 with SMTP id u16mr152406ang.229.1264478008801;\r
36         Mon, 25 Jan 2010 19:53:28 -0800 (PST)\r
37 Received: from localhost.localdomain (umass-959-100.wireless.umass.edu\r
38         [128.119.77.100])\r
39         by mx.google.com with ESMTPS id 9sm1980893ywe.26.2010.01.25.19.53.27\r
40         (version=SSLv3 cipher=RC4-MD5); Mon, 25 Jan 2010 19:53:27 -0800 (PST)\r
41 From: Ben Gamari <bgamari.foss@gmail.com>\r
42 To: notmuch@notmuchmail.org\r
43 Date: Mon, 25 Jan 2010 22:53:18 -0500\r
44 Message-Id: <1264477998-20681-2-git-send-email-bgamari.foss@gmail.com>\r
45 X-Mailer: git-send-email 1.6.3.3\r
46 In-Reply-To: <1264477998-20681-1-git-send-email-bgamari.foss@gmail.com>\r
47 References: <1264477998-20681-1-git-send-email-bgamari.foss@gmail.com>\r
48 Subject: [notmuch] [PATCH] Add SWIG interface file\r
49 X-BeenThere: notmuch@notmuchmail.org\r
50 X-Mailman-Version: 2.1.13\r
51 Precedence: list\r
52 List-Id: "Use and development of the notmuch mail system."\r
53         <notmuch.notmuchmail.org>\r
54 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
55         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
56 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
57 List-Post: <mailto:notmuch@notmuchmail.org>\r
58 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
59 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
60         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
61 X-List-Received-Date: Tue, 26 Jan 2010 03:53:31 -0000\r
62 \r
63 ---\r
64  swig/Makefile        |   18 ++++\r
65  swig/notmuch.py      |  222 ++++++++++++++++++++++++++++++++++++++++++++++++++\r
66  swig/notmuch_funcs.i |    9 ++\r
67  3 files changed, 249 insertions(+), 0 deletions(-)\r
68  create mode 100644 swig/Makefile\r
69  create mode 100644 swig/notmuch.py\r
70  create mode 100644 swig/notmuch_funcs.i\r
71 \r
72 diff --git a/swig/Makefile b/swig/Makefile\r
73 new file mode 100644\r
74 index 0000000..7b10ea7\r
75 --- /dev/null\r
76 +++ b/swig/Makefile\r
77 @@ -0,0 +1,18 @@\r
78 +include ../Makefile.config\r
79 +\r
80 +INCLUDES=-I../lib -I/usr/include/python2.6\r
81 +CFLAGS=${INCLUDES}\r
82 +\r
83 +all : python\r
84 +\r
85 +python : _notmuch_funcs.so notmuch.py\r
86 +\r
87 +_notmuch_funcs.so : notmuch_funcs_wrap.o\r
88 +       g++ -shared -lnotmuch ${XAPIAN_LDFLAGS} ${GMIME_LDFLAGS} ${TALLOC_LDFLAGS} -o $@ $<\r
89 +\r
90 +%_wrap.o : %_wrap.c\r
91 +       gcc ${CFLAGS} -fPIC -c -o $@ $<\r
92 +\r
93 +%_wrap.c %.py : %.i \r
94 +       swig -python ${INCLUDES} $<\r
95 +\r
96 diff --git a/swig/notmuch.py b/swig/notmuch.py\r
97 new file mode 100644\r
98 index 0000000..e17f71f\r
99 --- /dev/null\r
100 +++ b/swig/notmuch.py\r
101 @@ -0,0 +1,222 @@\r
102 +import notmuch_funcs as nm\r
103 +from datetime import datetime\r
104 +\r
105 +class Exception(Exception):\r
106 +        def get_message():\r
107 +                errors = {\r
108 +                        nm.NOTMUCH_STATUS_OUT_OF_MEMORY: 'out of memory',\r
109 +                        nm.NOTMUCH_STATUS_READONLY_DATABASE: 'database opened as read-only',\r
110 +                        nm.NOTMUCH_STATUS_XAPIAN_EXCEPTION: 'xapian error',\r
111 +                        nm.NOTMUCH_STATUS_FILE_ERROR: 'file error',\r
112 +                        nm.NOTMUCH_STATUS_FILE_NOT_EMAIL: 'file not email message',\r
113 +                        nm.NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: 'duplicate message id',\r
114 +                        nm.NOTMUCH_STATUS_NULL_POINTER: 'null pointer',\r
115 +                        nm.NOTMUCH_STATUS_TAG_TOO_LONG: 'tag name too long',\r
116 +                        nm.NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: 'unbalanced freeze/thaw',\r
117 +                }\r
118 +                return errors.get(self.status, 'unknown error')\r
119 +\r
120 +        def __init__(self, status):\r
121 +                self.status = status\r
122 +\r
123 +def _handle_status(status):\r
124 +        if (status != nm.NOTMUCH_STATUS_SUCCESS):\r
125 +                raise Exception(status)\r
126 +\r
127 +class Database(object):\r
128 +        MODE_READ_ONLY = nm.NOTMUCH_DATABASE_MODE_READ_ONLY\r
129 +        MODE_READ_WRITE = nm.NOTMUCH_DATABASE_MODE_READ_WRITE\r
130 +\r
131 +        def __init__(self, db):\r
132 +                if not db:\r
133 +                        raise Exception("Failed to open database")\r
134 +                self.db = db\r
135 +\r
136 +        @staticmethod\r
137 +        def create(path):\r
138 +                return Database(nm.notmuch_database_create(path))\r
139 +\r
140 +        @staticmethod\r
141 +        def open(path, mode):\r
142 +                return Database(nm.notmuch_database_open(path, mode))\r
143 +\r
144 +        def close(self):\r
145 +                nm.notmuch_database_close(self.db)\r
146 +\r
147 +        def get_path(self):\r
148 +                return nm.notmuch_database_get_path(self.db)\r
149 +\r
150 +        def set_timestamp(self, key, timestamp):\r
151 +                _handle_status(nm.notmuch_database_set_timestamp(self.db, key, timestamp))\r
152 +\r
153 +        def get_timestamp(self, key):\r
154 +                return datetime.fromtimestamp(nm.notmuch_database_get_timestamp(self.db, key))\r
155 +\r
156 +        def add_message(self, filename, message):\r
157 +                _handle_status(nm.notmuch_database_add_message(self.db, filename, message.message))\r
158 +\r
159 +        def find_message(self, message_id):\r
160 +                return Message(nm.notmuch_database_find_message(self.db, message_id))\r
161 +\r
162 +        def get_all_tags(self):\r
163 +                return Tags(nm.notmuch_database_get_all_tags(self.db))\r
164 +\r
165 +        def __destroy__(self):\r
166 +                self.close()\r
167 +        \r
168 +class Query(object):\r
169 +        def __init__(self, db, query_string):\r
170 +                self.query = nm.notmuch_query_create(db, query_string)\r
171 +                if not self.query: # This might not work\r
172 +                        raise "Failed to create query"\r
173 +\r
174 +        def set_sort(self, sort):\r
175 +                nm.notmuch_query_set_sort(self.query, sort)\r
176 +                \r
177 +        def search_threads(self):\r
178 +                return Threads(nm.notmuch_query_search_threads(self.query))\r
179 +\r
180 +        def search_messages(self):\r
181 +                return Messages(nm.notmuch_query_search_messages(self.query))\r
182 +\r
183 +        def count_message(self):\r
184 +                return nm.notmuch_query_count_messages(self.query)\r
185 +\r
186 +        def __destroy__(self):\r
187 +                nm.notmuch_query_destroy(self.query)\r
188 +\r
189 +class Tags(object):\r
190 +        def __init__(self, tags):\r
191 +                self.tags = tags\r
192 +\r
193 +        def __iter__(self):\r
194 +                return self\r
195 +\r
196 +        def next(self):\r
197 +                if not nm.notmuch_tags_has_more(self.tags):\r
198 +                        raise StopIteration\r
199 +                else:\r
200 +                        h = nm.notmuch_tags_get(self.tags)\r
201 +                        nm.notmuch_tags_advance(self.tags)\r
202 +                        return h\r
203 +\r
204 +        def __destroy__(self):\r
205 +                nm.notmuch_messages_destroy(self.tags)\r
206 +\r
207 +class Thread(object):\r
208 +        def __init__(self, thread):\r
209 +                self.thread = thread\r
210 +\r
211 +        def get_thread_id(self):\r
212 +                return nm.notmuch_thread_get_thread_id(self.thread)\r
213 +\r
214 +        def get_total_messages(self):\r
215 +                return nm.notmuch_thread_total_messages(self.thread)\r
216 +        \r
217 +        def get_toplevel_messages(self):\r
218 +                return Messages(nm.notmuch_thread_get_toplevel_messages(self.thread))\r
219 +\r
220 +        def get_matched_messages(self):\r
221 +                return nm.notmuch_thread_get_matched_messages(self.thread)\r
222 +\r
223 +        def get_authors(self):\r
224 +                return nm.notmuch_thread_get_authors(self.thread)\r
225 +\r
226 +        def get_subject(self):\r
227 +                return nm.notmuch_thread_get_subject(self.thread)\r
228 +\r
229 +        def get_oldest_date(self):\r
230 +                return nm.notmuch_thread_get_oldest_date(self.thread)\r
231 +\r
232 +        def get_newest_date(self):\r
233 +                return nm.notmuch_thread_get_newest_date(self.thread)\r
234 +\r
235 +        def get_tags(self):\r
236 +                return Tags(nm.notmuch_thread_get_tags(self.thread))\r
237 +\r
238 +        def __destroy__(self):\r
239 +                nm.notmuch_thread_destroy(self.thread)\r
240 +\r
241 +class Threads(object):\r
242 +        def __init__(self, threads):\r
243 +                self.threads = threads\r
244 +\r
245 +        def __iter__(self):\r
246 +                return self\r
247 +\r
248 +        def next(self):\r
249 +                if not nm.notmuch_threads_has_more(self.threads):\r
250 +                        raise StopIteration\r
251 +                else:\r
252 +                        h = Thread(nm.notmuch_threads_get(self.threads))\r
253 +                        nm.notmuch_threads_advance(self.threads)\r
254 +                        return h\r
255 +\r
256 +        def __destroy__(self):\r
257 +                nm.notmuch_threads_destroy(self.threads)\r
258 +\r
259 +class Messages(object):\r
260 +        def __init__(self, messages):\r
261 +                self.messages = messages\r
262 +\r
263 +        def __iter__(self):\r
264 +                return self\r
265 +\r
266 +        def next(self):\r
267 +                if not nm.notmuch_messages_has_more(self.messages):\r
268 +                        raise StopIteration\r
269 +                else:\r
270 +                        h = Message(nm.notmuch_messages_get(self.messages))\r
271 +                        nm.notmuch_messages_advance(self.messages)\r
272 +                        return h\r
273 +\r
274 +        def __destroy__(self):\r
275 +                nm.notmuch_messages_destroy(self.messages)\r
276 +\r
277 +        def collect_tags(self):\r
278 +                return Tags(nm.notmuch_messages_collect_tags(self.messages))\r
279 +\r
280 +class Message(object):\r
281 +        def __init__(self, message):\r
282 +                self.message = message\r
283 +\r
284 +        def get_replies(self):\r
285 +                return Messages(nm.notmuch_message_get_replies(self.message))\r
286 +\r
287 +        def get_filename(self):\r
288 +                return nm.notmuch_message_get_filename(self.message)\r
289 +\r
290 +        def get_flag(self, flag):\r
291 +                return bool(nm.notmuch_message_get_flag(self.message, flag))\r
292 +\r
293 +        def set_flag(self, flag, value):\r
294 +                return nm.notmuch_message_set_flag(self.message, flag, value)\r
295 +\r
296 +        def get_date(self):\r
297 +                return datetime.fromtimestamp(nm.notmuch_message_get_date(self.message))\r
298 +\r
299 +        def get_header(self, header):\r
300 +                return nm.notmuch_message_get_header(self.message, header)\r
301 +\r
302 +        def get_tags(self):\r
303 +                return Tags(nm.notmuch_message_get_tags(self.message))\r
304 +\r
305 +        def add_tag(self, tag):\r
306 +                _handle_status(nm.notmuch_message_add_tag(self.message, tag))\r
307 +\r
308 +        def remove_tag(self, tag):\r
309 +                _handle_status(nm.notmuch_message_remove_tag(self.message, tag))\r
310 +\r
311 +        def remove_all_tags(self):\r
312 +                nm.notmuch_message_remove_all_tags(self.message)\r
313 +\r
314 +        def freeze(self):\r
315 +                nm.notmuch_message_freeze(self.message)\r
316 +\r
317 +        def thaw(self):\r
318 +                nm.notmuch_message_thaw(self.message)\r
319 +\r
320 +        def __destroy__(self):\r
321 +                nm.notmuch_message_destroy(self.message)\r
322 +\r
323 +\r
324 diff --git a/swig/notmuch_funcs.i b/swig/notmuch_funcs.i\r
325 new file mode 100644\r
326 index 0000000..cc1826e\r
327 --- /dev/null\r
328 +++ b/swig/notmuch_funcs.i\r
329 @@ -0,0 +1,9 @@\r
330 +%module notmuch_funcs\r
331 +\r
332 +%{\r
333 +#define SWIG_FILE_WITH_INIT\r
334 +#include "notmuch.h"\r
335 +%}\r
336 +\r
337 +%include "notmuch.h"\r
338 +\r
339 -- \r
340 1.6.3.3\r
341 \r