* - modpython.py calls for everything you can reg_ a handler for in x3
* - Some kind of system for getting needed binds bound automagicaly to make it easier
* to run peoples' scripts and mod-python in general.
+ * - Create a (python side) command registry that plugins register into
+ * - In modcmd.c check that list first, before the usual (c based) command search
+ * - If python version returns 0, go on with the built-in search, otherwise just quit (allows plugins to override)
+ * - OR
+ * - Mechanism for python plugins to register themselves like x3 plugins? (*module.____) ??
+ * - Then, same problem as other x3 modules, pain to set up commands 1st time etc, maybe solve that for all modules?
* - An interface to reading/writing data to x3.db. Maybe generic, or attached to account or channel reg records?
+
+ * basic startup for now:
+ * configure --enable-modules=python
+ * Make install will copy modpython.py and plugins/ directory to start out with hangman example/test
+ *
+ * x3.conf: in the "moduleS" section add:
+ * "python" {
+ * "scripts_dir" "/home/you/x3rundirectory";
+ * "main_module" "modpython";
+ * };
+
+ * /msg o3 bind o3 py\ run *python.run
+ * /msg o3 bind o3 py\ reload *python.reload
+ * /msg o3 bind o3 py\ command *python.command
+
+ * example script bindings (for now)
+ * /msg o3 bind x3 hangman *modcmd.joiner
+ * /msg o3 bind x3 hangman\ start *python.command hangman start
+ * /msg o3 bind x3 hangman\ end *python.command hangman end
+ * /msg o3 bind x3 hangman\ guess *python.command hangman guess $1
*/
static const struct message_entry msgtab[] = {
return pyobj_from_service(service_register(user));
}
+size_t logs_size = 0;
+static struct log_type **logs_list = NULL;
+
+PyDoc_STRVAR(emb_log_register_type__doc__,
+ "registers a log source to write event data to.");
+static PyObject* emb_log_register_type(UNUSED_ARG(PyObject *self), PyObject* args) {
+ const char* logName;
+ const char* defaultLog;
+ struct log_type* log;
+ struct log_type** newlogs;
+
+ if (!PyArg_ParseTuple(args, "ss", &logName, &defaultLog))
+ return NULL;
+
+ newlogs = realloc(logs_list, (logs_size+1)*sizeof(struct log_type*));
+ if (newlogs == NULL) {
+ PyErr_SetString(PyExc_Exception, "unable to allocate memory for log structures. aborting.");
+ return NULL;
+ }
+ logs_list = newlogs;
+
+ log = log_register_type(logName, defaultLog);
+ if (log == NULL) {
+ PyErr_SetString(PyExc_Exception, "unable to register log");
+ return NULL;
+ }
+
+ logs_list[logs_size++] = log;
+
+ return Py_BuildValue("O", PyCObject_FromVoidPtr(log, NULL));
+}
+
+PyDoc_STRVAR(emb_module_register__doc__, "registers a module");
+PyObject* emb_module_register(UNUSED_ARG(PyObject* self), PyObject* args) {
+ PyObject* pylog;
+ char const *name, *helpfile;
+ struct log_type* log;
+ struct module* mod;
+
+ if (!PyArg_ParseTuple(args, "sOs", &name, &pylog, &helpfile))
+ return NULL;
+
+ log = PyCObject_AsVoidPtr(pylog);
+
+ mod = module_register(name, log, helpfile, NULL);
+
+ if (mod == NULL) {
+ PyErr_SetString(PyExc_Exception, "unable to register module");
+ return NULL;
+ }
+
+ return Py_BuildValue("O", PyCObject_FromVoidPtr(mod, NULL));
+}
+
static PyMethodDef EmbMethods[] = {
/* Communication methods */
{"dump", emb_dump, METH_VARARGS, emb_dump__doc__},
{"timeq_add", emb_timeq_add, METH_VARARGS, emb_timeq_add__doc__},
{"timeq_del", emb_timeq_del, METH_VARARGS, emb_timeq_del__doc__},
+ /* module registration methods */
+ {"log_register_type", emb_log_register_type, METH_VARARGS,
+ emb_log_register_type__doc__},
+ {"module_register", emb_module_register, METH_VARARGS,
+ emb_module_register__doc__},
+
/* Information gathering methods */
{"get_user", emb_get_user, METH_VARARGS, emb_get_user__doc__},
{"get_users", emb_get_users, METH_VARARGS, emb_get_users__doc__},
it first? We will start by doing it every time.
*/
static int
-python_handle_join(struct modeNode *mNode)
+python_handle_join(struct modeNode *mNode, UNUSED_ARG(void *extra))
{
/* callback for handle_join events.
*/
}
static void
-python_handle_nick_change(struct userNode *user, const char *old_nick)
+python_handle_nick_change(struct userNode *user, const char *old_nick, UNUSED_ARG(void *extra))
{
PyObject* usr = NULL;
PyObject* name = NULL;
log_module(PY_LOG, LOG_WARNING, "%s", err);
}
-int python_handle_topic(struct userNode *who, struct chanNode *chan, const char *old_topic) {
+int python_handle_topic(struct userNode *who, struct chanNode *chan, const char *old_topic, UNUSED_ARG(void *extra)) {
PyObject* pwho = NULL, *pchan = NULL, *oldtopic = NULL;
PyObject* name = NULL, *retval = NULL;
const char* err = NULL;
free(env);
}
+ log_module(PY_LOG, LOG_DEBUG, "Starting Python Init from python_load");
Py_Initialize();
Py_InitModule("_svc", EmbMethods);
pName = PyString_FromString(modpython_conf.main_module);
else {
/* error handler class not found */
log_module(PY_LOG, LOG_WARNING, "Failed to create handler object");
+ exit(1);
return 0;
}
}
//PyErr_Print();
python_log_module();
log_module(PY_LOG, LOG_WARNING, "Failed to load modpython.py");
+ exit(1);
return 0;
}
return 0;
}
static void
-python_cleanup(void) {
+python_cleanup(UNUSED_ARG(void *extra)) {
/* Called on shutdown of the python module (or before reloading)
*/
/* reload the python system completely
*/
log_module(PY_LOG, LOG_INFO, "Shutting python down");
- python_cleanup();
+ python_cleanup(NULL);
log_module(PY_LOG, LOG_INFO, "Loading python stuff");
if(python_load()) {
reply("PYMSG_RELOAD_SUCCESS");
else {
msg = "";
}
- char *args[] = {plugin, command, msg};
+ char *args[] = {strdup(plugin), strdup(command), strdup(msg)};
python_call_handler("cmd_command", args, numstrargs(args), cmd->parent->bot->nick, user?user->nick:"", channel?channel->name:"");
+ free(args[0]);
+ free(args[1]);
+ free(args[2]);
return 1;
}
}
str = database_get_data(conf_node, "scripts_dir", RECDB_QSTRING);
- modpython_conf.scripts_dir = str ? str : "./";
+ modpython_conf.scripts_dir = strdup(str ? str : "./");
str = database_get_data(conf_node, "main_module", RECDB_QSTRING);
- modpython_conf.main_module = str ? str : "modpython";
+ modpython_conf.main_module = strdup(str ? str : "modpython");
}
int python_init(void) {
*/
modcmd_register(python_module, "reload", cmd_reload, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
modcmd_register(python_module, "run", cmd_run, 2, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
- modcmd_register(python_module, "command", cmd_command, 3, MODCMD_REQUIRE_STAFF, NULL);
+ modcmd_register(python_module, "command", cmd_command, 3, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
// Please help us by implementing any of the callbacks listed as TODO below. They already exist
// in x3, they just need handle_ bridges implemented. (see python_handle_join for an example)
reg_server_link_func(python_handle_server_link, NULL);
reg_new_user_func(python_handle_new_user, NULL);
- reg_nick_change_func(python_handle_nick_change);
+ reg_nick_change_func(python_handle_nick_change, NULL);
reg_del_user_func(python_handle_del_user, NULL);
//TODO: reg_account_func(python_handle_account); /* stamping of account name to the ircd */
//TODO: reg_handle_rename_func(python_handle_handle_rename); /* handle used to ALSO mean account name */
//
//TODO: reg_oper_func(python_handle_oper);
//TODO: reg_new_channel_func(python_handle_new_channel);
- reg_join_func(python_handle_join);
+ reg_join_func(python_handle_join, NULL);
//TODO: reg_del_channel_func(python_handle_del_channel);
//TODO: reg_part_func(python_handle_part);
//TODO: reg_kick_func(python_handle_kick);
- reg_topic_func(python_handle_topic);
+ reg_topic_func(python_handle_topic, NULL);
//TODO: reg_channel_mode_func(python_handle_channel_mode);
//TODO: reg_privmsg_func(python_handle_privmsg);
//TODO: reg_allchanmsg_func
//TODO: reg_user_mode_func
- reg_exit_func(python_cleanup);
+ reg_exit_func(python_cleanup, NULL);
python_load();
return 1;