2 This file is part of notmuch.
4 Notmuch is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation, either version 3 of the License, or (at your
7 option) any later version.
9 Notmuch is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with notmuch. If not, see <http://www.gnu.org/licenses/>.
17 Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'
20 from ctypes import CDLL, c_char_p, c_int
21 from ctypes.util import find_library
23 #-----------------------------------------------------------------------------
24 #package-global instance of the notmuch library
26 nmlib = CDLL("libnotmuch.so.1")
28 raise ImportError("Could not find shared 'notmuch' library.")
32 """Provides ENUMS as "code=Enum(['a','b','c'])" where code.a=0 etc..."""
33 def __init__(self, names):
34 for number, name in enumerate(names):
35 setattr(self, name, number)
39 """Enum with a string representation of a notmuch_status_t value."""
40 _status2str = nmlib.notmuch_status_to_string
41 _status2str.restype = c_char_p
42 _status2str.argtypes = [c_int]
44 def __init__(self, statuslist):
45 """It is initialized with a list of strings that are available as
46 Status().string1 - Status().stringn attributes.
48 super(Status, self).__init__(statuslist)
51 def status2str(self, status):
52 """Get a string representation of a notmuch_status_t value."""
53 # define strings for custom error messages
54 if status == STATUS.NOT_INITIALIZED:
55 return "Operation on uninitialized object impossible."
56 return str(Status._status2str(status))
58 STATUS = Status(['SUCCESS',
64 'DUPLICATE_MESSAGE_ID',
67 'UNBALANCED_FREEZE_THAW',
70 """STATUS is a class, whose attributes provide constants that serve as return
71 indicators for notmuch functions. Currently the following ones are defined. For
72 possible return values and specific meaning for each method, see the method
81 * DUPLICATE_MESSAGE_ID
84 * UNBALANCED_FREEZE_THAW
88 Invoke the class method `notmuch.STATUS.status2str` with a status value as
89 argument to receive a human readable string"""
90 STATUS.__name__ = 'STATUS'
92 class NotmuchError(Exception):
93 """Is initiated with a (notmuch.STATUS[, message=None]). It will not
94 return an instance of the class NotmuchError, but a derived instance
95 of a more specific Error Message, e.g. OutOfMemoryError. Each status
96 but SUCCESS has a corresponding subclassed Exception."""
99 def get_subclass_exc(cls, status, message=None):
100 """Returns a fine grained Exception() type,detailing the error status"""
102 STATUS.OUT_OF_MEMORY: OutOfMemoryError,
103 STATUS.READ_ONLY_DATABASE: ReadOnlyDatabaseError,
104 STATUS.XAPIAN_EXCEPTION: XapianError,
105 STATUS.FILE_ERROR: FileError,
106 STATUS.FILE_NOT_EMAIL: FileNotEmailError,
107 STATUS.DUPLICATE_MESSAGE_ID: DuplicateMessageIdError,
108 STATUS.NULL_POINTER: NullPointerError,
109 STATUS.TAG_TOO_LONG: TagTooLongError,
110 STATUS.UNBALANCED_FREEZE_THAW: UnbalancedFreezeThawError,
111 STATUS.UNBALANCED_ATOMIC: UnbalancedAtomicError,
112 STATUS.NOT_INITIALIZED: NotInitializedError
114 assert 0 < status <= len(subclasses)
115 return subclasses[status](status, message)
117 def __init__(self, status, message=None):
119 self.message = message
122 if self.message is not None:
124 elif self.status is not None:
125 return STATUS.status2str(self.status)
127 return 'Unknown error'
129 # List of Subclassed exceptions that correspond to STATUS values and are
130 # subclasses of NotmuchError:
131 class OutOfMemoryError(NotmuchError):
133 class ReadOnlyDatabaseError(NotmuchError):
135 class XapianError(NotmuchError):
137 class FileError(NotmuchError):
139 class FileNotEmailError(NotmuchError):
141 class DuplicateMessageIdError(NotmuchError):
143 class NullPointerError(NotmuchError):
145 class TagTooLongError(NotmuchError):
147 class UnbalancedFreezeThawError(NotmuchError):
149 class UnbalancedAtomicError(NotmuchError):
151 class NotInitializedError(NotmuchError):
156 """Ensure a nicely utf-8 encoded string to pass to libnotmuch
158 C++ code expects strings to be well formatted and
159 unicode strings to have no null bytes."""
160 if not isinstance(value, basestring):
161 raise TypeError("Expected str or unicode, got %s" % str(type(value)))
162 if isinstance(value, unicode):
163 return value.encode('UTF-8')