diff options
author | Christopher Davis <loafier@gmail.com> | 2006-06-19 12:25:06 +0000 |
---|---|---|
committer | Christopher Davis <loafier@gmail.com> | 2006-06-19 12:25:06 +0000 |
commit | bb48c914c6239ed1dbcb29eb62d33d3ab91e7215 (patch) | |
tree | 0b6910959f96f683f3aa11a8e2f53572e42b3305 /objects/log-object.c | |
parent | efef73ae301947875602d67d0979a8ce3bd57dd0 (diff) | |
download | irssi-python-bb48c914c6239ed1dbcb29eb62d33d3ab91e7215.tar.gz irssi-python-bb48c914c6239ed1dbcb29eb62d33d3ab91e7215.tar.xz irssi-python-bb48c914c6239ed1dbcb29eb62d33d3ab91e7215.zip |
initial import
git-svn-id: http://svn.irssi.org/repos/irssi-python@4282 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'objects/log-object.c')
-rw-r--r-- | objects/log-object.c | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/objects/log-object.c b/objects/log-object.c new file mode 100644 index 0000000..fae9cd4 --- /dev/null +++ b/objects/log-object.c @@ -0,0 +1,465 @@ +#include <Python.h> +#include "pyirssi_irc.h" +#include "pymodule.h" +#include "log-object.h" +#include "factory.h" +#include "pycore.h" + +static LOG_ITEM_REC *find_item(LOG_REC *log, PyLogitem *item); +static void log_cleanup(LOG_REC *log); +static int logtype(int *type, int target, int window); + +/* find/convert a py log item */ +static LOG_ITEM_REC *find_item(LOG_REC *log, PyLogitem *item) +{ + int type; + char *name; + char *servertag = NULL; + + if (!item->type || !item->name) + return NULL; + + type = PyInt_AS_LONG(item->type); + name = PyString_AS_STRING(item->name); + if (item->servertag) + servertag = PyString_AS_STRING(item->servertag); + + return log_item_find(log, type, name, servertag); +} + +/* monitor "log remove" signal */ +static void log_cleanup(LOG_REC *log) +{ + PyLog *pylog = signal_get_user_data(); + + if (log == pylog->data) + { + pylog->data = NULL; + pylog->cleanup_installed = 0; + signal_remove_data("log remove", log_cleanup, pylog); + } +} + +static void PyLog_dealloc(PyLog *self) +{ + if (self->cleanup_installed) + signal_remove_data("log remove", log_cleanup, self); + + if (self->data && !g_slist_find(logs, self->data)) + { + printtext(NULL, NULL, MSGLEVEL_CRAP, "destroying orphan log %s", self->data->fname); + log_close(self->data); + } + + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject *PyLog_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyLog *self; + + self = (PyLog *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + return (PyObject *)self; +} + +/* function to create the log */ +PyDoc_STRVAR(PyLog_doc, + "__init__(fname, level=MSGLEVEL_ALL)\n" + "\n" + "Create a log\n" +); +static int PyLog_init(PyLog *self, PyObject *args, PyObject *kwds) +{ + char *fname; + int level = MSGLEVEL_ALL; + LOG_REC *log; + + static char *kwlist[] = {"fname", "level", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, + &fname, &level)) + return -1; + + /*XXX: anything better than RuntimeError ? */ + if (self->data || self->cleanup_installed) + { + PyErr_Format(PyExc_RuntimeError, "log already opened; close it first"); + return -1; + } + + log = log_create_rec(fname, level); + if (!log) + { + PyErr_Format(PyExc_RuntimeError, "failed to create log"); + return -1; + } + + self->data = log; + self->cleanup_installed = 1; + signal_add_last_data("log remove", log_cleanup, self); + + return 0; +} + +/* Getters */ +PyDoc_STRVAR(PyLog_fname_doc, + "Log file name" +); +static PyObject *PyLog_fname_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->fname); +} + +PyDoc_STRVAR(PyLog_real_fname_doc, + "The actual opened log file (after %d.%m.Y etc. are expanded)" +); +static PyObject *PyLog_real_fname_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + RET_AS_STRING_OR_NONE(self->data->real_fname); +} + +PyDoc_STRVAR(PyLog_opened_doc, + "Log file is open" +); +static PyObject *PyLog_opened_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(self->data->opened); +} + +PyDoc_STRVAR(PyLog_level_doc, + "Log only these levels" +); +static PyObject *PyLog_level_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyInt_FromLong(self->data->level); +} + +PyDoc_STRVAR(PyLog_last_doc, + "Timestamp when last message was written" +); +static PyObject *PyLog_last_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyLong_FromUnsignedLong(self->data->last); +} + +PyDoc_STRVAR(PyLog_autoopen_doc, + "Automatically open log at startup" +); +static PyObject *PyLog_autoopen_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->autoopen); +} + +PyDoc_STRVAR(PyLog_failed_doc, + "Opening log failed last time" +); +static PyObject *PyLog_failed_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->failed); +} + +PyDoc_STRVAR(PyLog_temp_doc, + "Log isn't saved to config file" +); +static PyObject *PyLog_temp_get(PyLog *self, void *closure) +{ + RET_NULL_IF_INVALID(self->data); + return PyBool_FromLong(self->data->temp); +} + +/* specialized getters/setters */ +static PyGetSetDef PyLog_getseters[] = { + {"fname", (getter)PyLog_fname_get, NULL, + PyLog_fname_doc, NULL}, + {"real_fname", (getter)PyLog_real_fname_get, NULL, + PyLog_real_fname_doc, NULL}, + {"opened", (getter)PyLog_opened_get, NULL, + PyLog_opened_doc, NULL}, + {"level", (getter)PyLog_level_get, NULL, + PyLog_level_doc, NULL}, + {"last", (getter)PyLog_last_get, NULL, + PyLog_last_doc, NULL}, + {"autoopen", (getter)PyLog_autoopen_get, NULL, + PyLog_autoopen_doc, NULL}, + {"failed", (getter)PyLog_failed_get, NULL, + PyLog_failed_doc, NULL}, + {"temp", (getter)PyLog_temp_get, NULL, + PyLog_temp_doc, NULL}, + {NULL} +}; + +/* Methods */ +PyDoc_STRVAR(PyLog_items_doc, + "Return a list of log items" +); +static PyObject *PyLog_items(PyLog *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + return py_irssi_objlist_new(self->data->items, 1, (InitFunc)pylogitem_new); +} + +PyDoc_STRVAR(PyLog_update_doc, + "Add log to list of logs / save changes to config file." +); +static PyObject *PyLog_update(PyLog *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + + log_update(self->data); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyLog_close_doc, + "Destroy the log file" +); +static PyObject *PyLog_close(PyLog *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + + log_close(self->data); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyLog_start_logging_doc, + "Open log file and start logging." +); +static PyObject *PyLog_start_logging(PyLog *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + + log_start_logging(self->data); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyLog_stop_logging_doc, + "Stop and close the log file." +); +static PyObject *PyLog_stop_logging(PyLog *self, PyObject *args) +{ + RET_NULL_IF_INVALID(self->data); + + log_stop_logging(self->data); + + Py_RETURN_NONE; +} + +static int logtype(int *type, int target, int window) +{ + if (target || window) + { + if (target && window) + { + PyErr_SetString(PyExc_TypeError, "must specify target or window, not both"); + return 0; + } + + *type = target? 0 : 1; + } + else if (*type < 0) + { + PyErr_SetString(PyExc_TypeError, "must specify type, target, or window"); + return 0; + } + + return 1; +} + +PyDoc_STRVAR(PyLog_item_add_doc, + "item_add(item, servertag=None, type=0, target=False, window=False) -> None\n" + "\n" + "Add a log item to log.\n" + "\n" + "Add a target item (nick, chan): \n" + " item_add('#linux', target=True)\n" + " item_add('#linux', type=0)\n" + "\n" + "Add a window ref: \n" + " item_add('2', window=True)\n" + " item_add('2', type=1)\n" +); +static PyObject *PyLog_item_add(PyLog *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"item", "servertag", "type", "target", "window", NULL}; + char *item = ""; + char *servertag = NULL; + int type = 0; + int target = 0; + int window = 0; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ziii", kwlist, + &item, &servertag, &type, &target, &window)) + return NULL; + + if (!logtype(&type, target, window)) + return NULL; + + log_item_add(self->data, type, item, servertag); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyLog_item_destroy_doc, + "Remove log item from log." +); +static PyObject *PyLog_item_destroy(PyLog *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"item", NULL}; + PyObject *item = NULL; + LOG_ITEM_REC *li; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, + &item)) + return NULL; + + if (!pylogitem_check(item)) + return PyErr_Format(PyExc_TypeError, "arg 1 should be log item"); + + li = find_item(self->data, (PyLogitem *)item); + if (!li) + return PyErr_Format(PyExc_TypeError, "log item invalid or not found"); + + log_item_destroy(self->data, li); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PyLog_item_find_doc, + "item_find(item, servertag=None, type=-1, target=False, window=False) -> item or None\n" + "\n" + "Find item from log.\n" +); +static PyObject *PyLog_item_find(PyLog *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"item", "servertag", "type", "target", "window", NULL}; + char *item = ""; + char *server = NULL; + int type = 0; + int target = 0; + int window = 0; + LOG_ITEM_REC *li; + + RET_NULL_IF_INVALID(self->data); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ziii", kwlist, + &item, &server, &type, &target, &window)) + return NULL; + + if (!logtype(&type, target, window)) + return NULL; + + li = log_item_find(self->data, type, item, server); + if (li) + return pylogitem_new(li); + + Py_RETURN_NONE; +} + +/* Methods for object */ +static PyMethodDef PyLog_methods[] = { + {"items", (PyCFunction)PyLog_items, METH_NOARGS, + PyLog_items_doc}, + {"update", (PyCFunction)PyLog_update, METH_NOARGS, + PyLog_update_doc}, + {"close", (PyCFunction)PyLog_close, METH_NOARGS, + PyLog_close_doc}, + {"start_logging", (PyCFunction)PyLog_start_logging, METH_NOARGS, + PyLog_start_logging_doc}, + {"stop_logging", (PyCFunction)PyLog_stop_logging, METH_NOARGS, + PyLog_stop_logging_doc}, + {"item_add", (PyCFunction)PyLog_item_add, METH_VARARGS | METH_KEYWORDS, + PyLog_item_add_doc}, + {"item_destroy", (PyCFunction)PyLog_item_destroy, METH_VARARGS | METH_KEYWORDS, + PyLog_item_destroy_doc}, + {"item_find", (PyCFunction)PyLog_item_find, METH_VARARGS | METH_KEYWORDS, + PyLog_item_find_doc}, + {NULL} /* Sentinel */ +}; + +PyTypeObject PyLogType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Log", /*tp_name*/ + sizeof(PyLog), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyLog_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*/ + PyLog_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyLog_methods, /* tp_methods */ + 0, /* tp_members */ + PyLog_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)PyLog_init, /* tp_init */ + 0, /* tp_alloc */ + PyLog_new, /* tp_new */ +}; + + +/* window item wrapper factory function */ +PyObject *pylog_new(void *log) +{ + PyLog *pylog; + + pylog = (PyLog *)PyLogType.tp_alloc(&PyLogType, 0); + if (!pylog) + return NULL; + + pylog->data = log; + pylog->cleanup_installed = 1; + signal_add_last_data("log remove", log_cleanup, pylog); + + return (PyObject *)pylog; +} + +int log_object_init(void) +{ + g_return_val_if_fail(py_module != NULL, 0); + + if (PyType_Ready(&PyLogType) < 0) + return 0; + + Py_INCREF(&PyLogType); + PyModule_AddObject(py_module, "Log", (PyObject *)&PyLogType); + + return 1; +} |