X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=cnotmuch%2Fdatabase.py;h=0ae24ec245b53f8bbbb191739f6271e806fb6b95;hp=92afa0a047d8f773ec76b1459723bc9f0cdbc1b1;hb=b42fdb0f70c23d72b0c7e91c6e09f48192a8206c;hpb=4ed01d055ac59b182535dfe44a33e52fc271279b diff --git a/cnotmuch/database.py b/cnotmuch/database.py index 92afa0a0..0ae24ec2 100644 --- a/cnotmuch/database.py +++ b/cnotmuch/database.py @@ -1,4 +1,4 @@ -import ctypes +import ctypes, os from ctypes import c_int, c_char_p, c_void_p, c_uint, c_uint64, c_bool from cnotmuch.globals import nmlib, STATUS, NotmuchError, Enum import logging @@ -13,12 +13,12 @@ class Database(object): as well. Accessing these objects will lead to segfaults and other unexpected behavior. See above for more details. """ - MODE = Enum(['READ_ONLY','READ_WRITE']) - """Constants: Mode in which to open the database""" - _std_db_path = None """Class attribute to cache user's default database""" + MODE = Enum(['READ_ONLY','READ_WRITE']) + """Constants: Mode in which to open the database""" + """notmuch_database_get_path (notmuch_database_t *database)""" _get_path = nmlib.notmuch_database_get_path _get_path.restype = c_char_p @@ -43,11 +43,14 @@ class Database(object): _create = nmlib.notmuch_database_create _create.restype = c_void_p - def __init__(self, path=None, create=False, mode= MODE.READ_ONLY): - """If *path* is *None*, we will try to read a users notmuch - configuration and use his default database. If *create* is `True`, - the database will always be created in - :attr:`MODE`.READ_WRITE mode. + def __init__(self, path=None, create=False, mode= 0): + """If *path* is *None*, we will try to read a users notmuch + configuration and use his configured database. The location of the + configuration file can be specified through the environment variable + *NOTMUCH_CONFIG*, falling back to the default `~/.notmuch-config`. + + If *create* is `True`, the database will always be created in + :attr:`MODE`.READ_WRITE mode. Default mode for opening is READ_ONLY. :param path: Directory to open/create the database in (see above for behavior if `None`) @@ -94,14 +97,14 @@ class Database(object): raise NotmuchError( message="Cannot create db, this Database() already has an open one.") - res = Database._create(path, MODE.READ_WRITE) + res = Database._create(path, Database.MODE.READ_WRITE) if res is None: raise NotmuchError( message="Could not create the specified database") self._db = res - def open(self, path, mode= MODE.READ_ONLY): + def open(self, path, mode= 0): """Opens an existing database This function is used by __init__() and usually does not need @@ -204,9 +207,10 @@ class Database(object): Throws a NotmuchError if it cannot find it""" from ConfigParser import SafeConfigParser - import os.path config = SafeConfigParser() - config.read(os.path.expanduser('~/.notmuch-config')) + conf_f = os.getenv('NOTMUCH_CONFIG', + os.path.expanduser('~/.notmuch-config')) + config.read(conf_f) if not config.has_option('database','path'): raise NotmuchError(message= "No DB path specified and no user default found") @@ -246,6 +250,11 @@ class Query(object): _search_messages = nmlib.notmuch_query_search_messages _search_messages.restype = c_void_p + + """notmuch_query_count_messages""" + _count_messages = nmlib.notmuch_query_count_messages + _count_messages.restype = c_uint + def __init__(self, db, querystr): """ :param db: An open database which we derive the Query from. @@ -323,6 +332,25 @@ class Query(object): return Messages(msgs_p,self) + def count_messages(self): + """Estimate the number of messages matching the query + + This function performs a search and returns Xapian's best + guess as to the number of matching messages. It is much faster + than performing :meth:`search_messages` and counting the + result with `len()` (although it always returned the same + result in my tests). Technically, it wraps the underlying + *notmuch_query_count_messages* function. + + :returns: :class:`Messages` + :exception: :exc:`NotmuchError` + + * STATUS.NOT_INITIALIZED if query is not inited + """ + if self._query is None: + raise NotmuchError(STATUS.NOT_INITIALIZED) + + return Query._count_messages(self._query) def __del__(self): """Close and free the Query""" @@ -592,10 +620,15 @@ class Message(object): """notmuch_message_get_filename (notmuch_message_t *message)""" _get_filename = nmlib.notmuch_message_get_filename _get_filename.restype = c_char_p + """notmuch_message_get_message_id (notmuch_message_t *message)""" _get_message_id = nmlib.notmuch_message_get_message_id _get_message_id.restype = c_char_p + """notmuch_message_get_thread_id""" + _get_thread_id = nmlib.notmuch_message_get_thread_id + _get_thread_id.restype = c_char_p + """notmuch_message_get_tags (notmuch_message_t *message)""" _get_tags = nmlib.notmuch_message_get_tags _get_tags.restype = c_void_p @@ -625,7 +658,7 @@ class Message(object): def get_message_id(self): - """Return the message ID + """Returns the message ID :returns: String with a message ID :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message @@ -635,6 +668,24 @@ class Message(object): raise NotmuchError(STATUS.NOT_INITIALIZED) return Message._get_message_id(self._msg) + def get_thread_id(self): + """Returns the thread ID + + The returned string belongs to 'message' will only be valid for as + long as the message is valid. + + This function will not return None since Notmuch ensures that every + message belongs to a single thread. + + :returns: String with a thread ID + :exception: :exc:`NotmuchError` STATUS.NOT_INITIALIZED if the message + is not initialized. + """ + if self._msg is None: + raise NotmuchError(STATUS.NOT_INITIALIZED) + + return Message._get_thread_id (self._msg); + def get_date(self): """Returns time_t of the message date