Improve Python API. Add MemoryStream class.
* python/libmu_py/sieve.c (api_sieve_machine_init): Improve. (api_sieve_machine_error_text): Add new function. * python/libmu_py/stream.c (api_memory_stream_create): Likewise. (api_stream_to_message): Likewise. * python/mailutils/error.py (Error): Add optional str_error argument. * python/mailutils/sieve.py: Update. * python/mailutils/stream.py (to_message): Add new method. (MemoryStream): Add new class.
Showing
5 changed files
with
115 additions
and
6 deletions
... | @@ -94,12 +94,58 @@ api_sieve_machine_init (PyObject *self, PyObject *args) | ... | @@ -94,12 +94,58 @@ api_sieve_machine_init (PyObject *self, PyObject *args) |
94 | { | 94 | { |
95 | int status; | 95 | int status; |
96 | PySieveMachine *py_mach; | 96 | PySieveMachine *py_mach; |
97 | mu_stream_t str, estr; | ||
97 | 98 | ||
98 | if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach)) | 99 | if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach)) |
99 | return NULL; | 100 | return NULL; |
100 | 101 | ||
101 | status = mu_sieve_machine_init (&py_mach->mach); | 102 | status = mu_memory_stream_create (&str, MU_STREAM_RDWR); |
103 | if (status) | ||
102 | return _ro (PyInt_FromLong (status)); | 104 | return _ro (PyInt_FromLong (status)); |
105 | status = mu_log_stream_create (&estr, str); | ||
106 | mu_stream_unref (str); | ||
107 | if (status) | ||
108 | return _ro (PyInt_FromLong (status)); | ||
109 | |||
110 | status = mu_sieve_machine_init_ex (&py_mach->mach, NULL, estr); | ||
111 | mu_stream_unref (estr); | ||
112 | return _ro (PyInt_FromLong (status)); | ||
113 | } | ||
114 | |||
115 | static PyObject * | ||
116 | api_sieve_machine_error_text (PyObject *self, PyObject *args) | ||
117 | { | ||
118 | int status; | ||
119 | PySieveMachine *py_mach; | ||
120 | mu_stream_t estr; | ||
121 | mu_transport_t trans[2]; | ||
122 | PyObject *retval; | ||
123 | size_t length = 0; | ||
124 | |||
125 | if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach)) | ||
126 | return NULL; | ||
127 | if (!py_mach->mach) | ||
128 | PyErr_SetString (PyExc_RuntimeError, "Uninitialized Sieve machine"); | ||
129 | |||
130 | mu_sieve_get_diag_stream (py_mach->mach, &estr); | ||
131 | status = mu_stream_ioctl (estr, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, | ||
132 | trans); | ||
133 | if (status == 0) | ||
134 | { | ||
135 | mu_stream_t str = (mu_stream_t) trans[0]; | ||
136 | |||
137 | mu_stream_size (str, &length); | ||
138 | status = mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, | ||
139 | trans); | ||
140 | mu_stream_truncate (str, 0); | ||
141 | } | ||
142 | |||
143 | if (status) | ||
144 | PyErr_SetString (PyExc_RuntimeError, mu_strerror (status)); | ||
145 | retval = PyString_FromStringAndSize ((char*) trans[0], length); | ||
146 | |||
147 | mu_stream_unref (estr); | ||
148 | return _ro (retval); | ||
103 | } | 149 | } |
104 | 150 | ||
105 | static PyObject * | 151 | static PyObject * |
... | @@ -110,7 +156,8 @@ api_sieve_machine_destroy (PyObject *self, PyObject *args) | ... | @@ -110,7 +156,8 @@ api_sieve_machine_destroy (PyObject *self, PyObject *args) |
110 | if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach)) | 156 | if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach)) |
111 | return NULL; | 157 | return NULL; |
112 | 158 | ||
113 | if (py_mach->mach) { | 159 | if (py_mach->mach) |
160 | { | ||
114 | struct _mu_py_sieve_logger *s = mu_sieve_get_data (py_mach->mach); | 161 | struct _mu_py_sieve_logger *s = mu_sieve_get_data (py_mach->mach); |
115 | if (s) | 162 | if (s) |
116 | free (s); | 163 | free (s); |
... | @@ -280,6 +327,9 @@ static PyMethodDef methods[] = { | ... | @@ -280,6 +327,9 @@ static PyMethodDef methods[] = { |
280 | { "machine_destroy", (PyCFunction) api_sieve_machine_destroy, METH_VARARGS, | 327 | { "machine_destroy", (PyCFunction) api_sieve_machine_destroy, METH_VARARGS, |
281 | "Destroy Sieve 'machine'." }, | 328 | "Destroy Sieve 'machine'." }, |
282 | 329 | ||
330 | { "errortext", (PyCFunction) api_sieve_machine_error_text, METH_VARARGS, | ||
331 | "Return the most recent error description." }, | ||
332 | |||
283 | { "compile", (PyCFunction) api_sieve_compile, METH_VARARGS, | 333 | { "compile", (PyCFunction) api_sieve_compile, METH_VARARGS, |
284 | "Compile the sieve script from the file 'name'." }, | 334 | "Compile the sieve script from the file 'name'." }, |
285 | 335 | ... | ... |
... | @@ -126,6 +126,25 @@ api_stdio_stream_create (PyObject *self, PyObject *args) | ... | @@ -126,6 +126,25 @@ api_stdio_stream_create (PyObject *self, PyObject *args) |
126 | } | 126 | } |
127 | 127 | ||
128 | static PyObject * | 128 | static PyObject * |
129 | api_memory_stream_create (PyObject *self, PyObject *args) | ||
130 | { | ||
131 | int status; | ||
132 | char *s; | ||
133 | PyStream *py_stm; | ||
134 | |||
135 | if (!PyArg_ParseTuple (args, "O!s", &PyStreamType, &py_stm, &s)) | ||
136 | return NULL; | ||
137 | |||
138 | status = mu_memory_stream_create (&py_stm->stm, MU_STREAM_RDWR); | ||
139 | if (status == 0) | ||
140 | { | ||
141 | status = mu_stream_write (py_stm->stm, s, strlen (s), NULL); | ||
142 | mu_stream_seek (py_stm->stm, MU_SEEK_SET, 0, NULL); | ||
143 | } | ||
144 | return _ro (PyInt_FromLong (status)); | ||
145 | } | ||
146 | |||
147 | static PyObject * | ||
129 | api_prog_stream_create (PyObject *self, PyObject *args) | 148 | api_prog_stream_create (PyObject *self, PyObject *args) |
130 | { | 149 | { |
131 | int status, flags; | 150 | int status, flags; |
... | @@ -317,6 +336,22 @@ api_stream_readline (PyObject *self, PyObject *args) | ... | @@ -317,6 +336,22 @@ api_stream_readline (PyObject *self, PyObject *args) |
317 | return _ro (py_ret); | 336 | return _ro (py_ret); |
318 | } | 337 | } |
319 | 338 | ||
339 | static PyObject * | ||
340 | api_stream_to_message (PyObject *self, PyObject *args) | ||
341 | { | ||
342 | int status; | ||
343 | PyStream *py_stm; | ||
344 | PyMessage *py_msg = PyMessage_NEW (); | ||
345 | |||
346 | if (!PyArg_ParseTuple (args, "O!", &PyStreamType, &py_stm)) | ||
347 | return NULL; | ||
348 | |||
349 | Py_INCREF (py_msg); | ||
350 | |||
351 | status = mu_stream_to_message (py_stm->stm, &py_msg->msg); | ||
352 | return status_object (status, (PyObject *)py_msg); | ||
353 | } | ||
354 | |||
320 | static PyMethodDef methods[] = { | 355 | static PyMethodDef methods[] = { |
321 | { "tcp_stream_create", (PyCFunction) api_tcp_stream_create, METH_VARARGS, | 356 | { "tcp_stream_create", (PyCFunction) api_tcp_stream_create, METH_VARARGS, |
322 | "" }, | 357 | "" }, |
... | @@ -327,6 +362,10 @@ static PyMethodDef methods[] = { | ... | @@ -327,6 +362,10 @@ static PyMethodDef methods[] = { |
327 | { "stdio_stream_create", (PyCFunction) api_stdio_stream_create, METH_VARARGS, | 362 | { "stdio_stream_create", (PyCFunction) api_stdio_stream_create, METH_VARARGS, |
328 | "" }, | 363 | "" }, |
329 | 364 | ||
365 | { "memory_stream_create", | ||
366 | (PyCFunction) api_memory_stream_create, METH_VARARGS, | ||
367 | "" }, | ||
368 | |||
330 | { "prog_stream_create", (PyCFunction) api_prog_stream_create, METH_VARARGS, | 369 | { "prog_stream_create", (PyCFunction) api_prog_stream_create, METH_VARARGS, |
331 | "" }, | 370 | "" }, |
332 | 371 | ||
... | @@ -364,6 +403,9 @@ static PyMethodDef methods[] = { | ... | @@ -364,6 +403,9 @@ static PyMethodDef methods[] = { |
364 | { "readline", (PyCFunction) api_stream_readline, METH_VARARGS, | 403 | { "readline", (PyCFunction) api_stream_readline, METH_VARARGS, |
365 | "" }, | 404 | "" }, |
366 | 405 | ||
406 | { "to_message", (PyCFunction) api_stream_to_message, METH_VARARGS, | ||
407 | "" }, | ||
408 | |||
367 | { NULL, NULL, 0, NULL } | 409 | { NULL, NULL, 0, NULL } |
368 | }; | 410 | }; |
369 | 411 | ... | ... |
... | @@ -22,9 +22,9 @@ def strerror (status): | ... | @@ -22,9 +22,9 @@ def strerror (status): |
22 | return error.strerror (status) | 22 | return error.strerror (status) |
23 | 23 | ||
24 | class Error (Exception): | 24 | class Error (Exception): |
25 | def __init__ (self, status): | 25 | def __init__ (self, status, str_error=None): |
26 | self.status = status | 26 | self.status = status |
27 | self.strerror = strerror (status) | 27 | self.strerror = str_error or strerror (status) |
28 | def __str__ (self): | 28 | def __str__ (self): |
29 | return "%d: %s" % (self.status, self.strerror) | 29 | return "%d: %s" % (self.status, self.strerror) |
30 | 30 | ... | ... |
... | @@ -26,6 +26,9 @@ class Machine: | ... | @@ -26,6 +26,9 @@ class Machine: |
26 | raise SieveMachineError (status) | 26 | raise SieveMachineError (status) |
27 | 27 | ||
28 | def __del__ (self): | 28 | def __del__ (self): |
29 | s = sieve.errortext (self.mach) | ||
30 | if s: | ||
31 | raise SieveMachineError (MU_ERR_FAILURE, s) | ||
29 | sieve.machine_destroy (self.mach) | 32 | sieve.machine_destroy (self.mach) |
30 | del self.mach | 33 | del self.mach |
31 | 34 | ||
... | @@ -38,7 +41,7 @@ class Machine: | ... | @@ -38,7 +41,7 @@ class Machine: |
38 | """Compile the sieve script from the file 'name'.""" | 41 | """Compile the sieve script from the file 'name'.""" |
39 | status = sieve.compile (self.mach, name) | 42 | status = sieve.compile (self.mach, name) |
40 | if status: | 43 | if status: |
41 | raise SieveMachineError (status) | 44 | raise SieveMachineError (status, sieve.errortext (self.mach)) |
42 | 45 | ||
43 | def disass (self): | 46 | def disass (self): |
44 | """Dump the disassembled code of the sieve machine.""" | 47 | """Dump the disassembled code of the sieve machine.""" |
... | @@ -58,4 +61,4 @@ class Machine: | ... | @@ -58,4 +61,4 @@ class Machine: |
58 | over the 'msg'.""" | 61 | over the 'msg'.""" |
59 | status = sieve.message (self.mach, msg.msg) | 62 | status = sieve.message (self.mach, msg.msg) |
60 | if status: | 63 | if status: |
61 | raise SieveMachineError (status) | 64 | raise SieveMachineError (status, sieve.errortext (self.mach)) | ... | ... |
... | @@ -103,6 +103,13 @@ class Stream: | ... | @@ -103,6 +103,13 @@ class Stream: |
103 | raise StreamError (status) | 103 | raise StreamError (status) |
104 | return rbuf | 104 | return rbuf |
105 | 105 | ||
106 | def to_message (self): | ||
107 | from mailutils import message | ||
108 | status, msg = stream.to_message (self.stm) | ||
109 | if status: | ||
110 | raise StreamError (status) | ||
111 | return message.Message (msg) | ||
112 | |||
106 | class TcpStream (Stream): | 113 | class TcpStream (Stream): |
107 | def __init__ (self, host, port, flags=MU_STREAM_READ): | 114 | def __init__ (self, host, port, flags=MU_STREAM_READ): |
108 | Stream.__init__ (self) | 115 | Stream.__init__ (self) |
... | @@ -124,6 +131,13 @@ class StdioStream (Stream): | ... | @@ -124,6 +131,13 @@ class StdioStream (Stream): |
124 | if status: | 131 | if status: |
125 | raise StreamError (status) | 132 | raise StreamError (status) |
126 | 133 | ||
134 | class MemoryStream (Stream): | ||
135 | def __init__ (self, s): | ||
136 | Stream.__init__ (self) | ||
137 | status = stream.memory_stream_create (self.stm, s) | ||
138 | if status: | ||
139 | raise StreamError (status) | ||
140 | |||
127 | class ProgStream (Stream): | 141 | class ProgStream (Stream): |
128 | def __init__ (self, progname, flags=MU_STREAM_READ): | 142 | def __init__ (self, progname, flags=MU_STREAM_READ): |
129 | Stream.__init__ (self) | 143 | Stream.__init__ (self) | ... | ... |
-
Please register or sign in to post a comment