mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-26 20:57:58 +01:00
Implement Message(), Database.find_message(), Database.create()
Message() basically has get_message_id get_filename get_tags Plus various bullet proofing and bug fixing. --HG-- extra : transplant_source : O%3B1%EB%E0%D4pYrEY_%E3%0E%BA%C23%11a%B0
This commit is contained in:
parent
90c47567f4
commit
55f1971437
2 changed files with 151 additions and 37 deletions
|
@ -24,47 +24,57 @@ class Database(object):
|
||||||
_open = nmlib.notmuch_database_open
|
_open = nmlib.notmuch_database_open
|
||||||
_open.restype = c_void_p
|
_open.restype = c_void_p
|
||||||
|
|
||||||
|
""" notmuch_database_find_message """
|
||||||
|
_find_message = nmlib.notmuch_database_find_message
|
||||||
|
_find_message.restype = c_void_p
|
||||||
|
|
||||||
"""notmuch_database_get_all_tags (notmuch_database_t *database)"""
|
"""notmuch_database_get_all_tags (notmuch_database_t *database)"""
|
||||||
_get_all_tags = nmlib.notmuch_database_get_all_tags
|
_get_all_tags = nmlib.notmuch_database_get_all_tags
|
||||||
_get_all_tags.restype = c_void_p
|
_get_all_tags.restype = c_void_p
|
||||||
|
|
||||||
class notmuch_database_t(ctypes.Structure):
|
""" notmuch_database_create(const char *path):"""
|
||||||
"""the opaque database that is returned by functions."""
|
_create = nmlib.notmuch_database_create
|
||||||
pass
|
_create.restype = c_void_p
|
||||||
|
|
||||||
def __init__(self, path=None, create=False, status= MODE_READ_ONLY):
|
def __init__(self, path=None, create=False, status= MODE_READ_ONLY):
|
||||||
""" Open or create a notmuch database"""
|
""" Open or create a notmuch database
|
||||||
self._db = None
|
|
||||||
if create == False:
|
|
||||||
self.open(path, status)
|
|
||||||
else:
|
|
||||||
#TODO: implement
|
|
||||||
raise NotmuchError(message="Not implemented yet")
|
|
||||||
|
|
||||||
#TODO: make a proper function
|
|
||||||
create=nmlib.notmuch_database_create
|
|
||||||
""" notmuch_database_create(const char *path):"""
|
|
||||||
|
|
||||||
def open(self, path=None, status= MODE_READ_ONLY):
|
|
||||||
"""calls notmuch_database_open
|
|
||||||
|
|
||||||
If path is None, we will try to read a users notmuch configuration and
|
If path is None, we will try to read a users notmuch configuration and
|
||||||
use his default database.
|
use his default database.
|
||||||
|
Throws a NotmuchError in case of failure.
|
||||||
|
"""
|
||||||
|
self._db = None
|
||||||
|
if path is None:
|
||||||
|
# no path specified. use a user's default database
|
||||||
|
if Database._std_db_path is None:
|
||||||
|
#the following line throws a NotmuchError if it fails
|
||||||
|
Database._std_db_path = self._get_user_default_db()
|
||||||
|
path = Database._std_db_path
|
||||||
|
|
||||||
|
if create == False:
|
||||||
|
self.open(path, status)
|
||||||
|
else:
|
||||||
|
self.create(path, status)
|
||||||
|
|
||||||
|
def create(self, path, status=MODE_READ_ONLY):
|
||||||
|
""" notmuch_database_create(const char *path)
|
||||||
|
|
||||||
:returns: Raises :exc:`notmuch.NotmuchError` in case
|
:returns: Raises :exc:`notmuch.NotmuchError` in case
|
||||||
of any failure (after printing an error message on stderr).
|
of any failure (after printing an error message on stderr).
|
||||||
"""
|
"""
|
||||||
if path is None:
|
res = Database._create(path, status)
|
||||||
if Database._std_db_path is None:
|
|
||||||
from ConfigParser import SafeConfigParser
|
|
||||||
import os.path
|
|
||||||
config = SafeConfigParser()
|
|
||||||
config.read(os.path.expanduser('~/.notmuch-config'))
|
|
||||||
if not config.has_option('database','path'):
|
|
||||||
raise NotmuchError(message=
|
|
||||||
"No DB path specified and no user default found")
|
|
||||||
Database._std_db_path=config.get('database','path')
|
|
||||||
path = Database._std_db_path
|
|
||||||
|
|
||||||
|
if res is None:
|
||||||
|
raise NotmuchError(
|
||||||
|
message="Could not create the specified database")
|
||||||
|
self._db = res
|
||||||
|
|
||||||
|
def open(self, path, status= MODE_READ_ONLY):
|
||||||
|
"""calls notmuch_database_open
|
||||||
|
|
||||||
|
:returns: Raises :exc:`notmuch.NotmuchError` in case
|
||||||
|
of any failure (after printing an error message on stderr).
|
||||||
|
"""
|
||||||
res = Database._open(path, status)
|
res = Database._open(path, status)
|
||||||
|
|
||||||
if res is None:
|
if res is None:
|
||||||
|
@ -76,12 +86,20 @@ class Database(object):
|
||||||
"""notmuch_database_get_path (notmuch_database_t *database); """
|
"""notmuch_database_get_path (notmuch_database_t *database); """
|
||||||
return Database._get_path(self._db)
|
return Database._get_path(self._db)
|
||||||
|
|
||||||
#TODO:implement
|
def find_message(self, msgid):
|
||||||
#If no message is found with the given message_id or if an
|
"""notmuch_database_find_message
|
||||||
#out-of-memory situation occurs, this function returns NULL.
|
:param msgid: The message id
|
||||||
#notmuch_message_t *
|
:ptype msgid: string
|
||||||
#notmuch_database_find_message (notmuch_database_t *database,
|
|
||||||
# const char *message_id);
|
:returns: Message() or None if no message is found or if an
|
||||||
|
out-of-memory situation occurs.
|
||||||
|
"""
|
||||||
|
if self._db is None:
|
||||||
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
|
msg_p = Database._find_message(self._db, msgid)
|
||||||
|
if msg_p is None:
|
||||||
|
return None
|
||||||
|
return Message(msg_p, self)
|
||||||
|
|
||||||
def get_all_tags(self):
|
def get_all_tags(self):
|
||||||
"""Return a Tags() object (list of all tags found in the database)
|
"""Return a Tags() object (list of all tags found in the database)
|
||||||
|
@ -89,6 +107,9 @@ class Database(object):
|
||||||
:returns: Tags() object or raises :exc:`NotmuchError` with
|
:returns: Tags() object or raises :exc:`NotmuchError` with
|
||||||
STATUS.NULL_POINTER on error
|
STATUS.NULL_POINTER on error
|
||||||
"""
|
"""
|
||||||
|
if self._db is None:
|
||||||
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
|
|
||||||
tags_p = Database._get_all_tags (self._db)
|
tags_p = Database._get_all_tags (self._db)
|
||||||
if tags_p == None:
|
if tags_p == None:
|
||||||
raise NotmuchError(STATUS.NULL_POINTER)
|
raise NotmuchError(STATUS.NULL_POINTER)
|
||||||
|
@ -103,6 +124,19 @@ class Database(object):
|
||||||
print("Freeing the database now")
|
print("Freeing the database now")
|
||||||
nmlib.notmuch_database_close(self._db)
|
nmlib.notmuch_database_close(self._db)
|
||||||
|
|
||||||
|
def _get_user_default_db(self):
|
||||||
|
""" Reads a user's notmuch config and returns his db location
|
||||||
|
|
||||||
|
Throws a NotmuchError if it cannot find it"""
|
||||||
|
from ConfigParser import SafeConfigParser
|
||||||
|
import os.path
|
||||||
|
config = SafeConfigParser()
|
||||||
|
config.read(os.path.expanduser('~/.notmuch-config'))
|
||||||
|
if not config.has_option('database','path'):
|
||||||
|
raise NotmuchError(message=
|
||||||
|
"No DB path specified and no user default found")
|
||||||
|
return config.get('database','path')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def db_p(self):
|
def db_p(self):
|
||||||
"""Returns a pointer to the current notmuch_database_t or None"""
|
"""Returns a pointer to the current notmuch_database_t or None"""
|
||||||
|
@ -121,7 +155,11 @@ class Tags(object):
|
||||||
_get.restype = c_char_p
|
_get.restype = c_char_p
|
||||||
|
|
||||||
def __init__(self, tags_p, db=None):
|
def __init__(self, tags_p, db=None):
|
||||||
""" Is passed the db these tags are derived from, and saves a
|
"""
|
||||||
|
msg_p is a pointer to an notmuch_message_t Structure. If it is None,
|
||||||
|
we will raise an NotmuchError(STATUS.NULL_POINTER).
|
||||||
|
|
||||||
|
Is passed the db these tags are derived from, and saves a
|
||||||
reference to it, so we can automatically delete the db object
|
reference to it, so we can automatically delete the db object
|
||||||
once all derived objects are dead.
|
once all derived objects are dead.
|
||||||
|
|
||||||
|
@ -131,9 +169,12 @@ class Tags(object):
|
||||||
#TODO: make the iterator work more than once and cache the tags in
|
#TODO: make the iterator work more than once and cache the tags in
|
||||||
the Python object.
|
the Python object.
|
||||||
"""
|
"""
|
||||||
|
if tags_p is None:
|
||||||
|
NotmuchError(STATUS.NULL_POINTER)
|
||||||
|
|
||||||
self._tags = tags_p
|
self._tags = tags_p
|
||||||
self._db = db
|
self._db = db
|
||||||
print "inited tags with %d %s" %(tags_p, str(db))
|
print "Inited Tags derived from %s" %(str(db))
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
""" Make Tags an iterator """
|
""" Make Tags an iterator """
|
||||||
|
@ -154,3 +195,73 @@ class Tags(object):
|
||||||
if self._tags is not None:
|
if self._tags is not None:
|
||||||
print("Freeing the Tags now")
|
print("Freeing the Tags now")
|
||||||
nmlib.notmuch_tags_destroy (self._tags)
|
nmlib.notmuch_tags_destroy (self._tags)
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
class Message(object):
|
||||||
|
"""Wrapper around notmuch_message_t"""
|
||||||
|
|
||||||
|
"""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_tags (notmuch_message_t *message)"""
|
||||||
|
_get_tags = nmlib.notmuch_message_get_tags
|
||||||
|
_get_tags.restype = c_void_p
|
||||||
|
|
||||||
|
def __init__(self, msg_p, parent=None):
|
||||||
|
"""
|
||||||
|
msg_p is a pointer to an notmuch_message_t Structure. If it is None,
|
||||||
|
we will raise an NotmuchError(STATUS.NULL_POINTER).
|
||||||
|
|
||||||
|
Is a 'parent' object is passed which this message is derived from,
|
||||||
|
we save a reference to it, so we can automatically delete the parent
|
||||||
|
object once all derived objects are dead.
|
||||||
|
"""
|
||||||
|
if msg_p is None:
|
||||||
|
NotmuchError(STATUS.NULL_POINTER)
|
||||||
|
self._msg = msg_p
|
||||||
|
self._parent = parent
|
||||||
|
print "Inited Message derived from %s" %(str(parent))
|
||||||
|
|
||||||
|
|
||||||
|
def get_message_id(self):
|
||||||
|
""" return the msg id
|
||||||
|
|
||||||
|
Raises NotmuchError(STATUS.NOT_INITIALIZED) if not inited
|
||||||
|
"""
|
||||||
|
if self._msg is None:
|
||||||
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
|
return Message._get_message_id(self._msg)
|
||||||
|
|
||||||
|
|
||||||
|
def get_filename(self):
|
||||||
|
""" return the msg filename
|
||||||
|
|
||||||
|
Raises NotmuchError(STATUS.NOT_INITIALIZED) if not inited
|
||||||
|
"""
|
||||||
|
if self._msg is None:
|
||||||
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
|
return Message._get_filename(self._msg)
|
||||||
|
|
||||||
|
def get_tags(self):
|
||||||
|
""" return the msg tags
|
||||||
|
|
||||||
|
Raises NotmuchError(STATUS.NOT_INITIALIZED) if not inited
|
||||||
|
Raises NotmuchError(STATUS.NULL_POINTER) on error.
|
||||||
|
"""
|
||||||
|
if self._msg is None:
|
||||||
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
|
|
||||||
|
tags_p = Message._get_tags(self._msg)
|
||||||
|
if tags_p == None:
|
||||||
|
raise NotmuchError(STATUS.NULL_POINTER)
|
||||||
|
return Tags(tags_p, self)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
"""Close and free the notmuch Message"""
|
||||||
|
if self._msg is not None:
|
||||||
|
print("Freeing the Message now")
|
||||||
|
nmlib.notmuch_message_destroy (self._msg)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class STATUS(object):
|
||||||
NULL_POINTER = 7
|
NULL_POINTER = 7
|
||||||
TAG_TOO_LONG = 8
|
TAG_TOO_LONG = 8
|
||||||
UNBALANCED_FREEZE_THAW = 9
|
UNBALANCED_FREEZE_THAW = 9
|
||||||
LAST_STATUS = 10
|
NOT_INITIALIZED = 10
|
||||||
|
|
||||||
"""Get a string representation of a notmuch_status_t value."""
|
"""Get a string representation of a notmuch_status_t value."""
|
||||||
status2str = nmlib.notmuch_status_to_string
|
status2str = nmlib.notmuch_status_to_string
|
||||||
|
@ -26,6 +26,9 @@ class STATUS(object):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Get a string representation of a notmuch_status_t value."""
|
"""Get a string representation of a notmuch_status_t value."""
|
||||||
|
# define strings for custom error messages
|
||||||
|
if self._status == STATUS.NOT_INITIALIZED:
|
||||||
|
return "Operation on uninitialized DB/MSG/THREAD impossible."
|
||||||
return str(STATUS.status2str(self._status))
|
return str(STATUS.status2str(self._status))
|
||||||
|
|
||||||
class NotmuchError(Exception):
|
class NotmuchError(Exception):
|
||||||
|
|
Loading…
Reference in a new issue