mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-22 10:58:10 +01:00
python: Ensure that we pass utf-8 encoded string to libnotmuch
If we use unicode objects, libnotmuch would not cope with null bytes in the byte array, so we need to make sure they are nicely formatted as utf-8. Introduce a helper function _str which does this throughout the code. Patch slightly modified by Sebastian Spaeth. Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
parent
bdaee77e1b
commit
8e7a108363
3 changed files with 24 additions and 23 deletions
|
@ -19,12 +19,11 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from ctypes import c_int, c_char_p, c_void_p, c_uint, c_long, byref
|
from ctypes import c_int, c_char_p, c_void_p, c_uint, c_long, byref
|
||||||
from notmuch.globals import nmlib, STATUS, NotmuchError, Enum
|
from notmuch.globals import nmlib, STATUS, NotmuchError, Enum, _str
|
||||||
from notmuch.thread import Threads
|
from notmuch.thread import Threads
|
||||||
from notmuch.message import Messages, Message
|
from notmuch.message import Messages, Message
|
||||||
from notmuch.tag import Tags
|
from notmuch.tag import Tags
|
||||||
|
|
||||||
|
|
||||||
class Database(object):
|
class Database(object):
|
||||||
"""Represents a notmuch database (wraps notmuch_database_t)
|
"""Represents a notmuch database (wraps notmuch_database_t)
|
||||||
|
|
||||||
|
@ -101,7 +100,6 @@ class Database(object):
|
||||||
Database._std_db_path = self._get_user_default_db()
|
Database._std_db_path = self._get_user_default_db()
|
||||||
path = Database._std_db_path
|
path = Database._std_db_path
|
||||||
|
|
||||||
assert isinstance(path, basestring), 'Path must be a string or None.'
|
|
||||||
if create == False:
|
if create == False:
|
||||||
self.open(path, mode)
|
self.open(path, mode)
|
||||||
else:
|
else:
|
||||||
|
@ -132,7 +130,7 @@ class Database(object):
|
||||||
raise NotmuchError(message="Cannot create db, this Database() "
|
raise NotmuchError(message="Cannot create db, this Database() "
|
||||||
"already has an open one.")
|
"already has an open one.")
|
||||||
|
|
||||||
res = Database._create(path, Database.MODE.READ_WRITE)
|
res = Database._create(_str(path), Database.MODE.READ_WRITE)
|
||||||
|
|
||||||
if res is None:
|
if res is None:
|
||||||
raise NotmuchError(
|
raise NotmuchError(
|
||||||
|
@ -152,9 +150,7 @@ class Database(object):
|
||||||
:exception: Raises :exc:`NotmuchError` in case
|
:exception: Raises :exc:`NotmuchError` in case
|
||||||
of any failure (after printing an error message on stderr).
|
of any failure (after printing an error message on stderr).
|
||||||
"""
|
"""
|
||||||
if isinstance(path, unicode):
|
res = Database._open(_str(path), mode)
|
||||||
path = path.encode('utf-8')
|
|
||||||
res = Database._open(path, mode)
|
|
||||||
|
|
||||||
if res is None:
|
if res is None:
|
||||||
raise NotmuchError(
|
raise NotmuchError(
|
||||||
|
@ -259,12 +255,10 @@ class Database(object):
|
||||||
#we got a relative path, make it absolute
|
#we got a relative path, make it absolute
|
||||||
abs_dirpath = os.path.abspath(os.path.join(self.get_path(), path))
|
abs_dirpath = os.path.abspath(os.path.join(self.get_path(), path))
|
||||||
|
|
||||||
if isinstance(path, unicode):
|
dir_p = Database._get_directory(self._db, _str(path))
|
||||||
path = path.encode('UTF-8')
|
|
||||||
dir_p = Database._get_directory(self._db, path)
|
|
||||||
|
|
||||||
# return the Directory, init it with the absolute path
|
# return the Directory, init it with the absolute path
|
||||||
return Directory(abs_dirpath, dir_p, self)
|
return Directory(_str(abs_dirpath), dir_p, self)
|
||||||
|
|
||||||
def add_message(self, filename, sync_maildir_flags=False):
|
def add_message(self, filename, sync_maildir_flags=False):
|
||||||
"""Adds a new message to the database
|
"""Adds a new message to the database
|
||||||
|
@ -321,7 +315,7 @@ class Database(object):
|
||||||
|
|
||||||
msg_p = c_void_p()
|
msg_p = c_void_p()
|
||||||
status = nmlib.notmuch_database_add_message(self._db,
|
status = nmlib.notmuch_database_add_message(self._db,
|
||||||
filename,
|
_str(filename),
|
||||||
byref(msg_p))
|
byref(msg_p))
|
||||||
|
|
||||||
if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
|
if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
|
||||||
|
@ -390,10 +384,8 @@ class Database(object):
|
||||||
# Raise a NotmuchError if not initialized
|
# Raise a NotmuchError if not initialized
|
||||||
self._verify_initialized_db()
|
self._verify_initialized_db()
|
||||||
|
|
||||||
msg_p = Database._find_message(self._db, msgid)
|
msg_p = Database._find_message(self._db, _str(msgid))
|
||||||
if msg_p is None:
|
return msg_p and Message(msg_p, self) or None
|
||||||
return None
|
|
||||||
return Message(msg_p, self)
|
|
||||||
|
|
||||||
def get_all_tags(self):
|
def get_all_tags(self):
|
||||||
"""Returns :class:`Tags` with a list of all tags found in the database
|
"""Returns :class:`Tags` with a list of all tags found in the database
|
||||||
|
@ -535,11 +527,8 @@ class Query(object):
|
||||||
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
# create reference to parent db to keep it alive
|
# create reference to parent db to keep it alive
|
||||||
self._db = db
|
self._db = db
|
||||||
if isinstance(querystr, unicode):
|
|
||||||
# xapian takes utf-8 encoded byte arrays
|
|
||||||
querystr = querystr.encode('utf-8')
|
|
||||||
# create query, return None if too little mem available
|
# create query, return None if too little mem available
|
||||||
query_p = Query._create(db.db_p, querystr)
|
query_p = Query._create(db.db_p, _str(querystr))
|
||||||
if query_p is None:
|
if query_p is None:
|
||||||
NotmuchError(STATUS.NULL_POINTER)
|
NotmuchError(STATUS.NULL_POINTER)
|
||||||
self._query = query_p
|
self._query = query_p
|
||||||
|
|
|
@ -98,3 +98,15 @@ class NotmuchError(Exception):
|
||||||
return self.args[0]
|
return self.args[0]
|
||||||
else:
|
else:
|
||||||
return STATUS.status2str(self.args[1])
|
return STATUS.status2str(self.args[1])
|
||||||
|
|
||||||
|
def _str(value):
|
||||||
|
"""Ensure a nicely utf-8 encoded string to pass to libnotmuch
|
||||||
|
|
||||||
|
C++ code expects strings to be well formatted and
|
||||||
|
unicode strings to have no null bytes."""
|
||||||
|
if not isinstance(value, basestring):
|
||||||
|
raise TypeError("Expected str or unicode, got %s" % str(type(value)))
|
||||||
|
if isinstance(value, unicode):
|
||||||
|
return value.encode('UTF-8')
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
|
||||||
|
|
||||||
from ctypes import c_char_p, c_void_p, c_long, c_uint, c_int
|
from ctypes import c_char_p, c_void_p, c_long, c_uint, c_int
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from notmuch.globals import nmlib, STATUS, NotmuchError, Enum
|
from notmuch.globals import nmlib, STATUS, NotmuchError, Enum, _str
|
||||||
from notmuch.tag import Tags
|
from notmuch.tag import Tags
|
||||||
from notmuch.filename import Filenames
|
from notmuch.filename import Filenames
|
||||||
import sys
|
import sys
|
||||||
|
@ -505,7 +505,7 @@ class Message(object):
|
||||||
if self._msg is None:
|
if self._msg is None:
|
||||||
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
|
|
||||||
status = nmlib.notmuch_message_add_tag(self._msg, tag)
|
status = nmlib.notmuch_message_add_tag(self._msg, _str(tag))
|
||||||
|
|
||||||
# bail out on failure
|
# bail out on failure
|
||||||
if status != STATUS.SUCCESS:
|
if status != STATUS.SUCCESS:
|
||||||
|
@ -549,7 +549,7 @@ class Message(object):
|
||||||
if self._msg is None:
|
if self._msg is None:
|
||||||
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
raise NotmuchError(STATUS.NOT_INITIALIZED)
|
||||||
|
|
||||||
status = nmlib.notmuch_message_remove_tag(self._msg, tag)
|
status = nmlib.notmuch_message_remove_tag(self._msg, _str(tag))
|
||||||
# bail out on error
|
# bail out on error
|
||||||
if status != STATUS.SUCCESS:
|
if status != STATUS.SUCCESS:
|
||||||
raise NotmuchError(status)
|
raise NotmuchError(status)
|
||||||
|
|
Loading…
Reference in a new issue