diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | objects/Makefile | 7 | ||||
-rw-r--r-- | objects/dcc-chat-object.c | 135 | ||||
-rw-r--r-- | objects/dcc-chat-object.h | 21 | ||||
-rw-r--r-- | objects/dcc-get-object.c | 138 | ||||
-rw-r--r-- | objects/dcc-get-object.h | 18 | ||||
-rw-r--r-- | objects/dcc-object.c | 112 | ||||
-rw-r--r-- | objects/dcc-send-object.c | 138 | ||||
-rw-r--r-- | objects/dcc-send-object.h | 18 | ||||
-rw-r--r-- | objects/factory.c | 31 | ||||
-rw-r--r-- | objects/factory.h | 8 | ||||
-rw-r--r-- | objects/irc-server-object.c | 143 | ||||
-rw-r--r-- | objects/netsplit-channel-object.c | 170 | ||||
-rw-r--r-- | objects/netsplit-channel-object.h | 21 | ||||
-rw-r--r-- | objects/netsplit-object.c | 182 | ||||
-rw-r--r-- | objects/netsplit-object.h | 19 | ||||
-rw-r--r-- | objects/netsplit-server-object.c | 157 | ||||
-rw-r--r-- | objects/netsplit-server-object.h | 18 | ||||
-rw-r--r-- | objects/notifylist-object.c | 217 | ||||
-rw-r--r-- | objects/notifylist-object.h | 18 | ||||
-rw-r--r-- | objects/process-object.c | 222 | ||||
-rw-r--r-- | objects/process-object.h | 22 | ||||
-rw-r--r-- | objects/server-object.c | 2 | ||||
-rw-r--r-- | objects/window-item-object.c | 11 | ||||
-rw-r--r-- | pyirssi.h | 1 | ||||
-rw-r--r-- | pyirssi_irc.h | 2 | ||||
-rw-r--r-- | pymodule.c | 102 |
27 files changed, 1838 insertions, 98 deletions
@@ -6,7 +6,8 @@ IRSSI = /usr/local/include/irssi CFLAGS = -fpic -ggdb -Wall -I$(PYTHON) -I$(IRSSI) -I$(IRSSI)/src \ -I$(IRSSI)/src/fe-common/core -I$(IRSSI)/src/core -I$(IRSSI)/src/fe-text \ -I$(IRSSI)/src/irc -I$(IRSSI)/src/irc/core -I$(IRSSI)/src/irc/dcc \ --I. -Iobjects `pkg-config glib-2.0 --cflags` +-I$(IRSSI)/src/irc/notifylist -I.. -I. -Iobjects \ +`pkg-config glib-2.0 --cflags` LDFLAGS = -fpic /usr/lib/libpython2.4.so diff --git a/objects/Makefile b/objects/Makefile index b48d47e..ae14e94 100644 --- a/objects/Makefile +++ b/objects/Makefile @@ -4,7 +4,8 @@ PYTHON = /usr/include/python2.4 IRSSI = /usr/local/include/irssi CFLAGS = -fpic -ggdb -Wall -I$(PYTHON) -I$(IRSSI) -I$(IRSSI)/src \ -I$(IRSSI)/src/fe-common/core -I$(IRSSI)/src/core -I$(IRSSI)/src/fe-text \ --I$(IRSSI)/src/irc -I$(IRSSI)/src/irc/core -I$(IRSSI)/src/irc/dcc -I.. \ +-I$(IRSSI)/src/irc -I$(IRSSI)/src/irc/core -I$(IRSSI)/src/irc/dcc \ +-I$(IRSSI)/src/irc/notifylist -I.. \ `pkg-config glib-2.0 --cflags` OBJ = pyscript-object.o base-objects.o window-item-object.o channel-object.o \ @@ -12,7 +13,9 @@ query-object.o server-object.o connect-object.o irc-server-object.o \ irc-connect-object.o irc-channel-object.o ban-object.o nick-object.o \ chatnet-object.o reconnect-object.o window-object.o textdest-object.o \ rawlog-object.o log-object.o logitem-object.o ignore-object.o \ -dcc-object.o factory.o +dcc-object.o dcc-chat-object.o dcc-get-object.o dcc-send-object.o \ +netsplit-object.o netsplit-server-object.o netsplit-channel-object.o \ +notifylist-object.o process-object.o factory.o pyobjects.a: $(OBJ) ar r pyobjects.a $(OBJ) diff --git a/objects/dcc-chat-object.c b/objects/dcc-chat-object.c new file mode 100644 index 0000000..c7e25f9 --- /dev/null +++ b/objects/dcc-chat-object.c @@ -0,0 +1,135 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "dcc-chat-object.h" +#include "factory.h" +#include "pycore.h" + +/* inherit destroy and cleanup from DccChat type */ + +/* Getters */ +PyDoc_STRVAR(PyDccChat_id_doc, + "Unique identifier - usually same as nick" +); +static PyObject *PyDccChat_id_get(PyDccChat *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->id); +} + +PyDoc_STRVAR(PyDccChat_mirc_ctcp_doc, + "Send CTCPs without the CTCP_MESSAGE prefix" +); +static PyObject *PyDccChat_mirc_ctcp_get(PyDccChat *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->mirc_ctcp); +} + +PyDoc_STRVAR(PyDccChat_connection_lost_doc, + "Other side closed connection" +); +static PyObject *PyDccChat_connection_lost_get(PyDccChat *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->connection_lost); +} + +/* specialized getters/setters */ +static PyGetSetDef PyDccChat_getseters[] = { + {"id", (getter)PyDccChat_id_get, NULL, + PyDccChat_id_doc, NULL}, + {"mirc_ctcp", (getter)PyDccChat_mirc_ctcp_get, NULL, + PyDccChat_mirc_ctcp_doc, NULL}, + {"connection_lost", (getter)PyDccChat_connection_lost_get, NULL, + PyDccChat_connection_lost_doc, NULL}, + {NULL} +}; + +/* Methods */ +PyDoc_STRVAR(PyDccChat_chat_send_doc, + "Send data to a dcc chat session." +); +static PyObject *PyDccChat_chat_send(PyDccChat *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"data", NULL}; + char *data = ""; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &data)) + return NULL; + + dcc_chat_send(self->data, data); + + Py_RETURN_NONE; +} + +/* Methods for object */ +static PyMethodDef PyDccChat_methods[] = { + {"chat_send", (PyCFunction)PyDccChat_chat_send, METH_VARARGS | METH_KEYWORDS, + PyDccChat_chat_send_doc}, + {NULL} /* Sentinel */ +}; + +PyTypeObject PyDccChatType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "DccChat", /*tp_name*/ + sizeof(PyDccChat), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*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*/ + "PyDccChat objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyDccChat_methods, /* tp_methods */ + 0, /* tp_members */ + PyDccChat_getseters, /* tp_getset */ + &PyDccType, /* 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 */ +}; + +PyObject *pydcc_chat_new(void *dcc) +{ + static const char *name = "DCC CHAT"; + return pydcc_sub_new(dcc, name, &PyDccChatType); +} + +int dcc_chat_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyDccChatType) < 0) + return 0; + + Py_INCREF(&PyDccChatType); + PyModule_AddObject(py_module, "DccChat", (PyObject *)&PyDccChatType); + + return 1; +} diff --git a/objects/dcc-chat-object.h b/objects/dcc-chat-object.h new file mode 100644 index 0000000..955e6be --- /dev/null +++ b/objects/dcc-chat-object.h @@ -0,0 +1,21 @@ +#ifndef _DCC_CHAT_OBJECT_H_ +#define _DCC_CHAT_OBJECT_H_ + +#include <Python.h> +#include "dcc-object.h" + +/* forward */ +struct CHAT_DCC_REC; + +typedef struct +{ + PyDcc_HEAD(struct CHAT_DCC_REC) +} PyDccChat; + +extern PyTypeObject PyDccChatType; + +PyObject *pydcc_chat_new(void *dcc); +#define pydcc_chat_check(op) PyObject_TypeCheck(op, &PyDccChatType) +int dcc_chat_object_init(void); + +#endif diff --git a/objects/dcc-get-object.c b/objects/dcc-get-object.c new file mode 100644 index 0000000..fa7c13a --- /dev/null +++ b/objects/dcc-get-object.c @@ -0,0 +1,138 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "dcc-get-object.h" +#include "factory.h" +#include "pycore.h" + +#define DCC_GET_CAST(rec) ((GET_DCC_REC *)rec) + +/* inherit destroy and cleanup from Dcc type */ + +/* Getters */ +PyDoc_STRVAR(PyDccGet_size_doc, + "File size" +); +static PyObject *PyDccGet_size_get(PyDccGet *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(DCC_GET_CAST(self->data)->size); +} + +PyDoc_STRVAR(PyDccGet_skipped_doc, + "Bytes skipped from start (resuming file)" +); +static PyObject *PyDccGet_skipped_get(PyDccGet *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(DCC_GET_CAST(self->data)->skipped); +} + +PyDoc_STRVAR(PyDccGet_get_type_doc, + "What to do if file exists? 0=default, 1=rename, 2=overwrite, 3=resume" +); +static PyObject *PyDccGet_get_type_get(PyDccGet *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyInt_FromLong(DCC_GET_CAST(self->data)->get_type); +} + +PyDoc_STRVAR(PyDccGet_file_doc, + "The real file name which we use." +); +static PyObject *PyDccGet_file_get(PyDccGet *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(DCC_GET_CAST(self->data)->file); +} + +PyDoc_STRVAR(PyDccGet_file_quoted_doc, + "true if file name was received quoted (\"file name\")" +); +static PyObject *PyDccGet_file_quoted_get(PyDccGet *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(DCC_GET_CAST(self->data)->file_quoted); +} + +/* specialized getters/setters */ +static PyGetSetDef PyDccGet_getseters[] = { + {"size", (getter)PyDccGet_size_get, NULL, + PyDccGet_size_doc, NULL}, + {"skipped", (getter)PyDccGet_skipped_get, NULL, + PyDccGet_skipped_doc, NULL}, + {"get_type", (getter)PyDccGet_get_type_get, NULL, + PyDccGet_get_type_doc, NULL}, + {"file", (getter)PyDccGet_file_get, NULL, + PyDccGet_file_doc, NULL}, + {"file_quoted", (getter)PyDccGet_file_quoted_get, NULL, + PyDccGet_file_quoted_doc, NULL}, + {NULL} +}; + +/* Methods */ +/* Methods for object */ +static PyMethodDef PyDccGet_methods[] = { + {NULL} /* Sentinel */ +}; + +PyTypeObject PyDccGetType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "DccGet", /*tp_name*/ + sizeof(PyDccGet), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*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*/ + "PyDccGet objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyDccGet_methods, /* tp_methods */ + 0, /* tp_members */ + PyDccGet_getseters, /* tp_getset */ + &PyDccType, /* 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 */ +}; + +PyObject *pydcc_get_new(void *dcc) +{ + static const char *name = "DCC GET"; + return pydcc_sub_new(dcc, name, &PyDccGetType); +} + +int dcc_get_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyDccGetType) < 0) + return 0; + + Py_INCREF(&PyDccGetType); + PyModule_AddObject(py_module, "DccGet", (PyObject *)&PyDccGetType); + + return 1; +} diff --git a/objects/dcc-get-object.h b/objects/dcc-get-object.h new file mode 100644 index 0000000..532b854 --- /dev/null +++ b/objects/dcc-get-object.h @@ -0,0 +1,18 @@ +#ifndef _DCC_GET_OBJECT_H_ +#define _DCC_GET_OBJECT_H_ + +#include <Python.h> +#include "dcc-object.h" + +typedef struct +{ + PyDcc_HEAD(void) +} PyDccGet; + +extern PyTypeObject PyDccGetType; + +PyObject *pydcc_get_new(void *dcc); +#define pydcc_get_check(op) PyObject_TypeCheck(op, &PyDccGetType) +int dcc_get_object_init(void); + +#endif diff --git a/objects/dcc-object.c b/objects/dcc-object.c index 772c011..62b5915 100644 --- a/objects/dcc-object.c +++ b/objects/dcc-object.c @@ -5,6 +5,7 @@ #include "factory.h" #include "pycore.h" + /* monitor "dcc destroyed signal" */ static void dcc_cleanup(DCC_REC *dcc) { @@ -35,12 +36,11 @@ PyDoc_STRVAR(PyDcc_orig_type_doc, ); static PyObject *PyDcc_orig_type_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; const char *type; - RET_NULL_IF_INVALID(data); + RET_NULL_IF_INVALID(self->data); - type = module_find_id_str("DCC", data->orig_type); + type = module_find_id_str("DCC", DCC(self->data)->orig_type); RET_AS_STRING_OR_NONE(type); } @@ -49,10 +49,8 @@ PyDoc_STRVAR(PyDcc_created_doc, ); static PyObject *PyDcc_created_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - return PyLong_FromUnsignedLong(data->created); + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(DCC(self->data)->created); } PyDoc_STRVAR(PyDcc_server_doc, @@ -60,9 +58,7 @@ PyDoc_STRVAR(PyDcc_server_doc, ); static PyObject *PyDcc_server_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); + RET_NULL_IF_INVALID(self->data); RET_AS_OBJ_OR_NONE(self->server); } @@ -71,10 +67,8 @@ PyDoc_STRVAR(PyDcc_servertag_doc, ); static PyObject *PyDcc_servertag_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - RET_AS_STRING_OR_NONE(data->servertag); + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(DCC(self->data)->servertag); } PyDoc_STRVAR(PyDcc_mynick_doc, @@ -82,10 +76,8 @@ PyDoc_STRVAR(PyDcc_mynick_doc, ); static PyObject *PyDcc_mynick_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - RET_AS_STRING_OR_NONE(data->mynick); + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(DCC(self->data)->mynick); } PyDoc_STRVAR(PyDcc_nick_doc, @@ -93,10 +85,8 @@ PyDoc_STRVAR(PyDcc_nick_doc, ); static PyObject *PyDcc_nick_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - RET_AS_STRING_OR_NONE(data->nick); + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(DCC(self->data)->nick); } PyDoc_STRVAR(PyDcc_chat_doc, @@ -104,9 +94,7 @@ PyDoc_STRVAR(PyDcc_chat_doc, ); static PyObject *PyDcc_chat_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); + RET_NULL_IF_INVALID(self->data); RET_AS_OBJ_OR_NONE(self->chat); } @@ -115,10 +103,8 @@ PyDoc_STRVAR(PyDcc_target_doc, ); static PyObject *PyDcc_target_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - RET_AS_STRING_OR_NONE(data->target); + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(DCC(self->data)->target); } PyDoc_STRVAR(PyDcc_arg_doc, @@ -126,10 +112,8 @@ PyDoc_STRVAR(PyDcc_arg_doc, ); static PyObject *PyDcc_arg_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - RET_AS_STRING_OR_NONE(data->arg); + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(DCC(self->data)->arg); } PyDoc_STRVAR(PyDcc_addr_doc, @@ -137,10 +121,8 @@ PyDoc_STRVAR(PyDcc_addr_doc, ); static PyObject *PyDcc_addr_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - RET_AS_STRING_OR_NONE(data->addrstr); + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(DCC(self->data)->addrstr); } PyDoc_STRVAR(PyDcc_port_doc, @@ -148,10 +130,8 @@ PyDoc_STRVAR(PyDcc_port_doc, ); static PyObject *PyDcc_port_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - return PyInt_FromLong(data->port); + RET_NULL_IF_INVALID(self->data); + return PyInt_FromLong(DCC(self->data)->port); } PyDoc_STRVAR(PyDcc_starttime_doc, @@ -159,10 +139,8 @@ PyDoc_STRVAR(PyDcc_starttime_doc, ); static PyObject *PyDcc_starttime_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - return PyLong_FromUnsignedLong(data->starttime); + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(DCC(self->data)->starttime); } PyDoc_STRVAR(PyDcc_transfd_doc, @@ -170,10 +148,8 @@ PyDoc_STRVAR(PyDcc_transfd_doc, ); static PyObject *PyDcc_transfd_get(PyDcc *self, void *closure) { - DCC_REC *data = self->data; - - RET_NULL_IF_INVALID(data); - return PyLong_FromUnsignedLong(data->transfd); + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(DCC(self->data)->transfd); } /* specialized getters/setters */ @@ -220,10 +196,48 @@ static PyObject *PyDcc_destroy(PyDcc *self, PyObject *args) Py_RETURN_NONE; } +PyDoc_STRVAR(PyDcc_reject_doc, + "?" +); +static PyObject *PyDcc_reject(PyDcc *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"server", NULL}; + PyObject *server = NULL; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, + &server)) + return NULL; + + if (!pyirc_server_check(server)) + return PyErr_Format(PyExc_TypeError, "arg must be IRC server object"); + + dcc_reject(self->data, ((PyIrcServer*)server)->data); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyDcc_close_doc, + "Close and destroy DCC connection" +); +static PyObject *PyDcc_close(PyDcc *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + + dcc_close(self->data); + + Py_RETURN_NONE; +} + /* Methods for object */ static PyMethodDef PyDcc_methods[] = { {"destroy", (PyCFunction)PyDcc_destroy, METH_NOARGS, PyDcc_destroy_doc}, + {"reject", (PyCFunction)PyDcc_reject, METH_VARARGS | METH_KEYWORDS, + PyDcc_reject_doc}, + {"close", (PyCFunction)PyDcc_close, METH_NOARGS, + PyDcc_close_doc}, {NULL} /* Sentinel */ }; diff --git a/objects/dcc-send-object.c b/objects/dcc-send-object.c new file mode 100644 index 0000000..643f741 --- /dev/null +++ b/objects/dcc-send-object.c @@ -0,0 +1,138 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "dcc-send-object.h" +#include "factory.h" +#include "pycore.h" + +#define DCC_SEND_CAST(rec) ((SEND_DCC_REC *)rec) + +/* inherit destroy and cleanup from Dcc type */ + +/* Getters */ +PyDoc_STRVAR(PyDccSend_size_doc, + "File size" +); +static PyObject *PyDccSend_size_get(PyDccSend *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(DCC_SEND_CAST(self->data)->size); +} + +PyDoc_STRVAR(PyDccSend_skipped_doc, + "Bytes skipped from start (resuming file)" +); +static PyObject *PyDccSend_skipped_get(PyDccSend *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(DCC_SEND_CAST(self->data)->skipped); +} + +PyDoc_STRVAR(PyDccSend_file_quoted_doc, + "True if file name was received quoted (\"file name\")" +); +static PyObject *PyDccSend_file_quoted_get(PyDccSend *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(DCC_SEND_CAST(self->data)->file_quoted); +} + +PyDoc_STRVAR(PyDccSend_waitforend_doc, + "File is sent, just wait for the replies from the other side" +); +static PyObject *PyDccSend_waitforend_get(PyDccSend *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(DCC_SEND_CAST(self->data)->waitforend); +} + +PyDoc_STRVAR(PyDccSend_gotalldata_doc, + "Got all acks from the other end" +); +static PyObject *PyDccSend_gotalldata_get(PyDccSend *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(DCC_SEND_CAST(self->data)->gotalldata); +} + +/* specialized getters/setters */ +static PyGetSetDef PyDccSend_getseters[] = { + {"size", (getter)PyDccSend_size_get, NULL, + PyDccSend_size_doc, NULL}, + {"skipped", (getter)PyDccSend_skipped_get, NULL, + PyDccSend_skipped_doc, NULL}, + {"file_quoted", (getter)PyDccSend_file_quoted_get, NULL, + PyDccSend_file_quoted_doc, NULL}, + {"waitforend", (getter)PyDccSend_waitforend_get, NULL, + PyDccSend_waitforend_doc, NULL}, + {"gotalldata", (getter)PyDccSend_gotalldata_get, NULL, + PyDccSend_gotalldata_doc, NULL}, + {NULL} +}; + +/* Methods */ +/* Methods for object */ +static PyMethodDef PyDccSend_methods[] = { + {NULL} /* Sentinel */ +}; + +PyTypeObject PyDccSendType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "DccSend", /*tp_name*/ + sizeof(PyDccSend), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*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*/ + "PyDccSend objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyDccSend_methods, /* tp_methods */ + 0, /* tp_members */ + PyDccSend_getseters, /* tp_getset */ + &PyDccType, /* 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 */ +}; + +PyObject *pydcc_send_new(void *dcc) +{ + static const char *name = "DCC SEND"; + return pydcc_sub_new(dcc, name, &PyDccSendType); +} + +int dcc_send_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyDccSendType) < 0) + return 0; + + Py_INCREF(&PyDccSendType); + PyModule_AddObject(py_module, "DccSend", (PyObject *)&PyDccSendType); + + return 1; +} diff --git a/objects/dcc-send-object.h b/objects/dcc-send-object.h new file mode 100644 index 0000000..6303f86 --- /dev/null +++ b/objects/dcc-send-object.h @@ -0,0 +1,18 @@ +#ifndef _DCC_SEND_OBJECT_H_ +#define _DCC_SEND_OBJECT_H_ + +#include <Python.h> +#include "dcc-object.h" + +typedef struct +{ + PyDcc_HEAD(void) +} PyDccSend; + +extern PyTypeObject PyDccSendType; + +PyObject *pydcc_send_new(void *dcc); +#define pydcc_send_check(op) PyObject_TypeCheck(op, &PyDccSendType) +int dcc_send_object_init(void); + +#endif diff --git a/objects/factory.c b/objects/factory.c index bf78688..3e08074 100644 --- a/objects/factory.c +++ b/objects/factory.c @@ -91,7 +91,31 @@ static int init_objects(void) if (!dcc_object_init()) return 0; + + if (!dcc_chat_object_init()) + return 0; + + if (!dcc_get_object_init()) + return 0; + + if (!dcc_send_object_init()) + return 0; + if (!netsplit_object_init()) + return 0; + + if (!netsplit_server_object_init()) + return 0; + + if (!netsplit_channel_object_init()) + return 0; + + if (!notifylist_object_init()) + return 0; + + if (!process_object_init()) + return 0; + return 1; } @@ -164,15 +188,14 @@ static void register_nonchat(void) int type; int chat_type = 0xffff; - //FIXME: specify init funcs type = module_get_uniq_id_str("DCC", "CHAT"); - insert_map(type, chat_type, (InitFunc)pydcc_new); + insert_map(type, chat_type, (InitFunc)pydcc_chat_new); type = module_get_uniq_id_str("DCC", "GET"); - insert_map(type, chat_type, (InitFunc)pydcc_new); + insert_map(type, chat_type, (InitFunc)pydcc_get_new); type = module_get_uniq_id_str("DCC", "SEND"); - insert_map(type, chat_type, (InitFunc)pydcc_new); + insert_map(type, chat_type, (InitFunc)pydcc_send_new); type = module_get_uniq_id_str("DCC", "SERVER"); insert_map(type, chat_type, (InitFunc)pydcc_new); diff --git a/objects/factory.h b/objects/factory.h index 1171003..c310951 100644 --- a/objects/factory.h +++ b/objects/factory.h @@ -23,6 +23,14 @@ #include "logitem-object.h" #include "ignore-object.h" #include "dcc-object.h" +#include "dcc-chat-object.h" +#include "dcc-get-object.h" +#include "dcc-send-object.h" +#include "netsplit-object.h" +#include "netsplit-server-object.h" +#include "netsplit-channel-object.h" +#include "notifylist-object.h" +#include "process-object.h" int factory_init(void); void factory_deinit(void); diff --git a/objects/irc-server-object.c b/objects/irc-server-object.c index 0e0ccdc..c162dfa 100644 --- a/objects/irc-server-object.c +++ b/objects/irc-server-object.c @@ -1,59 +1,53 @@ #include <Python.h> #include "pymodule.h" #include "base-objects.h" -#include "server-object.h" #include "irc-server-object.h" -#include "irc-connect-object.h" +#include "factory.h" #include "pyirssi_irc.h" #include "pycore.h" #include "pyutils.h" -/* member IDs */ -enum -{ - M_IRC_SERVER_REAL_ADDRESS, - M_IRC_SERVER_USERMODE, - M_IRC_SERVER_USERHOST, -}; - /* cleanup and dealloc inherited from base Server */ -static PyObject *PyIrcServer_get(PyIrcServer *self, void *closure) +/* Getters */ +PyDoc_STRVAR(PyIrcServer_real_address_doc, + "Address the IRC server gives" +); +static PyObject *PyIrcServer_real_address_get(PyIrcServer *self, void *closure) { - int member = GPOINTER_TO_INT(closure); + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->real_address); +} +PyDoc_STRVAR(PyIrcServer_usermode_doc, + "User mode in server" +); +static PyObject *PyIrcServer_usermode_get(PyIrcServer *self, void *closure) +{ RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->usermode); +} - switch (member) - { - case M_IRC_SERVER_REAL_ADDRESS: - RET_AS_STRING_OR_NONE(self->data->real_address); - case M_IRC_SERVER_USERMODE: - RET_AS_STRING_OR_NONE(self->data->usermode); - case M_IRC_SERVER_USERHOST: - RET_AS_STRING_OR_NONE(self->data->userhost); - } - - /* This shouldn't be reached... but... */ - return PyErr_Format(PyExc_RuntimeError, "invalid member id, %d", member); +PyDoc_STRVAR(PyIrcServer_userhost_doc, + "Your user host in server" +); +static PyObject *PyIrcServer_userhost_get(PyIrcServer *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->userhost); } static PyGetSetDef PyIrcServer_getseters[] = { - {"real_address", (getter)PyIrcServer_get, NULL, - "Address the IRC server gives", - GINT_TO_POINTER(M_IRC_SERVER_REAL_ADDRESS)}, - - {"usermode", (getter)PyIrcServer_get, NULL, - "User mode in server", - GINT_TO_POINTER(M_IRC_SERVER_USERMODE)}, - - {"userhost", (getter)PyIrcServer_get, NULL, - "Your user host in server", - GINT_TO_POINTER(M_IRC_SERVER_USERHOST)}, - + {"real_address", (getter)PyIrcServer_real_address_get, NULL, + PyIrcServer_real_address_doc, NULL}, + {"usermode", (getter)PyIrcServer_usermode_get, NULL, + PyIrcServer_usermode_doc, NULL}, + {"userhost", (getter)PyIrcServer_userhost_get, NULL, + PyIrcServer_userhost_doc, NULL}, {NULL} }; +/* Methods */ PyDoc_STRVAR(get_channels_doc, "Return a string of all channels (and keys, if any have them) in server,\n" "like '#a,#b,#c,#d x,b_chan_key,x,x' or just '#e,#f,#g'\n" @@ -181,26 +175,91 @@ static PyObject *PyIrcServer_isupport(PyIrcServer *self, PyObject *args, PyObjec RET_AS_STRING_OR_NONE(found); } +PyDoc_STRVAR(PyIrcServer_netsplit_find_doc, + "Check if nick!address is on the other side of netsplit. Netsplit records\n" + "are automatically removed after 30 minutes (current default)..\n" +); +static PyObject *PyIrcServer_netsplit_find(PyIrcServer *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"nick", "address", NULL}; + char *nick = ""; + char *address = ""; + NETSPLIT_REC *ns; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist, + &nick, &address)) + return NULL; + + ns = netsplit_find(self->data, nick, address); + if (ns) + return pynetsplit_new(ns); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyIrcServer_netsplit_find_channel_doc, + "Find nick record for nick!address in channel `channel'." +); +static PyObject *PyIrcServer_netsplit_find_channel(PyIrcServer *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"nick", "address", "channel", NULL}; + char *nick = ""; + char *address = ""; + char *channel = ""; + NETSPLIT_CHAN_REC *nsc; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "sss", kwlist, + &nick, &address, &channel)) + return NULL; + + nsc = netsplit_find_channel(self->data, nick, address, channel); + if (nsc) + return pynetsplit_channel_new(nsc); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyIrcServer_notifylist_ison_doc, + "Check if nick is on server" +); +static PyObject *PyIrcServer_notifylist_ison(PyIrcServer *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 PyBool_FromLong(notifylist_ison_server(self->data, nick)); +} + /* Methods for object */ static PyMethodDef PyIrcServer_methods[] = { {"get_channels", (PyCFunction)PyIrcServer_get_channels, METH_NOARGS, get_channels_doc}, - {"send_raw", (PyCFunction)PyIrcServer_send_raw, METH_VARARGS | METH_KEYWORDS, send_raw_doc}, - {"send_raw_now", (PyCFunction)PyIrcServer_send_raw_now, METH_VARARGS | METH_KEYWORDS, send_raw_now_doc}, - {"send_raw_split", (PyCFunction)PyIrcServer_send_raw_split, METH_VARARGS | METH_KEYWORDS, send_raw_split_doc}, - {"ctcp_send_reply", (PyCFunction)PyIrcServer_ctcp_send_reply, METH_VARARGS | METH_KEYWORDS, ctcp_send_reply_doc}, - {"isupport", (PyCFunction)PyIrcServer_isupport, METH_VARARGS | METH_KEYWORDS, isupport_doc}, - + {"netsplit_find", (PyCFunction)PyIrcServer_netsplit_find, METH_VARARGS | METH_KEYWORDS, + PyIrcServer_netsplit_find_doc}, + {"netsplit_find_channel", (PyCFunction)PyIrcServer_netsplit_find_channel, METH_VARARGS | METH_KEYWORDS, + PyIrcServer_netsplit_find_channel_doc}, + {"notifylist_ison", (PyCFunction)PyIrcServer_notifylist_ison, METH_VARARGS | METH_KEYWORDS, + PyIrcServer_notifylist_ison_doc}, {NULL} /* Sentinel */ }; diff --git a/objects/netsplit-channel-object.c b/objects/netsplit-channel-object.c new file mode 100644 index 0000000..3e2639b --- /dev/null +++ b/objects/netsplit-channel-object.c @@ -0,0 +1,170 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "netsplit-channel-object.h" +#include "factory.h" +#include "pycore.h" + +/* value copied -- no special cleanup */ + +static void PyNetsplitChannel_dealloc(PyNetsplitChannel *self) +{ + Py_XDECREF(self->name); + + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject *PyNetsplitChannel_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyNetsplitChannel *self; + + self = (PyNetsplitChannel *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + return (PyObject *)self; +} + +/* Getters */ +PyDoc_STRVAR(PyNetsplitChannel_name_doc, + "Channel name" +); +static PyObject *PyNetsplitChannel_name_get(PyNetsplitChannel *self, void *closure) +{ + RET_AS_OBJ_OR_NONE(self->name); +} + +PyDoc_STRVAR(PyNetsplitChannel_op_doc, + "is op" +); +static PyObject *PyNetsplitChannel_op_get(PyNetsplitChannel *self, void *closure) +{ + return PyBool_FromLong(self->op); +} + +PyDoc_STRVAR(PyNetsplitChannel_halfop_doc, + "is halfop" +); +static PyObject *PyNetsplitChannel_halfop_get(PyNetsplitChannel *self, void *closure) +{ + return PyBool_FromLong(self->halfop); +} + +PyDoc_STRVAR(PyNetsplitChannel_voice_doc, + "is voice" +); +static PyObject *PyNetsplitChannel_voice_get(PyNetsplitChannel *self, void *closure) +{ + return PyBool_FromLong(self->voice); +} + +PyDoc_STRVAR(PyNetsplitChannel_other_doc, + "?" +); +static PyObject *PyNetsplitChannel_other_get(PyNetsplitChannel *self, void *closure) +{ + return PyInt_FromLong(self->other); +} + +/* specialized getters/setters */ +static PyGetSetDef PyNetsplitChannel_getseters[] = { + {"name", (getter)PyNetsplitChannel_name_get, NULL, + PyNetsplitChannel_name_doc, NULL}, + {"op", (getter)PyNetsplitChannel_op_get, NULL, + PyNetsplitChannel_op_doc, NULL}, + {"halfop", (getter)PyNetsplitChannel_halfop_get, NULL, + PyNetsplitChannel_halfop_doc, NULL}, + {"voice", (getter)PyNetsplitChannel_voice_get, NULL, + PyNetsplitChannel_voice_doc, NULL}, + {"other", (getter)PyNetsplitChannel_other_get, NULL, + PyNetsplitChannel_other_doc, NULL}, + {NULL} +}; + +/* Methods */ +/* Methods for object */ +static PyMethodDef PyNetsplitChannel_methods[] = { + {NULL} /* Sentinel */ +}; + +PyTypeObject PyNetsplitChannelType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "NetsplitChannel", /*tp_name*/ + sizeof(PyNetsplitChannel), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyNetsplitChannel_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*/ + "PyNetsplitChannel objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyNetsplitChannel_methods, /* tp_methods */ + 0, /* tp_members */ + PyNetsplitChannel_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyNetsplitChannel_new, /* tp_new */ +}; + + +/* window item wrapper factory function */ +PyObject *pynetsplit_channel_new(void *netsplit) +{ + NETSPLIT_CHAN_REC *rec = netsplit; + PyNetsplitChannel *pynetsplit; + PyObject *name; + + name = PyString_FromString(rec->name); + if (!name) + return NULL; + + pynetsplit = py_inst(PyNetsplitChannel, PyNetsplitChannelType); + if (!pynetsplit) + { + Py_DECREF(name); + return NULL; + } + + pynetsplit->name = name; + pynetsplit->op = rec->op; + pynetsplit->halfop = rec->halfop; + pynetsplit->other = rec->other; + + return (PyObject *)pynetsplit; +} + +int netsplit_channel_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyNetsplitChannelType) < 0) + return 0; + + Py_INCREF(&PyNetsplitChannelType); + PyModule_AddObject(py_module, "NetsplitChannel", (PyObject *)&PyNetsplitChannelType); + + return 1; +} diff --git a/objects/netsplit-channel-object.h b/objects/netsplit-channel-object.h new file mode 100644 index 0000000..3a00fbb --- /dev/null +++ b/objects/netsplit-channel-object.h @@ -0,0 +1,21 @@ +#ifndef _NETSPLIT_CHANNEL_OBJECT_H_ +#define _NETSPLIT_CHANNEL_OBJECT_H_ + +#include <Python.h> +#include "base-objects.h" + +typedef struct +{ + PyObject_HEAD + PyObject *name; + int op, halfop; + int voice, other; +} PyNetsplitChannel; + +extern PyTypeObject PyNetsplitChannelType; + +int netsplit_channel_object_init(void); +PyObject *pynetsplit_channel_new(void *ns); +#define pynetsplit_channel_check(op) PyObject_TypeCheck(op, &PyNetsplitChannelType) + +#endif diff --git a/objects/netsplit-object.c b/objects/netsplit-object.c new file mode 100644 index 0000000..4864aba --- /dev/null +++ b/objects/netsplit-object.c @@ -0,0 +1,182 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "netsplit-object.h" +#include "factory.h" +#include "pycore.h" + +#define NETSPLIT(ns) ((NETSPLIT_REC*)ns) + +/* monitor "netsplit remove" signal */ +static void netsplit_cleanup(NETSPLIT_REC *netsplit) +{ + PyNetsplit *pynetsplit = signal_get_user_data(); + + if (netsplit == pynetsplit->data) + { + pynetsplit->data = NULL; + pynetsplit->cleanup_installed = 0; + signal_remove_data("netsplit remove", netsplit_cleanup, pynetsplit); + } +} + +static void PyNetsplit_dealloc(PyNetsplit *self) +{ + if (self->cleanup_installed) + signal_remove_data("netsplit remove", netsplit_cleanup, self); + + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject *PyNetsplit_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyNetsplit *self; + + self = (PyNetsplit *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + return (PyObject *)self; +} + +/* Getters */ +PyDoc_STRVAR(PyNetsplit_nick_doc, + "Nick" +); +static PyObject *PyNetsplit_nick_get(PyNetsplit *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(NETSPLIT(self->data)->nick); +} + +PyDoc_STRVAR(PyNetsplit_address_doc, + "Nick's host" +); +static PyObject *PyNetsplit_address_get(PyNetsplit *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(NETSPLIT(self->data)->address); +} + +PyDoc_STRVAR(PyNetsplit_destroy_doc, + "Timestamp when this record should be destroyed" +); +static PyObject *PyNetsplit_destroy_get(PyNetsplit *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(NETSPLIT(self->data)->destroy); +} + +PyDoc_STRVAR(PyNetsplit_server_doc, + "Netsplitserver object" +); +static PyObject *PyNetsplit_server_get(PyNetsplit *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_OBJ_OR_NONE(self->server); +} + +/* specialized getters/setters */ +static PyGetSetDef PyNetsplit_getseters[] = { + {"nick", (getter)PyNetsplit_nick_get, NULL, + PyNetsplit_nick_doc, NULL}, + {"address", (getter)PyNetsplit_address_get, NULL, + PyNetsplit_address_doc, NULL}, + {"destroy", (getter)PyNetsplit_destroy_get, NULL, + PyNetsplit_destroy_doc, NULL}, + {"server", (getter)PyNetsplit_server_get, NULL, + PyNetsplit_server_doc, NULL}, + {NULL} +}; + +/* Methods */ +PyDoc_STRVAR(PyNetsplit_channels_doc, + "Return list of NetsplitChannel objects" +); +static PyObject *PyNetsplit_channels(PyNetsplit *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + return py_irssi_objlist_new(NETSPLIT(self->data)->channels, 1, + (InitFunc)pynetsplit_channel_new); +} + +/* Methods for object */ +static PyMethodDef PyNetsplit_methods[] = { + {"channels", (PyCFunction)PyNetsplit_channels, METH_NOARGS, + PyNetsplit_channels_doc}, + {NULL} /* Sentinel */ +}; + +PyTypeObject PyNetsplitType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Netsplit", /*tp_name*/ + sizeof(PyNetsplit), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyNetsplit_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*/ + "PyNetsplit objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyNetsplit_methods, /* tp_methods */ + 0, /* tp_members */ + PyNetsplit_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyNetsplit_new, /* tp_new */ +}; + + +/* window item wrapper factory function */ +PyObject *pynetsplit_new(void *netsplit) +{ + PyNetsplit *pynetsplit; + + //FIXME: add netsplit server + + pynetsplit = py_inst(PyNetsplit, PyNetsplitType); + if (!pynetsplit) + return NULL; + + pynetsplit->data = netsplit; + pynetsplit->cleanup_installed = 1; + signal_add_last_data("netsplit remove", netsplit_cleanup, pynetsplit); + + return (PyObject *)pynetsplit; +} + +int netsplit_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyNetsplitType) < 0) + return 0; + + Py_INCREF(&PyNetsplitType); + PyModule_AddObject(py_module, "Netsplit", (PyObject *)&PyNetsplitType); + + return 1; +} diff --git a/objects/netsplit-object.h b/objects/netsplit-object.h new file mode 100644 index 0000000..bd166e0 --- /dev/null +++ b/objects/netsplit-object.h @@ -0,0 +1,19 @@ +#ifndef _NETSPLIT_OBJECT_H_ +#define _NETSPLIT_OBJECT_H_ + +#include <Python.h> +#include "base-objects.h" + +typedef struct +{ + PyIrssiFinal_HEAD(void) + PyObject *server; +} PyNetsplit; + +extern PyTypeObject PyNetsplitType; + +int netsplit_object_init(void); +PyObject *pynetsplit_new(void *ns); +#define pynetsplit_check(op) PyObject_TypeCheck(op, &PyNetsplitType) + +#endif diff --git a/objects/netsplit-server-object.c b/objects/netsplit-server-object.c new file mode 100644 index 0000000..7208ae1 --- /dev/null +++ b/objects/netsplit-server-object.c @@ -0,0 +1,157 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "netsplit-object.h" +#include "factory.h" +#include "pycore.h" + +#define NETSPLIT_SERVER(ns) ((NETSPLIT_SERVER_REC*)ns) + +/* monitor "netsplit remove" signal */ +static void netsplit_server_cleanup(NETSPLIT_SERVER_REC *netsplit) +{ + PyNetsplitServer *pynetsplit = signal_get_user_data(); + + if (netsplit == pynetsplit->data) + { + pynetsplit->data = NULL; + pynetsplit->cleanup_installed = 0; + signal_remove_data("netsplit remove", netsplit_server_cleanup, pynetsplit); + } +} + +static void PyNetsplitServer_dealloc(PyNetsplitServer *self) +{ + if (self->cleanup_installed) + signal_remove_data("netsplit remove", netsplit_server_cleanup, self); + + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject *PyNetsplitServer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyNetsplitServer *self; + + self = (PyNetsplitServer *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + return (PyObject *)self; +} + +/* Getters */ +PyDoc_STRVAR(PyNetsplitServer_server_doc, + "The server nick was in" +); +static PyObject *PyNetsplitServer_server_get(PyNetsplitServer *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(NETSPLIT_SERVER(self->data)->server); +} + +PyDoc_STRVAR(PyNetsplitServer_destserver_doc, + "The other server where split occured." +); +static PyObject *PyNetsplitServer_destserver_get(PyNetsplitServer *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(NETSPLIT_SERVER(self->data)->destserver); +} + +PyDoc_STRVAR(PyNetsplitServer_count_doc, + "Number of splits in server" +); +static PyObject *PyNetsplitServer_count_get(PyNetsplitServer *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyInt_FromLong(NETSPLIT_SERVER(self->data)->count); +} + +/* specialized getters/setters */ +static PyGetSetDef PyNetsplitServer_getseters[] = { + {"server", (getter)PyNetsplitServer_server_get, NULL, + PyNetsplitServer_server_doc, NULL}, + {"destserver", (getter)PyNetsplitServer_destserver_get, NULL, + PyNetsplitServer_destserver_doc, NULL}, + {"count", (getter)PyNetsplitServer_count_get, NULL, + PyNetsplitServer_count_doc, NULL}, + {NULL} +}; + +/* Methods */ +/* Methods for object */ +static PyMethodDef PyNetsplitServer_methods[] = { + {NULL} /* Sentinel */ +}; + +PyTypeObject PyNetsplitServerType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "NetsplitServer", /*tp_name*/ + sizeof(PyNetsplitServer), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyNetsplitServer_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*/ + "PyNetsplitServer objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyNetsplitServer_methods, /* tp_methods */ + 0, /* tp_members */ + PyNetsplitServer_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyNetsplitServer_new, /* tp_new */ +}; + + +/* window item wrapper factory function */ +PyObject *pynetsplit_server_new(void *nss) +{ + PyNetsplitServer *pynss; + + pynss = py_inst(PyNetsplitServer, PyNetsplitServerType); + if (!pynss) + return NULL; + + pynss->data = nss; + pynss->cleanup_installed = 1; + signal_add_last_data("netsplit server remove", netsplit_server_cleanup, pynss); + + return (PyObject *)pynss; +} + +int netsplit_server_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyNetsplitServerType) < 0) + return 0; + + Py_INCREF(&PyNetsplitServerType); + PyModule_AddObject(py_module, "NetsplitServer", (PyObject *)&PyNetsplitServerType); + + return 1; +} diff --git a/objects/netsplit-server-object.h b/objects/netsplit-server-object.h new file mode 100644 index 0000000..f1d5fbf --- /dev/null +++ b/objects/netsplit-server-object.h @@ -0,0 +1,18 @@ +#ifndef _NETSPLIT_SERVER_OBJECT_H_ +#define _NETSPLIT_SERVER_OBJECT_H_ + +#include <Python.h> +#include "base-objects.h" + +typedef struct +{ + PyIrssiFinal_HEAD(void) +} PyNetsplitServer; + +extern PyTypeObject PyNetsplitServerType; + +int netsplit_server_object_init(void); +PyObject *pynetsplit_server_new(void *nss); +#define pynetsplit_server_check(op) PyObject_TypeCheck(op, &PyNetsplitServerType) + +#endif diff --git a/objects/notifylist-object.c b/objects/notifylist-object.c new file mode 100644 index 0000000..890c256 --- /dev/null +++ b/objects/notifylist-object.c @@ -0,0 +1,217 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "notifylist-object.h" +#include "pycore.h" + +#define NOTIFYLIST(nl) ((NOTIFYLIST_REC *)nl) + +/* monitor "notifylist remove" signal */ +static void notifylist_cleanup(NOTIFYLIST_REC *notifylist) +{ + PyNotifylist *pynotifylist = signal_get_user_data(); + + if (notifylist == pynotifylist->data) + { + pynotifylist->data = NULL; + pynotifylist->cleanup_installed = 0; + signal_remove_data("notifylist remove", notifylist_cleanup, pynotifylist); + } +} + +static void PyNotifylist_dealloc(PyNotifylist *self) +{ + if (self->cleanup_installed) + signal_remove_data("notifylist remove", notifylist_cleanup, self); + + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject *PyNotifylist_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyNotifylist *self; + + self = (PyNotifylist *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + return (PyObject *)self; +} + +/* Getters */ +PyDoc_STRVAR(PyNotifylist_mask_doc, + "Notify nick mask" +); +static PyObject *PyNotifylist_mask_get(PyNotifylist *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(NOTIFYLIST(self->data)->mask); +} + +PyDoc_STRVAR(PyNotifylist_away_check_doc, + "Notify away status changes" +); +static PyObject *PyNotifylist_away_check_get(PyNotifylist *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(NOTIFYLIST(self->data)->away_check); +} + +PyDoc_STRVAR(PyNotifylist_idle_check_time_doc, + "Notify when idle time is reset and idle was bigger than this (seconds)" +); +static PyObject *PyNotifylist_idle_check_time_get(PyNotifylist *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(NOTIFYLIST(self->data)->idle_check_time); +} + +/* specialized getters/setters */ +static PyGetSetDef PyNotifylist_getseters[] = { + {"mask", (getter)PyNotifylist_mask_get, NULL, + PyNotifylist_mask_doc, NULL}, + {"away_check", (getter)PyNotifylist_away_check_get, NULL, + PyNotifylist_away_check_doc, NULL}, + {"idle_check_time", (getter)PyNotifylist_idle_check_time_get, NULL, + PyNotifylist_idle_check_time_doc, NULL}, + {NULL} +}; + +/* Methods */ +PyDoc_STRVAR(PyNotifylist_ircnets_doc, + "Return list of ircnets the notify is checked" +); +static PyObject *PyNotifylist_ircnets(PyNotifylist *self, PyObject *args) +{ + PyObject *list; + char **nets; + + RET_NULL_IF_INVALID(self->data); + + nets = NOTIFYLIST(self->data)->ircnets; + list = PyList_New(0); + if (!list) + return NULL; + + while (nets && *nets) + { + int ret; + PyObject *str = PyString_FromString(*nets); + + if (!str) + { + Py_DECREF(list); + return NULL; + } + + ret = PyList_Append(list, str); + Py_DECREF(str); + if (ret != 0) + { + Py_DECREF(list); + return NULL; + } + + nets++; + } + + return list; +} + +PyDoc_STRVAR(PyNotifylist_ircnets_match_doc, + "Return True if notify is checked in ircnet" +); +static PyObject *PyNotifylist_ircnets_match(PyNotifylist *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"ircnet", NULL}; + char *ircnet = ""; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &ircnet)) + return NULL; + + return PyBool_FromLong(notifylist_ircnets_match(self->data, ircnet)); +} + +/* Methods for object */ +static PyMethodDef PyNotifylist_methods[] = { + {"ircnets", (PyCFunction)PyNotifylist_ircnets, METH_NOARGS, + PyNotifylist_ircnets_doc}, + {"ircnets_match", (PyCFunction)PyNotifylist_ircnets_match, METH_VARARGS | METH_KEYWORDS, + PyNotifylist_ircnets_match_doc}, + {NULL} /* Sentinel */ +}; + +PyTypeObject PyNotifylistType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Notifylist", /*tp_name*/ + sizeof(PyNotifylist), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyNotifylist_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*/ + "PyNotifylist objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyNotifylist_methods, /* tp_methods */ + 0, /* tp_members */ + PyNotifylist_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyNotifylist_new, /* tp_new */ +}; + + +/* window item wrapper factory function */ +PyObject *pynotifylist_new(void *notifylist) +{ + PyNotifylist *pynotifylist; + + pynotifylist = py_inst(PyNotifylist, PyNotifylistType); + if (!pynotifylist) + return NULL; + + pynotifylist->data = notifylist; + pynotifylist->cleanup_installed = 1; + signal_add_last_data("notifylist remove", notifylist_cleanup, pynotifylist); + + return (PyObject *)pynotifylist; +} + +int notifylist_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyNotifylistType) < 0) + return 0; + + Py_INCREF(&PyNotifylistType); + PyModule_AddObject(py_module, "Notifylist", (PyObject *)&PyNotifylistType); + + return 1; +} diff --git a/objects/notifylist-object.h b/objects/notifylist-object.h new file mode 100644 index 0000000..9db6922 --- /dev/null +++ b/objects/notifylist-object.h @@ -0,0 +1,18 @@ +#ifndef _NOTIFYLIST_OBJECT_H_ +#define _NOTIFYLIST_OBJECT_H_ + +#include <Python.h> +#include "base-objects.h" + +typedef struct +{ + PyIrssiFinal_HEAD(void) +} PyNotifylist; + +extern PyTypeObject PyNotifylistType; + +int notifylist_object_init(void); +PyObject *pynotifylist_new(void *notifylist); +#define pynotifylist_check(op) PyObject_TypeCheck(op, &PyNotifylistType) + +#endif diff --git a/objects/process-object.c b/objects/process-object.c new file mode 100644 index 0000000..43c0fd7 --- /dev/null +++ b/objects/process-object.c @@ -0,0 +1,222 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "process-object.h" +#include "pycore.h" + +/* monitor "exec remove" signal */ +static void process_cleanup(PROCESS_REC *process, int status) +{ + PyProcess *pyprocess = signal_get_user_data(); + + if (process == pyprocess->data) + { + pyprocess->data = NULL; + pyprocess->cleanup_installed = 0; + signal_remove_data("exec remove", process_cleanup, pyprocess); + } +} + +static void PyProcess_dealloc(PyProcess *self) +{ + if (self->cleanup_installed) + signal_remove_data("exec remove", process_cleanup, self); + + Py_XDECREF(self->target_win); + + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject *PyProcess_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyProcess *self; + + self = (PyProcess *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + return (PyObject *)self; +} + +/* Getters */ +PyDoc_STRVAR(PyProcess_id_doc, + "ID for the process" +); +static PyObject *PyProcess_id_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyInt_FromLong(self->data->id); +} + +PyDoc_STRVAR(PyProcess_name_doc, + "Name for the process (if given)" +); +static PyObject *PyProcess_name_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->name); +} + +PyDoc_STRVAR(PyProcess_args_doc, + "The command that is being executed" +); +static PyObject *PyProcess_args_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->args); +} + +PyDoc_STRVAR(PyProcess_pid_doc, + "PID for the executed command" +); +static PyObject *PyProcess_pid_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyInt_FromLong(self->data->pid); +} + +PyDoc_STRVAR(PyProcess_target_doc, + "send text with /msg <target> ..." +); +static PyObject *PyProcess_target_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->target); +} + +PyDoc_STRVAR(PyProcess_target_win_doc, + "print text to this window" +); +static PyObject *PyProcess_target_win_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_OBJ_OR_NONE(self->target_win); +} + +PyDoc_STRVAR(PyProcess_shell_doc, + "start the program via /bin/sh" +); +static PyObject *PyProcess_shell_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->shell); +} + +PyDoc_STRVAR(PyProcess_notice_doc, + "send text with /notice, not /msg if target is set" +); +static PyObject *PyProcess_notice_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->notice); +} + +PyDoc_STRVAR(PyProcess_silent_doc, + "don't print \"process exited with level xx\"" +); +static PyObject *PyProcess_silent_get(PyProcess *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->silent); +} + +/* specialized getters/setters */ +static PyGetSetDef PyProcess_getseters[] = { + {"id", (getter)PyProcess_id_get, NULL, + PyProcess_id_doc, NULL}, + {"name", (getter)PyProcess_name_get, NULL, + PyProcess_name_doc, NULL}, + {"args", (getter)PyProcess_args_get, NULL, + PyProcess_args_doc, NULL}, + {"pid", (getter)PyProcess_pid_get, NULL, + PyProcess_pid_doc, NULL}, + {"target", (getter)PyProcess_target_get, NULL, + PyProcess_target_doc, NULL}, + {"target_win", (getter)PyProcess_target_win_get, NULL, + PyProcess_target_win_doc, NULL}, + {"shell", (getter)PyProcess_shell_get, NULL, + PyProcess_shell_doc, NULL}, + {"notice", (getter)PyProcess_notice_get, NULL, + PyProcess_notice_doc, NULL}, + {"silent", (getter)PyProcess_silent_get, NULL, + PyProcess_silent_doc, NULL}, + {NULL} +}; + +/* Methods */ +/* Methods for object */ +static PyMethodDef PyProcess_methods[] = { + {NULL} /* Sentinel */ +}; + +PyTypeObject PyProcessType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Process", /*tp_name*/ + sizeof(PyProcess), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyProcess_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*/ + "PyProcess objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyProcess_methods, /* tp_methods */ + 0, /* tp_members */ + PyProcess_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyProcess_new, /* tp_new */ +}; + + +/* process factory function */ +PyObject *pyprocess_new(void *process) +{ + PyProcess *pyprocess; + + pyprocess = py_inst(PyProcess, PyProcessType); + if (!pyprocess) + return NULL; + + pyprocess->data = process; + pyprocess->cleanup_installed = 1; + signal_add_last_data("exec remove", process_cleanup, pyprocess); + + return (PyObject *)pyprocess; +} + +int process_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyProcessType) < 0) + return 0; + + Py_INCREF(&PyProcessType); + PyModule_AddObject(py_module, "Process", (PyObject *)&PyProcessType); + + return 1; +} diff --git a/objects/process-object.h b/objects/process-object.h new file mode 100644 index 0000000..041f187 --- /dev/null +++ b/objects/process-object.h @@ -0,0 +1,22 @@ +#ifndef _PROCESS_OBJECT_H_ +#define _PROCESS_OBJECT_H_ + +#include <Python.h> +#include "base-objects.h" + +/* forward */ +struct PROCESS_REC; + +typedef struct +{ + PyIrssiFinal_HEAD(struct PROCESS_REC) + PyObject *target_win; +} PyProcess; + +extern PyTypeObject PyProcessType; + +int process_object_init(void); +PyObject *pyprocess_new(void *process); +#define pyprocess_check(op) PyObject_TypeCheck(op, &PyProcessType) + +#endif diff --git a/objects/server-object.c b/objects/server-object.c index 23a33b0..c000b80 100644 --- a/objects/server-object.c +++ b/objects/server-object.c @@ -34,6 +34,7 @@ static void PyServer_dealloc(PyServer *self) self->ob_type->tp_free((PyObject*)self); } +/* Getters */ PyDoc_STRVAR(PyServer_connect_time_doc, "Time when connect() to server finished" ); @@ -203,6 +204,7 @@ static PyGetSetDef PyServer_getseters[] = { {NULL} }; +/* Methods */ PyDoc_STRVAR(print_doc, "Print to server\n" ); diff --git a/objects/window-item-object.c b/objects/window-item-object.c index 96181fc..6494d48 100644 --- a/objects/window-item-object.c +++ b/objects/window-item-object.c @@ -200,6 +200,15 @@ static PyObject *PyWindowItem_destroy(PyWindowItem *self, PyObject *args) Py_RETURN_NONE; } +PyDoc_STRVAR(PyWindowItem_get_dcc_doc, + "If item is a query of a =nick, return DCC chat record of nick" +); +static PyObject *PyWindowItem_get_dcc(PyWindowItem *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + return py_irssi_new(self->data, 1); +} + /* Methods for object */ static PyMethodDef PyWindowItem_methods[] = { {"prnt", (PyCFunction)PyWindowItem_prnt, METH_VARARGS | METH_KEYWORDS, @@ -218,6 +227,8 @@ static PyMethodDef PyWindowItem_methods[] = { PyWindowItem_activity_doc}, {"destroy", (PyCFunction)PyWindowItem_destroy, METH_NOARGS, PyWindowItem_destroy_doc}, + {"get_dcc", (PyCFunction)PyWindowItem_get_dcc, METH_NOARGS, + PyWindowItem_get_dcc_doc}, {NULL} /* Sentinel */ }; @@ -21,5 +21,6 @@ #include "rawlog.h" #include "log.h" #include "ignore.h" +#include "fe-exec.h" #endif diff --git a/pyirssi_irc.h b/pyirssi_irc.h index 31b0908..b157eff 100644 --- a/pyirssi_irc.h +++ b/pyirssi_irc.h @@ -12,5 +12,7 @@ #include "dcc-get.h" #include "dcc-send.h" #include "dcc-chat.h" +#include "netsplit.h" +#include "notifylist.h" #endif @@ -686,6 +686,98 @@ static PyObject *py_dcc_get_download_path(PyObject *self, PyObject *args, PyObje return pypath; } +PyDoc_STRVAR(py_notifies_doc, + "Return list of notifies" +); +static PyObject *py_notifies(PyObject *self, PyObject *args) +{ + return py_irssi_objlist_new(notifies, 1, (InitFunc)pynotifylist_new); +} + +PyDoc_STRVAR(py_notifylist_add_doc, + "notifylist_add(mask, ircnets=None, away_check=0, idle_time_check=0) -> Notifylist object\n" + "\n" + "Add new item to notify list\n" +); +static PyObject *py_notifylist_add(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"mask", "ircnets", "away_check", "idle_check_time", NULL}; + char *mask = ""; + char *ircnets = NULL; + int away_check = 0; + int idle_check_time = 0; + NOTIFYLIST_REC *rec; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|zii", kwlist, + &mask, &ircnets, &away_check, &idle_check_time)) + return NULL; + + rec = notifylist_add(mask, ircnets, away_check, idle_check_time); + if (rec) + return pynotifylist_new(rec); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(py_notifylist_remove_doc, + "Remove notify item from notify list" +); +static PyObject *py_notifylist_remove(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"mask", NULL}; + char *mask = ""; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &mask)) + return NULL; + + notifylist_remove(mask); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(py_notifylist_ison_doc, + "notifylist_ison(nick, serverlist="") -> IrcServer object\n" + "\n" + "Check if nick is in IRC. serverlist is a space separated list of server tags.\n" + "If it's empty string, all servers will be checked\n" +); +static PyObject *py_notifylist_ison(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"nick", "serverlist", NULL}; + char *nick = ""; + char *serverlist = ""; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, + &nick, &serverlist)) + return NULL; + + return py_irssi_chat_new(notifylist_ison(nick, serverlist), 1); +} + +PyDoc_STRVAR(py_notifylist_find_doc, + "notifylist_find(mask, ircnet=None) -> Notifylist object\n" + "\n" + "Find notify\n" +); +static PyObject *py_notifylist_find(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"mask", "ircnet", NULL}; + char *mask = ""; + char *ircnet = NULL; + NOTIFYLIST_REC *rec; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|z", kwlist, + &mask, &ircnet)) + return NULL; + + rec = notifylist_find(mask, ircnet); + if (rec) + pynotifylist_new(rec); + + Py_RETURN_NONE; +} + static PyMethodDef ModuleMethods[] = { {"prnt", (PyCFunction)py_prnt, METH_VARARGS|METH_KEYWORDS, py_prnt_doc}, {"get_script", (PyCFunction)py_get_script, METH_NOARGS, py_get_script_doc}, @@ -771,6 +863,16 @@ static PyMethodDef ModuleMethods[] = { py_dcc_type2str_doc}, {"dcc_get_download_path", (PyCFunction)py_dcc_get_download_path, METH_VARARGS | METH_KEYWORDS, py_dcc_get_download_path_doc}, + {"notifies", (PyCFunction)py_notifies, METH_NOARGS, + py_notifies_doc}, + {"notifylist_add", (PyCFunction)py_notifylist_add, METH_VARARGS | METH_KEYWORDS, + py_notifylist_add_doc}, + {"notifylist_remove", (PyCFunction)py_notifylist_remove, METH_VARARGS | METH_KEYWORDS, + py_notifylist_remove_doc}, + {"notifylist_ison", (PyCFunction)py_notifylist_ison, METH_VARARGS | METH_KEYWORDS, + py_notifylist_ison_doc}, + {"notifylist_find", (PyCFunction)py_notifylist_find, METH_VARARGS | METH_KEYWORDS, + py_notifylist_find_doc}, {NULL, NULL, 0, NULL} /* Sentinel */ }; |