diff options
Diffstat (limited to 'src/objects/channel-object.c')
| -rw-r--r-- | src/objects/channel-object.c | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/src/objects/channel-object.c b/src/objects/channel-object.c new file mode 100644 index 0000000..fa4edd4 --- /dev/null +++ b/src/objects/channel-object.c @@ -0,0 +1,379 @@ +#include <Python.h> +#include "pyirssi.h" +#include "pymodule.h" +#include "factory.h" +#include "channel-object.h" +#include "pycore.h" + +/* monitor "channel destroyed" signal */ +static void chan_cleanup(CHANNEL_REC *chan) +{ + PyChannel *pychan = signal_get_user_data(); + + if (chan == pychan->data) + { + pychan->data = NULL; + pychan->cleanup_installed = 0; + signal_remove_data("channel destroyed", chan_cleanup, pychan); + } +} + +static void PyChannel_dealloc(PyChannel *self) +{ + if (self->cleanup_installed) + signal_remove_data("channel destroyed", chan_cleanup, self); + + self->ob_type->tp_free((PyObject*)self); +} + +/* Getters */ +PyDoc_STRVAR(PyChannel_topic_doc, + "Channel topic" +); +static PyObject *PyChannel_topic_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->topic); +} + +PyDoc_STRVAR(PyChannel_topic_by_doc, + "Nick who set the topic" +); +static PyObject *PyChannel_topic_by_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->topic_by); +} + +PyDoc_STRVAR(PyChannel_topic_time_doc, + "Timestamp when the topic was set" +); +static PyObject *PyChannel_topic_time_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromLong(self->data->topic_time); +} + +PyDoc_STRVAR(PyChannel_no_modes_doc, + "Channel is modeless" +); +static PyObject *PyChannel_no_modes_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->no_modes); +} + +PyDoc_STRVAR(PyChannel_mode_doc, + "Channel mode" +); +static PyObject *PyChannel_mode_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->mode); +} + +PyDoc_STRVAR(PyChannel_limit_doc, + "Max. users in channel (+l mode)" +); +static PyObject *PyChannel_limit_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyInt_FromLong(self->data->limit); +} + +PyDoc_STRVAR(PyChannel_key_doc, + "Channel key (password)" +); +static PyObject *PyChannel_key_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->key); +} + +PyDoc_STRVAR(PyChannel_chanop_doc, + "You are channel operator" +); +static PyObject *PyChannel_chanop_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->chanop); +} + +PyDoc_STRVAR(PyChannel_names_got_doc, + "/NAMES list has been received" +); +static PyObject *PyChannel_names_got_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->names_got); +} + +PyDoc_STRVAR(PyChannel_wholist_doc, + "/WHO list has been received" +); +static PyObject *PyChannel_wholist_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->wholist); +} + +PyDoc_STRVAR(PyChannel_synced_doc, + "Channel is fully synchronized" +); +static PyObject *PyChannel_synced_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->synced); +} + +PyDoc_STRVAR(PyChannel_joined_doc, + "JOIN event for this channel has been received" +); +static PyObject *PyChannel_joined_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->joined); +} + +PyDoc_STRVAR(PyChannel_left_doc, + "You just left the channel (for 'channel destroyed' event)" +); +static PyObject *PyChannel_left_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->left); +} + +PyDoc_STRVAR(PyChannel_kicked_doc, + "You were just kicked out of the channel (for 'channel destroyed' event)" +); +static PyObject *PyChannel_kicked_get(PyChannel *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->kicked); +} + +/* specialized getters/setters */ +static PyGetSetDef PyChannel_getseters[] = { + {"topic", (getter)PyChannel_topic_get, NULL, + PyChannel_topic_doc, NULL}, + {"topic_by", (getter)PyChannel_topic_by_get, NULL, + PyChannel_topic_by_doc, NULL}, + {"topic_time", (getter)PyChannel_topic_time_get, NULL, + PyChannel_topic_time_doc, NULL}, + {"no_modes", (getter)PyChannel_no_modes_get, NULL, + PyChannel_no_modes_doc, NULL}, + {"mode", (getter)PyChannel_mode_get, NULL, + PyChannel_mode_doc, NULL}, + {"limit", (getter)PyChannel_limit_get, NULL, + PyChannel_limit_doc, NULL}, + {"key", (getter)PyChannel_key_get, NULL, + PyChannel_key_doc, NULL}, + {"chanop", (getter)PyChannel_chanop_get, NULL, + PyChannel_chanop_doc, NULL}, + {"names_got", (getter)PyChannel_names_got_get, NULL, + PyChannel_names_got_doc, NULL}, + {"wholist", (getter)PyChannel_wholist_get, NULL, + PyChannel_wholist_doc, NULL}, + {"synced", (getter)PyChannel_synced_get, NULL, + PyChannel_synced_doc, NULL}, + {"joined", (getter)PyChannel_joined_get, NULL, + PyChannel_joined_doc, NULL}, + {"left", (getter)PyChannel_left_get, NULL, + PyChannel_left_doc, NULL}, + {"kicked", (getter)PyChannel_kicked_get, NULL, + PyChannel_kicked_doc, NULL}, + {NULL} +}; + +/* Methods */ +PyDoc_STRVAR(PyChannel_nicks_doc, + "nicks() -> list of Nick objects\n" + "\n" + "Return a list of nicks in the channel.\n" +); +static PyObject *PyChannel_nicks(PyChannel *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + + return py_irssi_chatlist_new(nicklist_getnicks(self->data), 1); +} + +PyDoc_STRVAR(PyChannel_nicks_find_mask_doc, + "nicks_find_mask(mask) -> Nick object or None\n" + "\n" + "Find nick mask from nicklist, wildcards allowed.\n" +); +static PyObject *PyChannel_nicks_find_mask(PyChannel *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"mask", NULL}; + char *mask = ""; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &mask)) + return NULL; + + return py_irssi_chat_new(nicklist_find_mask(self->data, mask), 1); +} + +PyDoc_STRVAR(PyChannel_nick_find_doc, + "nick_find(nick) -> Nick object or None\n" + "\n" + "Find nick from nicklist.\n" +); +static PyObject *PyChannel_nick_find(PyChannel *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"nick", NULL}; + char *nick = ""; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &nick)) + return NULL; + + return py_irssi_chat_new(nicklist_find(self->data, nick), 1); +} + +PyDoc_STRVAR(PyChannel_nick_remove_doc, + "nick_remove(nick) -> None\n" + "\n" + "Remove nick from nicklist.\n" +); +static PyObject *PyChannel_nick_remove(PyChannel *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"nick", NULL}; + PyObject *nick = NULL; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, + &nick)) + return NULL; + + if (!pynick_check(nick)) + return PyErr_Format(PyExc_TypeError, "arg must be nick"); + + nicklist_remove(self->data, ((PyNick*)nick)->data); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyChannel_nick_insert_obj_doc, + "nick_insert(nick) -> None\n" + "\n" + "Insert nick object into nicklist.\n" +); +static PyObject *PyChannel_nick_insert_obj(PyChannel *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"nick", NULL}; + PyObject *nick = NULL; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, + &nick)) + return NULL; + + if (!pynick_check(nick)) + return PyErr_Format(PyExc_TypeError, "arg must be nick"); + + nicklist_insert(self->data, ((PyNick*)nick)->data); + + Py_RETURN_NONE; +} + +/* Methods for object */ +static PyMethodDef PyChannel_methods[] = { + {"nicks", (PyCFunction)PyChannel_nicks, METH_NOARGS, + PyChannel_nicks_doc}, + {"nicks_find_mask", (PyCFunction)PyChannel_nicks_find_mask, METH_VARARGS | METH_KEYWORDS, + PyChannel_nicks_find_mask_doc}, + {"nick_find", (PyCFunction)PyChannel_nick_find, METH_VARARGS | METH_KEYWORDS, + PyChannel_nick_find_doc}, + {"nick_remove", (PyCFunction)PyChannel_nick_remove, METH_VARARGS | METH_KEYWORDS, + PyChannel_nick_remove_doc}, + {"nick_insert_obj", (PyCFunction)PyChannel_nick_insert_obj, METH_VARARGS | METH_KEYWORDS, + PyChannel_nick_insert_obj_doc}, + {NULL} /* Sentinel */ +}; + +PyTypeObject PyChannelType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Channel", /*tp_name*/ + sizeof(PyChannel), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyChannel_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "PyChannel objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyChannel_methods, /* tp_methods */ + 0, /* tp_members */ + PyChannel_getseters, /* tp_getset */ + &PyWindowItemType, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + + +/* window item wrapper factory function */ +PyObject *pychannel_sub_new(void *chan, const char *name, PyTypeObject *type) +{ + PyObject *pychan; + + pychan = pywindow_item_sub_new(chan, name, type); + if (pychan) + { + PyChannel *pych = (PyChannel *)pychan; + signal_add_last_data("channel destroyed", chan_cleanup, pych); + pych->cleanup_installed = 1; + } + + return pychan; +} + +PyObject *pychannel_new(void *chan) +{ + static const char *name = "CHANNEL"; + return pychannel_sub_new(chan, name, &PyChannelType); +} + +int channel_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyChannelType) < 0) + return 0; + + Py_INCREF(&PyChannelType); + PyModule_AddObject(py_module, "Channel", (PyObject *)&PyChannelType); + + return 1; +} |
