]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/mod-python.c
mod-python: make emb_dump raise exception on failure
[irc/evilnet/x3.git] / src / mod-python.c
index 6efc11924eab2f87c9ab27a80c3d27b5d307f5b3..1ef9b0a0714058725a63aa337165b0d2e9330d84 100644 (file)
@@ -90,11 +90,17 @@ emb_dump(UNUSED_ARG(PyObject *self), PyObject *args)
 
     if(!PyArg_ParseTuple(args, "s:dump", &buf ))
         return NULL;
+
     safestrncpy(linedup, buf, sizeof(linedup));
+
     if(parse_line(linedup, 1)) {
         irc_raw(buf);
         ret = 1;
+    } else {
+        PyErr_SetString(PyExc_Exception, "invalid protocol message");
+        return NULL;
     }
+
     return Py_BuildValue("i", ret);
 }
 
@@ -146,53 +152,74 @@ emb_send_target_notice(UNUSED_ARG(PyObject *self), PyObject *args)
     return Py_BuildValue("i", ret);
 }
 
+static PyObject*
+pyobj_from_usernode(struct userNode* user) {
+    unsigned int n;
+    struct modeNode *mn;
+    PyObject* pChanList = PyTuple_New(user->channels.used);
+
+    for (n=0; n < user->channels.used; n++) {
+        mn = user->channels.list[n];
+        PyTuple_SetItem(pChanList, n, Py_BuildValue("s", mn->channel->name));
+    }
+
+    return Py_BuildValue("{"
+            "s: s, " /* nick */
+            "s: s, " /* ident */
+            "s: s, " /* info */
+            "s: s, " /* hostname */
+            "s: s, " /* ip */
+            "s: s, " /* fakehost */
+            "s: s, " /* sethost */
+            "s: s, " /* crypthost */
+            "s: s, " /* cryptip */
+#ifdef WITH_PROTOCOL_P10
+            "s: s, " /* numeric */
+#endif /* WITH_PROTOCOL_P10 */
+            "s: i, " /* loc */
+            "s: i, " /* no_notice */
+            "s: s, " /* mark */
+            "s: s, " /* version_reply */
+            "s: s, " /* account */
+            "s: O}", /* channels */
+            "nick", user->nick,
+            "ident", user->ident,
+            "info", user->info,
+            "hostname", user->hostname,
+            "ip", irc_ntoa(&user->ip),
+            "fakehost", user->fakehost,
+            "sethost", user->sethost,
+            "crypthost", user->crypthost,
+            "cryptip", user->cryptip,
+#ifdef WITH_PROTOCOL_P10
+            "numeric", user->numeric,
+#endif /* WITH_PROTOCOL_P10 */
+            "loc", user->loc,
+            "no_notice", user->no_notice,
+            "mark", user->mark,
+            "version_reply", user->version_reply,
+            "account", user->handle_info ? user->handle_info->handle : NULL,
+            "channels", pChanList);
+}
+
 static PyObject*
 emb_get_user(UNUSED_ARG(PyObject *self), PyObject *args)
 {
     /* Get a python object containing everything x3 knows about a user, by nick.
         usage: _svc.get_user(<nick>)
     */
-    char *nick;
+    char const* nick;
     struct userNode *user;
-    struct modeNode *mn;
-    unsigned int n;
-    PyObject* pChanList;
-
 
     if(!PyArg_ParseTuple(args, "s", &nick))
         return NULL;
+
     if(!(user = GetUserH(nick))) {
-        /* TODO: generate python exception here */
+        PyErr_SetString(PyExc_Exception, "no such user");
         return NULL;
     }
-    pChanList = PyTuple_New(user->channels.used);
-    for(n=0;n<user->channels.used;n++) {
-        mn = user->channels.list[n];
-        PyTuple_SetItem(pChanList, n, Py_BuildValue("s", mn->channel->name));
-    }
-    return Py_BuildValue("{s:s,s:s,s:s,s:s,s:s"   /* format strings. s=string, i=int */
-                         ",s:s,s:s,s:s,s:s,s:s"   /* (format is key:value)  O=object */
-                         ",s:i,s:i,s:s,s:s,s:s"   /* blocks of 5 for readability     */
-                         "s:O}", 
-
-                         "nick", user->nick,
-                         "ident", user->ident,
-                         "info", user->info,
-                         "hostname", user->hostname,
-                         "ip", irc_ntoa(&user->ip),
-
-                         "fakehost", user->fakehost,
-                         "sethost", user->sethost,
-                         "crypthost", user->crypthost,
-                         "cryptip", user->cryptip,
-                         "numeric", user->numeric, /* TODO: only ifdef WITH_PROTOCOL_P10 */
-
-                         "loc", user->loc,
-                         "no_notice", user->no_notice,
-                         "mark", user->mark,
-                         "version_reply", user->version_reply,
-                         "account", user->handle_info?user->handle_info->handle:NULL,
-                         "channels", pChanList);
+
+    return pyobj_from_usernode(user);
 }
 
 static PyObject*
@@ -707,6 +734,10 @@ int python_load() {
     pName = PyString_FromString(modpython_conf.main_module);
     base_module = PyImport_Import(pName);
     Py_DECREF(pName);
+
+    Py_XDECREF(handler_object);
+    handler_object = NULL;
+
     if(base_module != NULL) {
         handler_object = python_new_handler_object();
         if(handler_object) {
@@ -751,7 +782,6 @@ python_cleanup(void) {
     if (PyErr_Occurred())
         PyErr_Clear();
     Py_Finalize(); /* Shut down python enterpriter */
-    return;
 }
 
 /* ---------------------------------------------------------------------------------- *