From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id D7568431FC3 for ; Mon, 25 Jan 2010 19:53:30 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -2.027 X-Spam-Level: X-Spam-Status: No, score=-2.027 tagged_above=-999 required=5 tests=[AWL=-0.917, BAYES_05=-1.11] autolearn=ham Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bmfAL-OolLZt for ; Mon, 25 Jan 2010 19:53:29 -0800 (PST) Received: from mail-yx0-f204.google.com (mail-yx0-f204.google.com [209.85.210.204]) by olra.theworths.org (Postfix) with ESMTP id 068CA431FAE for ; Mon, 25 Jan 2010 19:53:28 -0800 (PST) Received: by mail-yx0-f204.google.com with SMTP id 42so1974332yxe.22 for ; Mon, 25 Jan 2010 19:53:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=fYxeyVqr19/DKNEP//OXIa00UVBMVlPYNkkjoP43pMA=; b=vrLVhwFszHW//xOY9uwKJ193tdoKDeAcoZejTascX1X9QhsTIchHUSu5j83RSLEL6O UMXnPMxGRmbMow/5H818ClutEVxUDYwAHcLB5qjJlAlGO17BckIX8u5fPZphJj4aQfdB eN5DSbA/FUMAozFSz4d/TiuFBpFEGQCn8H+R0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=j1FZ+hmaVxT8LcFg3l9hqYKKZKIjdYIC+X8+C0YWhdz84V3AA1u9a4aqxO3YFp1QIu z2Su2JXB55JjDycVwrE+3MNQlfYGm5v7H8bgA3bgGGf4FKGcFAAHHYzJIwMuq/5Y+1qt YOB63nn2ODxE7osH1UJaYWGL8tUlqsQn9bHJs= Received: by 10.100.222.16 with SMTP id u16mr152406ang.229.1264478008801; Mon, 25 Jan 2010 19:53:28 -0800 (PST) Received: from localhost.localdomain (umass-959-100.wireless.umass.edu [128.119.77.100]) by mx.google.com with ESMTPS id 9sm1980893ywe.26.2010.01.25.19.53.27 (version=SSLv3 cipher=RC4-MD5); Mon, 25 Jan 2010 19:53:27 -0800 (PST) From: Ben Gamari To: notmuch@notmuchmail.org Date: Mon, 25 Jan 2010 22:53:18 -0500 Message-Id: <1264477998-20681-2-git-send-email-bgamari.foss@gmail.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1264477998-20681-1-git-send-email-bgamari.foss@gmail.com> References: <1264477998-20681-1-git-send-email-bgamari.foss@gmail.com> Subject: [PATCH] Add SWIG interface file X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 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: Tue, 26 Jan 2010 03:53:31 -0000 --- swig/Makefile | 18 ++++ swig/notmuch.py | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++ swig/notmuch_funcs.i | 9 ++ 3 files changed, 249 insertions(+), 0 deletions(-) create mode 100644 swig/Makefile create mode 100644 swig/notmuch.py create mode 100644 swig/notmuch_funcs.i diff --git a/swig/Makefile b/swig/Makefile new file mode 100644 index 0000000..7b10ea7 --- /dev/null +++ b/swig/Makefile @@ -0,0 +1,18 @@ +include ../Makefile.config + +INCLUDES=-I../lib -I/usr/include/python2.6 +CFLAGS=${INCLUDES} + +all : python + +python : _notmuch_funcs.so notmuch.py + +_notmuch_funcs.so : notmuch_funcs_wrap.o + g++ -shared -lnotmuch ${XAPIAN_LDFLAGS} ${GMIME_LDFLAGS} ${TALLOC_LDFLAGS} -o $@ $< + +%_wrap.o : %_wrap.c + gcc ${CFLAGS} -fPIC -c -o $@ $< + +%_wrap.c %.py : %.i + swig -python ${INCLUDES} $< + diff --git a/swig/notmuch.py b/swig/notmuch.py new file mode 100644 index 0000000..e17f71f --- /dev/null +++ b/swig/notmuch.py @@ -0,0 +1,222 @@ +import notmuch_funcs as nm +from datetime import datetime + +class Exception(Exception): + def get_message(): + errors = { + nm.NOTMUCH_STATUS_OUT_OF_MEMORY: 'out of memory', + nm.NOTMUCH_STATUS_READONLY_DATABASE: 'database opened as read-only', + nm.NOTMUCH_STATUS_XAPIAN_EXCEPTION: 'xapian error', + nm.NOTMUCH_STATUS_FILE_ERROR: 'file error', + nm.NOTMUCH_STATUS_FILE_NOT_EMAIL: 'file not email message', + nm.NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: 'duplicate message id', + nm.NOTMUCH_STATUS_NULL_POINTER: 'null pointer', + nm.NOTMUCH_STATUS_TAG_TOO_LONG: 'tag name too long', + nm.NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: 'unbalanced freeze/thaw', + } + return errors.get(self.status, 'unknown error') + + def __init__(self, status): + self.status = status + +def _handle_status(status): + if (status != nm.NOTMUCH_STATUS_SUCCESS): + raise Exception(status) + +class Database(object): + MODE_READ_ONLY = nm.NOTMUCH_DATABASE_MODE_READ_ONLY + MODE_READ_WRITE = nm.NOTMUCH_DATABASE_MODE_READ_WRITE + + def __init__(self, db): + if not db: + raise Exception("Failed to open database") + self.db = db + + @staticmethod + def create(path): + return Database(nm.notmuch_database_create(path)) + + @staticmethod + def open(path, mode): + return Database(nm.notmuch_database_open(path, mode)) + + def close(self): + nm.notmuch_database_close(self.db) + + def get_path(self): + return nm.notmuch_database_get_path(self.db) + + def set_timestamp(self, key, timestamp): + _handle_status(nm.notmuch_database_set_timestamp(self.db, key, timestamp)) + + def get_timestamp(self, key): + return datetime.fromtimestamp(nm.notmuch_database_get_timestamp(self.db, key)) + + def add_message(self, filename, message): + _handle_status(nm.notmuch_database_add_message(self.db, filename, message.message)) + + def find_message(self, message_id): + return Message(nm.notmuch_database_find_message(self.db, message_id)) + + def get_all_tags(self): + return Tags(nm.notmuch_database_get_all_tags(self.db)) + + def __destroy__(self): + self.close() + +class Query(object): + def __init__(self, db, query_string): + self.query = nm.notmuch_query_create(db, query_string) + if not self.query: # This might not work + raise "Failed to create query" + + def set_sort(self, sort): + nm.notmuch_query_set_sort(self.query, sort) + + def search_threads(self): + return Threads(nm.notmuch_query_search_threads(self.query)) + + def search_messages(self): + return Messages(nm.notmuch_query_search_messages(self.query)) + + def count_message(self): + return nm.notmuch_query_count_messages(self.query) + + def __destroy__(self): + nm.notmuch_query_destroy(self.query) + +class Tags(object): + def __init__(self, tags): + self.tags = tags + + def __iter__(self): + return self + + def next(self): + if not nm.notmuch_tags_has_more(self.tags): + raise StopIteration + else: + h = nm.notmuch_tags_get(self.tags) + nm.notmuch_tags_advance(self.tags) + return h + + def __destroy__(self): + nm.notmuch_messages_destroy(self.tags) + +class Thread(object): + def __init__(self, thread): + self.thread = thread + + def get_thread_id(self): + return nm.notmuch_thread_get_thread_id(self.thread) + + def get_total_messages(self): + return nm.notmuch_thread_total_messages(self.thread) + + def get_toplevel_messages(self): + return Messages(nm.notmuch_thread_get_toplevel_messages(self.thread)) + + def get_matched_messages(self): + return nm.notmuch_thread_get_matched_messages(self.thread) + + def get_authors(self): + return nm.notmuch_thread_get_authors(self.thread) + + def get_subject(self): + return nm.notmuch_thread_get_subject(self.thread) + + def get_oldest_date(self): + return nm.notmuch_thread_get_oldest_date(self.thread) + + def get_newest_date(self): + return nm.notmuch_thread_get_newest_date(self.thread) + + def get_tags(self): + return Tags(nm.notmuch_thread_get_tags(self.thread)) + + def __destroy__(self): + nm.notmuch_thread_destroy(self.thread) + +class Threads(object): + def __init__(self, threads): + self.threads = threads + + def __iter__(self): + return self + + def next(self): + if not nm.notmuch_threads_has_more(self.threads): + raise StopIteration + else: + h = Thread(nm.notmuch_threads_get(self.threads)) + nm.notmuch_threads_advance(self.threads) + return h + + def __destroy__(self): + nm.notmuch_threads_destroy(self.threads) + +class Messages(object): + def __init__(self, messages): + self.messages = messages + + def __iter__(self): + return self + + def next(self): + if not nm.notmuch_messages_has_more(self.messages): + raise StopIteration + else: + h = Message(nm.notmuch_messages_get(self.messages)) + nm.notmuch_messages_advance(self.messages) + return h + + def __destroy__(self): + nm.notmuch_messages_destroy(self.messages) + + def collect_tags(self): + return Tags(nm.notmuch_messages_collect_tags(self.messages)) + +class Message(object): + def __init__(self, message): + self.message = message + + def get_replies(self): + return Messages(nm.notmuch_message_get_replies(self.message)) + + def get_filename(self): + return nm.notmuch_message_get_filename(self.message) + + def get_flag(self, flag): + return bool(nm.notmuch_message_get_flag(self.message, flag)) + + def set_flag(self, flag, value): + return nm.notmuch_message_set_flag(self.message, flag, value) + + def get_date(self): + return datetime.fromtimestamp(nm.notmuch_message_get_date(self.message)) + + def get_header(self, header): + return nm.notmuch_message_get_header(self.message, header) + + def get_tags(self): + return Tags(nm.notmuch_message_get_tags(self.message)) + + def add_tag(self, tag): + _handle_status(nm.notmuch_message_add_tag(self.message, tag)) + + def remove_tag(self, tag): + _handle_status(nm.notmuch_message_remove_tag(self.message, tag)) + + def remove_all_tags(self): + nm.notmuch_message_remove_all_tags(self.message) + + def freeze(self): + nm.notmuch_message_freeze(self.message) + + def thaw(self): + nm.notmuch_message_thaw(self.message) + + def __destroy__(self): + nm.notmuch_message_destroy(self.message) + + diff --git a/swig/notmuch_funcs.i b/swig/notmuch_funcs.i new file mode 100644 index 0000000..cc1826e --- /dev/null +++ b/swig/notmuch_funcs.i @@ -0,0 +1,9 @@ +%module notmuch_funcs + +%{ +#define SWIG_FILE_WITH_INIT +#include "notmuch.h" +%} + +%include "notmuch.h" + -- 1.6.3.3