Add basic python bindings for linestack.
authorJelmer Vernooij <jelmer@samba.org>
Sat, 13 Jun 2009 14:09:37 +0000 (16:09 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Sat, 13 Jun 2009 14:09:37 +0000 (16:09 +0200)
libirc/Makefile
libirc/python/irc.c
libirc/python/irc.h
libirc/python/linestack.c [new file with mode: 0644]
libirc/python/state.c
libirc/python/tests/test_irc.py

index 20ccfdf4f15e0b1f0eaacb846dce0bbd21378c7a..d5fbca4110f4fd053e446466b26d06e8f8aec1a5 100644 (file)
@@ -36,6 +36,7 @@ libirc_headers = \
 
 pyirc_objs = $(libircdir)/python/irc.o \
                         $(libircdir)/python/transport.o \
+                        $(libircdir)/python/linestack.o \
                         $(libircdir)/python/state.o
 
 $(libirc_objs): CFLAGS+=-fPIC
index e90f0b871082279aa0f2faec32ec2da3165ba1c1..8cc26fd2334a554691ebd14d7a8804600930fd20 100644 (file)
@@ -1129,6 +1129,9 @@ void initirc(void)
     if (PyType_Ready(&PyTransportType) < 0)
         return;
 
+    if (PyType_Ready(&PyLinestackType) < 0)
+        return;
+
     if (PyType_Ready(&PyChannelModeDictType) < 0)
         return;
 
@@ -1158,5 +1161,9 @@ void initirc(void)
     PyModule_AddObject(m, "QueryStack", (PyObject *)&PyQueryStackType);
     Py_INCREF(&PyTransportType);
     PyModule_AddObject(m, "Transport", (PyObject *)&PyTransportType);
+    Py_INCREF(&PyLinestackType);
+    PyModule_AddObject(m, "Linestack", (PyObject *)&PyLinestackType);
+    PyModule_AddIntConstant(m, "TO_SERVER", TO_SERVER);
+    PyModule_AddIntConstant(m, "FROM_SERVER", FROM_SERVER);
 }
 
index 1655eddb59d1e23d3dc13109a81fa52e10730472..407e0e5adb53c2c824a7a36c5c9db3add3d9dd02 100644 (file)
@@ -50,10 +50,19 @@ typedef struct {
     PyObject_HEAD
     struct irc_transport *transport;
     PyObject *parent;
-} PyTransportObject;PyTypeObject PyTransportType;
+} PyTransportObject;
+PyTypeObject PyTransportType;
 struct irc_transport *wrap_py_transport(PyObject *obj);
 struct irc_transport_ops py_transport_ops;
 
+/* linestack */
+
+typedef struct {
+    PyObject_HEAD
+    struct linestack_context *linestack;
+    PyObject *parent;
+} PyLinestackObject;
+PyTypeObject PyLinestackType;
 
 /* GList iterator */
 PyObject *py_g_list_iter(GList *list, PyObject *parent, PyObject *(*converter) (PyObject *parent, void *));
@@ -82,6 +91,8 @@ typedef struct {
     PyObject *parent;
 } PyNetworkStateObject;
 
+struct irc_network_state *PyObject_AsNetworkState(PyObject *obj);
+
 PyTypeObject PyChannelStateType;
 
 typedef struct {
diff --git a/libirc/python/linestack.c b/libirc/python/linestack.c
new file mode 100644 (file)
index 0000000..a3af6b7
--- /dev/null
@@ -0,0 +1,106 @@
+/*    ctrlproxy: A modular IRC proxy
+ *    (c) 2002-2009 Jelmer Vernooij <jelmer@nl.linux.org>
+ *     vim: expandtab
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdbool.h>
+#include "ctrlproxy.h"
+#include "redirect.h"
+#include "libirc/python/irc.h"
+
+static int py_linestack_dealloc(PyLinestackObject *self)
+{
+    if (self->parent != NULL)
+        Py_DECREF(self->parent);
+    else
+        free_linestack_context(self->linestack);
+    PyObject_Del((PyObject *)self);
+    return 0;
+}
+
+static PyObject *py_linestack_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    char *kwnames[] = { "name", "truncate", "basedir", "state", NULL };
+    PyLinestackObject *self;
+       char *name, *basedir;
+       int truncate;
+       PyObject *py_state;
+    struct irc_network_state *state;
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sisO", kwnames, 
+                                     &name, &truncate, &basedir, &py_state))
+        return NULL;
+
+    self = (PyLinestackObject *)type->tp_alloc(type, 0);
+    if (self == NULL) {
+        PyErr_NoMemory();
+        return NULL;
+    }
+
+    state = PyObject_AsNetworkState(py_state);
+    if (state == NULL) {
+        return NULL;
+    }
+
+    self->parent = NULL;
+    self->linestack = create_linestack(name, truncate, basedir, state);
+
+    return (PyObject *)self;
+}
+
+static PyObject *py_linestack_insert_line(PyLinestackObject *self, PyObject *args)
+{
+    struct irc_line *l;
+    gboolean ret;
+       enum data_direction dir;
+       PyObject *py_line, *py_state;
+       struct irc_network_state *state;
+
+       if (!PyArg_ParseTuple(args, "OiO", &py_line, &dir, &py_state))
+               return NULL;
+
+    l = PyObject_AsLine(py_line);
+    if (l == NULL) {
+        return NULL;
+    }
+
+    state = PyObject_AsNetworkState(py_state);
+    if (state == NULL) {
+        return NULL;
+    }
+
+    ret = linestack_insert_line(self->linestack, l, dir, state);
+    free_line(l);
+
+    return PyBool_FromLong(ret);
+}
+
+static PyMethodDef py_linestack_methods[] = {
+    { "insert_line", (PyCFunction)py_linestack_insert_line, 
+        METH_VARARGS, "Insert line" },
+    { NULL }
+};
+
+PyTypeObject PyLinestackType = {
+    .tp_name = "Linestack",
+    .tp_flags = Py_TPFLAGS_DEFAULT,
+    .tp_new = py_linestack_new,
+    .tp_methods = py_linestack_methods,
+    .tp_basicsize = sizeof(PyLinestackObject),
+    .tp_dealloc = (destructor)py_linestack_dealloc,
+};
+
+
index 73c84a09f99c9642eba397f93d23945fa10052f6..23ecda9b4bd14abd7a142c64d91bff5340e73049 100644 (file)
 #include "redirect.h"
 #include "libirc/python/irc.h"
 
+struct irc_network_state *PyObject_AsNetworkState(PyObject *obj)
+{
+    if (!PyObject_TypeCheck(obj, &PyNetworkStateType)) {
+        PyErr_SetNone(PyExc_TypeError);
+        return NULL;
+    }
+
+    return ((PyNetworkStateObject *)obj)->state;
+}
+
 static PyObject *py_networkinfo_is_prefix(PyNetworkInfoObject *self, PyObject *args)
 {
     char *prefix;
index 32efd35109118c261e8623a1129531f2dae6377b..18cd4c1f1a675e380ff083f276fb37dacfd21140 100644 (file)
@@ -660,3 +660,22 @@ class NetsplitTests(unittest.TestCase):
             c.nicks.add(irc.Nick("some%d!someuser@somehost" % i))
         self.client.state.add(c)
         self.assertLines([":some%d!someuser@somehost QUIT :us upstream" % i for i in range(10)])
+
+
+class LinestackTests(unittest.TestCase):
+
+    def get_basedir(self):
+        return "/tmp"
+
+    def get_state(self):
+        return irc.NetworkState("nick", "user", "host")
+
+    def test_create(self):
+        ls = irc.Linestack("network", True, self.get_basedir(), self.get_state())
+        self.assertTrue(ls is not None)
+
+    def test_insert_line(self):
+        state = self.get_state()
+        ls = irc.Linestack("insert_line", True, self.get_basedir(), state)
+        ls.insert_line(":somebody!some@host PRIVMSG #bla :BAR!", 
+                       irc.TO_SERVER, state)