diff --git a/Makefile.am b/Makefile.am index 2b4acae1..97944f0a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,8 @@ profanity_SOURCES = \ src/plugins/plugins.h src/plugins/plugins.c \ src/plugins/api.h src/plugins/api.c \ src/plugins/callbacks.h src/plugins/callbacks.c \ - src/plugins/python_plugins.h src/plugins/python_plugins.c + src/plugins/python_plugins.h src/plugins/python_plugins.c \ + src/plugins/python_api.h src/plugins/python_api.c TESTS = tests/testsuite check_PROGRAMS = tests/testsuite diff --git a/src/plugins/api.c b/src/plugins/api.c index 8e3505e0..73d09c5d 100644 --- a/src/plugins/api.c +++ b/src/plugins/api.c @@ -20,8 +20,6 @@ * */ -#include - #include #include "plugins/callbacks.h" @@ -29,135 +27,69 @@ #include "ui/notifier.h" #include "ui/ui.h" -static PyObject* -api_cons_alert(PyObject *self, PyObject *args) +void +api_cons_alert(void) { cons_alert(); - return Py_BuildValue(""); } -static PyObject* -api_cons_show(PyObject *self, PyObject *args) +void +api_cons_show(const char * const message) { - const char *message = NULL; - - if (!PyArg_ParseTuple(args, "s", &message)) { - return NULL; + if (message != NULL) { + cons_show("%s", message); + ui_current_page_off(); + ui_refresh(); } - cons_show("%s", message); - ui_current_page_off(); - ui_refresh(); - - return Py_BuildValue(""); } -static PyObject* -api_register_command(PyObject *self, PyObject *args) +void +api_register_command(const char *command_name, int min_args, int max_args, + const char *usage, const char *short_help, const char *long_help, void *callback) { - const char *command_name = NULL; - int min_args = 0; - int max_args = 0; - const char *usage = NULL; - const char *short_help = NULL; - const char *long_help = NULL; - PyObject *p_callback = NULL; + PluginCommand *command = malloc(sizeof(PluginCommand)); + command->command_name = command_name; + command->min_args = min_args; + command->max_args = max_args; + command->usage = usage; + command->short_help = short_help; + command->long_help = long_help; + command->callback = callback; - if (!PyArg_ParseTuple(args, "siisssO", &command_name, &min_args, &max_args, &usage, &short_help, &long_help, &p_callback)) { - return NULL; - } - - if (p_callback && PyCallable_Check(p_callback)) { - PluginCommand *command = malloc(sizeof(PluginCommand)); - command->command_name = command_name; - command->min_args = min_args; - command->max_args = max_args; - command->usage = usage; - command->short_help = short_help; - command->long_help = long_help; - command->p_callback = p_callback; - - callbacks_add_command(command); - } - - return Py_BuildValue(""); + callbacks_add_command(command); } -static PyObject * -api_register_timed(PyObject *self, PyObject *args) +void +api_register_timed(void *callback, int interval_seconds) { - PyObject *p_callback = NULL; - int interval_seconds = 0; + PluginTimedFunction *timed_function = malloc(sizeof(PluginTimedFunction)); + timed_function->callback = callback; + timed_function->interval_seconds = interval_seconds; + timed_function->timer = g_timer_new(); - if (!PyArg_ParseTuple(args, "Oi", &p_callback, &interval_seconds)) { - return NULL; - } - - if (p_callback && PyCallable_Check(p_callback)) { - PluginTimedFunction *timed_function = malloc(sizeof(PluginTimedFunction)); - timed_function->p_callback = p_callback; - timed_function->interval_seconds = interval_seconds; - timed_function->timer = g_timer_new(); - - callbacks_add_timed(timed_function); - } - - return Py_BuildValue(""); + callbacks_add_timed(timed_function); } -static PyObject* -api_notify(PyObject *self, PyObject *args) +void +api_notify(const char *message, const char *category, int timeout_ms) { - const char *message = NULL; - const char *category = NULL; - int timeout_ms = 5000; - - if (!PyArg_ParseTuple(args, "sis", &message, &timeout_ms, &category)) { - return NULL; - } - notify(message, timeout_ms, category); - - return Py_BuildValue(""); } -static PyObject* -api_send_line(PyObject *self, PyObject *args) +void +api_send_line(char *line) { - char *line = NULL; - if (!PyArg_ParseTuple(args, "s", &line)) { - return NULL; - } - prof_process_input(line); - - return Py_BuildValue(""); } -static PyObject * -api_get_current_recipient(PyObject *self, PyObject *args) +char * +api_get_current_recipient(void) { win_type_t win_type = ui_current_win_type(); if (win_type == WIN_CHAT) { char *recipient = ui_current_recipient(); - return Py_BuildValue("s", recipient); + return recipient; } else { - return Py_BuildValue(""); + return NULL; } } - -static PyMethodDef apiMethods[] = { - { "cons_alert", api_cons_alert, METH_NOARGS, "Highlight the console window in the status bar." }, - { "cons_show", api_cons_show, METH_VARARGS, "Print a line to the console." }, - { "register_command", api_register_command, METH_VARARGS, "Register a command." }, - { "register_timed", api_register_timed, METH_VARARGS, "Register a timed function." }, - { "send_line", api_send_line, METH_VARARGS, "Send a line of input." }, - { "notify", api_notify, METH_VARARGS, "Send desktop notification." }, - { "get_current_recipient", api_get_current_recipient, METH_VARARGS, "Return the jid of the recipient of the current window." }, - { NULL, NULL, 0, NULL } -}; - -void -api_init(void) -{ - Py_InitModule("prof", apiMethods); -} diff --git a/src/plugins/api.h b/src/plugins/api.h index 38f77dfe..7e884b47 100644 --- a/src/plugins/api.h +++ b/src/plugins/api.h @@ -23,6 +23,15 @@ #ifndef API_H #define API_H -void api_init(void); +void api_cons_alert(void); +void api_cons_show(const char * const message); +void api_notify(const char *message, const char *category, int timeout_ms); +void api_send_line(char *line); +char * api_get_current_recipient(void); + +void api_register_command(const char *command_name, int min_args, int max_args, + const char *usage, const char *short_help, const char *long_help, + void *callback); +void api_register_timed(void *callback, int interval_seconds); #endif diff --git a/src/plugins/callbacks.c b/src/plugins/callbacks.c index b5dda9f1..f0be5f09 100644 --- a/src/plugins/callbacks.c +++ b/src/plugins/callbacks.c @@ -69,30 +69,30 @@ plugins_run_command(const char * const input) if (num_args == 0) { if (command->max_args == 1) { p_args = Py_BuildValue("(O)", Py_BuildValue("")); - PyObject_CallObject(command->p_callback, p_args); + PyObject_CallObject(command->callback, p_args); Py_XDECREF(p_args); } else { - PyObject_CallObject(command->p_callback, p_args); + PyObject_CallObject(command->callback, p_args); } } else if (num_args == 1) { p_args = Py_BuildValue("(s)", args[0]); - PyObject_CallObject(command->p_callback, p_args); + PyObject_CallObject(command->callback, p_args); Py_XDECREF(p_args); } else if (num_args == 2) { p_args = Py_BuildValue("ss", args[0], args[1]); - PyObject_CallObject(command->p_callback, p_args); + PyObject_CallObject(command->callback, p_args); Py_XDECREF(p_args); } else if (num_args == 3) { p_args = Py_BuildValue("sss", args[0], args[1], args[2]); - PyObject_CallObject(command->p_callback, p_args); + PyObject_CallObject(command->callback, p_args); Py_XDECREF(p_args); } else if (num_args == 4) { p_args = Py_BuildValue("ssss", args[0], args[1], args[2], args[3]); - PyObject_CallObject(command->p_callback, p_args); + PyObject_CallObject(command->callback, p_args); Py_XDECREF(p_args); } else if (num_args == 5) { p_args = Py_BuildValue("sssss", args[0], args[1], args[2], args[3], args[4]); - PyObject_CallObject(command->p_callback, p_args); + PyObject_CallObject(command->callback, p_args); Py_XDECREF(p_args); } @@ -121,7 +121,7 @@ plugins_run_timed(void) gdouble elapsed = g_timer_elapsed(timed_function->timer, NULL); if (timed_function->interval_seconds > 0 && elapsed >= timed_function->interval_seconds) { - PyObject_CallObject(timed_function->p_callback, NULL); + PyObject_CallObject(timed_function->callback, NULL); g_timer_start(timed_function->timer); } diff --git a/src/plugins/callbacks.h b/src/plugins/callbacks.h index 59c071f8..3a599e33 100644 --- a/src/plugins/callbacks.h +++ b/src/plugins/callbacks.h @@ -34,11 +34,11 @@ typedef struct p_command { const char *usage; const char *short_help; const char *long_help; - PyObject *p_callback; + PyObject *callback; } PluginCommand; typedef struct p_timed_function { - PyObject *p_callback; + PyObject *callback; int interval_seconds; GTimer *timer; } PluginTimedFunction; diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c index 573f10ee..2e39f866 100644 --- a/src/plugins/plugins.c +++ b/src/plugins/plugins.c @@ -26,6 +26,7 @@ #include "plugins/api.h" #include "plugins/callbacks.h" #include "plugins/plugins.h" +#include "plugins/python_api.h" #include "plugins/python_plugins.h" #include "ui/ui.h" @@ -39,7 +40,7 @@ plugins_init(void) // initialse python and path Py_Initialize(); python_check_error(); - api_init(); + python_api_init(); python_check_error(); // TODO change to use XDG spec GString *path = g_string_new(Py_GetPath()); diff --git a/src/plugins/python_api.c b/src/plugins/python_api.c new file mode 100644 index 00000000..4d257aef --- /dev/null +++ b/src/plugins/python_api.c @@ -0,0 +1,146 @@ +/* + * python_api.c + * + * Copyright (C) 2012, 2013 James Booth + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see . + * + */ + +#include + +#include + +#include "plugins/api.h" +#include "profanity.h" +#include "ui/notifier.h" +#include "ui/ui.h" + +static PyObject* +python_api_cons_alert(PyObject *self, PyObject *args) +{ + api_cons_alert(); + return Py_BuildValue(""); +} + +static PyObject* +python_api_cons_show(PyObject *self, PyObject *args) +{ + const char *message = NULL; + if (!PyArg_ParseTuple(args, "s", &message)) { + return NULL; + } + api_cons_show(message); + return Py_BuildValue(""); +} + +static PyObject* +python_api_register_command(PyObject *self, PyObject *args) +{ + const char *command_name = NULL; + int min_args = 0; + int max_args = 0; + const char *usage = NULL; + const char *short_help = NULL; + const char *long_help = NULL; + PyObject *p_callback = NULL; + + if (!PyArg_ParseTuple(args, "siisssO", &command_name, &min_args, &max_args, + &usage, &short_help, &long_help, &p_callback)) { + return NULL; + } + + if (p_callback && PyCallable_Check(p_callback)) { + api_register_command(command_name, min_args, max_args, usage, + short_help, long_help, p_callback); + } + + return Py_BuildValue(""); +} + +static PyObject * +python_api_register_timed(PyObject *self, PyObject *args) +{ + PyObject *p_callback = NULL; + int interval_seconds = 0; + + if (!PyArg_ParseTuple(args, "Oi", &p_callback, &interval_seconds)) { + return NULL; + } + + if (p_callback && PyCallable_Check(p_callback)) { + api_register_timed(p_callback, interval_seconds); + } + + return Py_BuildValue(""); +} + +static PyObject* +python_api_notify(PyObject *self, PyObject *args) +{ + const char *message = NULL; + const char *category = NULL; + int timeout_ms = 5000; + + if (!PyArg_ParseTuple(args, "sis", &message, &timeout_ms, &category)) { + return NULL; + } + + api_notify(message, category, timeout_ms); + + return Py_BuildValue(""); +} + +static PyObject* +python_api_send_line(PyObject *self, PyObject *args) +{ + char *line = NULL; + if (!PyArg_ParseTuple(args, "s", &line)) { + return NULL; + } + + api_send_line(line); + + return Py_BuildValue(""); +} + +static PyObject * +python_api_get_current_recipient(PyObject *self, PyObject *args) +{ + char *recipient = api_get_current_recipient(); + if (recipient != NULL) { + return Py_BuildValue("s", recipient); + } else { + return Py_BuildValue(""); + } +} + +static PyMethodDef apiMethods[] = { + { "cons_alert", python_api_cons_alert, METH_NOARGS, "Highlight the console window in the status bar." }, + { "cons_show", python_api_cons_show, METH_VARARGS, "Print a line to the console." }, + { "register_command", python_api_register_command, METH_VARARGS, "Register a command." }, + { "register_timed", python_api_register_timed, METH_VARARGS, "Register a timed function." }, + { "send_line", python_api_send_line, METH_VARARGS, "Send a line of input." }, + { "notify", python_api_notify, METH_VARARGS, "Send desktop notification." }, + { "get_current_recipient", python_api_get_current_recipient, METH_VARARGS, "Return the jid of the recipient of the current window." }, + { NULL, NULL, 0, NULL } +}; + +void +python_api_init(void) +{ + Py_InitModule("prof", apiMethods); +} diff --git a/src/plugins/python_api.h b/src/plugins/python_api.h new file mode 100644 index 00000000..d598ec68 --- /dev/null +++ b/src/plugins/python_api.h @@ -0,0 +1,28 @@ +/* + * python_api.h + * + * Copyright (C) 2012, 2013 James Booth + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see . + * + */ + +#ifndef PYTHON_API_H +#define PYTHON_API_H + +void python_api_init(void); + +#endif