├── NEWS ├── AUTHORS ├── src ├── pyconstants.h ├── pycore.h ├── pymodule.h ├── pyutils.h ├── pysource.h ├── objects │ ├── ban-object.h │ ├── theme-object.h │ ├── dcc-get-object.h │ ├── dcc-send-object.h │ ├── command-object.h │ ├── log-object.h │ ├── netsplit-object.h │ ├── notifylist-object.h │ ├── query-object.h │ ├── window-object.h │ ├── ignore-object.h │ ├── dcc-chat-object.h │ ├── netsplit-server-object.h │ ├── logitem-object.h │ ├── rawlog-object.h │ ├── irc-server-object.h │ ├── main-window-object.h │ ├── nick-object.h │ ├── process-object.h │ ├── irc-channel-object.h │ ├── chatnet-object.h │ ├── irc-connect-object.h │ ├── reconnect-object.h │ ├── netsplit-channel-object.h │ ├── statusbar-item-object.h │ ├── textdest-object.h │ ├── channel-object.h │ ├── connect-object.h │ ├── dcc-object.h │ ├── server-object.h │ ├── window-item-object.h │ ├── pyscript-object.h │ ├── Makefile.am │ ├── factory.h │ ├── base-objects.h │ ├── irc-connect-object.c │ ├── dcc-chat-object.c │ ├── command-object.c │ ├── logitem-object.c │ ├── ban-object.c │ ├── dcc-get-object.c │ ├── dcc-send-object.c │ ├── reconnect-object.c │ ├── netsplit-server-object.c │ ├── netsplit-channel-object.c │ ├── query-object.c │ ├── irc-channel-object.c │ ├── chatnet-object.c │ ├── netsplit-object.c │ ├── theme-object.c │ ├── connect-object.c │ ├── main-window-object.c │ ├── process-object.c │ ├── notifylist-object.c │ └── nick-object.c ├── pythemes.h ├── pystatusbar.h ├── constants.awk ├── pyirssi_irc.h ├── irssi_startup.py ├── pyloader.h ├── pyirssi.h ├── constants.txt ├── sig2code.txt ├── Makefile.am ├── sig2code.awk ├── pysignals.h ├── irssi.py ├── pyutils.c ├── pysource.c ├── pystatusbar.c ├── pycore.c └── pysigmap.h ├── TODO ├── scripts ├── Makefile.am ├── hello.py ├── dccmove.py ├── beep_beep.py ├── df.py ├── fork.py ├── test_window.py └── dumper.py ├── Makefile.am ├── ChangeLog ├── README ├── INSTALL ├── configure.in └── classes.txt /NEWS: -------------------------------------------------------------------------------- 1 | This is news 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Christopher Davis 2 | -------------------------------------------------------------------------------- /src/pyconstants.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYCONSTANTS_H_ 2 | #define _PYCONSTANTS_H_ 3 | 4 | void pyconstants_init(void); 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /src/pycore.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYCORE_H 2 | #define _PYCORE_H 3 | 4 | void python_init(void); 5 | void python_deinit(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | -- Fix loader to handle module hierarchies better. 2 | 3 | -- Add more example scripts. 4 | 5 | -- Fix irssi-python to better match Irssi's structure. 6 | -------------------------------------------------------------------------------- /scripts/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | scriptsdir = $(datadir)/irssi/scripts 3 | 4 | scripts_DATA = \ 5 | beep_beep.py \ 6 | dccmove.py \ 7 | df.py \ 8 | dumper.py \ 9 | fork.py \ 10 | hello.py \ 11 | test_window.py 12 | 13 | EXTRA_DIST = $(scripts_DATA) 14 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src scripts docs 2 | 3 | variables: 4 | echo @PYTHON_CPPFLAGS@ 5 | echo $(PYTHON_CPPFLAGS) 6 | echo $(PYTHON_LDFLAGS) 7 | echo $(PYTHON_EXTRA_LIBS) 8 | echo $(PYTHON_EXTRA_LDFLAGS) 9 | echo $(GLIB_CFLAGS) 10 | echo $(GLIB_LIBS) 11 | -------------------------------------------------------------------------------- /src/pymodule.h: -------------------------------------------------------------------------------- 1 | #ifndef _PY_MODULE_H_ 2 | #define _PY_MODULE_H_ 3 | 4 | #include 5 | 6 | /* This is global so that type objects and such can be easily attached */ 7 | extern PyObject *py_module; 8 | int pymodule_init(void); 9 | void pymodule_deinit(void); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/pyutils.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYUTILS_H_ 2 | #define _PYUTILS_H_ 3 | 4 | #include "servers.h" 5 | 6 | void py_command(const char *cmd, SERVER_REC *server, WI_ITEM_REC *item); 7 | char *file_get_ext(const char *file); 8 | int file_has_ext(const char *file, const char *ext); 9 | char *file_get_filename(const char *path); 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/pysource.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYSOURCE_H_ 2 | #define _PYSOURCE_H_ 3 | 4 | #include 5 | 6 | /* condition is G_INPUT_READ or G_INPUT_WRITE */ 7 | int pysource_io_add_watch_list(GSList **list, int fd, int cond, PyObject *func, PyObject *data); 8 | int pysource_timeout_add_list(GSList **list, int msecs, PyObject *func, PyObject *data); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/objects/ban-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _BAN_OBJECT_H_ 2 | #define _BAN_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyIrssiFinal_HEAD(void) 10 | } PyBan; 11 | 12 | extern PyTypeObject PyBanType; 13 | 14 | int ban_object_init(void); 15 | PyObject *pyban_new(void *ban); 16 | #define pyban_check(op) PyObject_TypeCheck(op, &PyBanType) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/pythemes.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYTHEMES_H_ 2 | #define _PYTHEMES_H_ 3 | 4 | #include 5 | 6 | struct _TEXT_DEST_REC; 7 | 8 | int pythemes_printformat(struct _TEXT_DEST_REC *dest, const char *script, const char *format, PyObject *argtup); 9 | int pythemes_register(const char *script, PyObject *list); 10 | void pythemes_unregister(const char *script); 11 | int pythemes_init(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/pystatusbar.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYSTATUSBAR_H_ 2 | #define _PYSTATUSBAR_H_ 3 | 4 | #include 5 | 6 | void pystatusbar_item_register(PyObject *script, const char *sitem, 7 | const char *value, PyObject *func); 8 | void pystatusbar_item_unregister(const char *iname); 9 | void pystatusbar_cleanup_script(PyObject *script); 10 | void pystatusbar_init(void); 11 | void pystatusbar_deinit(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/objects/theme-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _THEME_OBJECT_H_ 2 | #define _THEME_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyIrssiFinal_HEAD(void) 10 | } PyTheme; 11 | 12 | extern PyTypeObject PyThemeType; 13 | 14 | int theme_object_init(void); 15 | PyObject *pytheme_new(void *td); 16 | #define pytheme_check(op) PyObject_TypeCheck(op, &PyThemeType) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/objects/dcc-get-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _DCC_GET_OBJECT_H_ 2 | #define _DCC_GET_OBJECT_H_ 3 | 4 | #include 5 | #include "dcc-object.h" 6 | 7 | typedef struct 8 | { 9 | PyDcc_HEAD(void) 10 | } PyDccGet; 11 | 12 | extern PyTypeObject PyDccGetType; 13 | 14 | PyObject *pydcc_get_new(void *dcc); 15 | #define pydcc_get_check(op) PyObject_TypeCheck(op, &PyDccGetType) 16 | int dcc_get_object_init(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/constants.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "#include \"pymodule.h\""; 3 | print "#include \"pyirssi_irc.h\""; 4 | print 5 | print "void pyconstants_init(void)" 6 | print "{" 7 | } 8 | 9 | { 10 | if (NF >= 2) 11 | constant = $2; 12 | else 13 | constant = $1; 14 | 15 | printf(" PyModule_AddIntConstant(py_module, \"%s\", %s);\n", $1, constant); 16 | } 17 | 18 | END { 19 | print "}" 20 | } 21 | -------------------------------------------------------------------------------- /src/objects/dcc-send-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _DCC_SEND_OBJECT_H_ 2 | #define _DCC_SEND_OBJECT_H_ 3 | 4 | #include 5 | #include "dcc-object.h" 6 | 7 | typedef struct 8 | { 9 | PyDcc_HEAD(void) 10 | } PyDccSend; 11 | 12 | extern PyTypeObject PyDccSendType; 13 | 14 | PyObject *pydcc_send_new(void *dcc); 15 | #define pydcc_send_check(op) PyObject_TypeCheck(op, &PyDccSendType) 16 | int dcc_send_object_init(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/objects/command-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMAND_OBJECT_H_ 2 | #define _COMMAND_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyIrssiFinal_HEAD(void) 10 | } PyCommand; 11 | 12 | extern PyTypeObject PyCommandType; 13 | 14 | int command_object_init(void); 15 | PyObject *pycommand_new(void *command); 16 | #define pycommand_check(op) PyObject_TypeCheck(op, &PyCommandType) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/objects/log-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOG_OBJECT_H_ 2 | #define _LOG_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _LOG_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssiFinal_HEAD(struct _LOG_REC) 13 | } PyLog; 14 | 15 | extern PyTypeObject PyLogType; 16 | 17 | int log_object_init(void); 18 | PyObject *pylog_new(void *log); 19 | #define pylog_check(op) PyObject_TypeCheck(op, &PyLogType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/netsplit-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _NETSPLIT_OBJECT_H_ 2 | #define _NETSPLIT_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyIrssiFinal_HEAD(void) 10 | PyObject *server; 11 | } PyNetsplit; 12 | 13 | extern PyTypeObject PyNetsplitType; 14 | 15 | int netsplit_object_init(void); 16 | PyObject *pynetsplit_new(void *ns); 17 | #define pynetsplit_check(op) PyObject_TypeCheck(op, &PyNetsplitType) 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/objects/notifylist-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _NOTIFYLIST_OBJECT_H_ 2 | #define _NOTIFYLIST_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyIrssiFinal_HEAD(void) 10 | } PyNotifylist; 11 | 12 | extern PyTypeObject PyNotifylistType; 13 | 14 | int notifylist_object_init(void); 15 | PyObject *pynotifylist_new(void *notifylist); 16 | #define pynotifylist_check(op) PyObject_TypeCheck(op, &PyNotifylistType) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/pyirssi_irc.h: -------------------------------------------------------------------------------- 1 | #ifndef _PY_IRSSI_IRC_H_ 2 | #define _PY_IRSSI_IRC_H_ 3 | 4 | #include "pyirssi.h" 5 | #include "irc.h" 6 | #include "irc-servers.h" 7 | #include "servers-redirect.h" 8 | #include "irc-channels.h" 9 | #include "ctcp.h" 10 | #include "mode-lists.h" 11 | #include "bans.h" 12 | #include "dcc.h" 13 | #include "dcc-get.h" 14 | #include "dcc-send.h" 15 | #include "dcc-chat.h" 16 | #include "netsplit.h" 17 | #include "notifylist.h" 18 | #include "irc-masks.h" 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/objects/query-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_OBJECT_H_ 2 | #define _QUERY_OBJECT_H_ 3 | 4 | #include 5 | #include "window-item-object.h" 6 | 7 | /* forward */ 8 | struct _QUERY_REC; 9 | 10 | typedef struct 11 | { 12 | PyWindowItem_HEAD(struct _QUERY_REC) 13 | } PyQuery; 14 | 15 | extern PyTypeObject PyQueryType; 16 | 17 | int query_object_init(void); 18 | PyObject *pyquery_new(void *query); 19 | #define pyquery_check(op) PyObject_TypeCheck(op, &PyQueryType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/window-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _WINDOW_OBJECT_H_ 2 | #define _WINDOW_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _WINDOW_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssiFinal_HEAD(struct _WINDOW_REC) 13 | } PyWindow; 14 | 15 | extern PyTypeObject PyWindowType; 16 | 17 | int window_object_init(void); 18 | PyObject *pywindow_new(void *win); 19 | #define pywindow_check(op) PyObject_TypeCheck(op, &PyWindowType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/ignore-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _IGNORE_OBJECT_H_ 2 | #define _IGNORE_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _IGNORE_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssiFinal_HEAD(struct _IGNORE_REC) 13 | } PyIgnore; 14 | 15 | extern PyTypeObject PyIgnoreType; 16 | 17 | int ignore_object_init(void); 18 | PyObject *pyignore_new(void *ignore); 19 | #define pyignore_check(op) PyObject_TypeCheck(op, &PyIgnoreType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/dcc-chat-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _DCC_CHAT_OBJECT_H_ 2 | #define _DCC_CHAT_OBJECT_H_ 3 | 4 | #include 5 | #include "dcc-object.h" 6 | 7 | /* forward */ 8 | struct CHAT_DCC_REC; 9 | 10 | typedef struct 11 | { 12 | PyDcc_HEAD(struct CHAT_DCC_REC) 13 | } PyDccChat; 14 | 15 | extern PyTypeObject PyDccChatType; 16 | 17 | PyObject *pydcc_chat_new(void *dcc); 18 | #define pydcc_chat_check(op) PyObject_TypeCheck(op, &PyDccChatType) 19 | int dcc_chat_object_init(void); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/netsplit-server-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _NETSPLIT_SERVER_OBJECT_H_ 2 | #define _NETSPLIT_SERVER_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyIrssiFinal_HEAD(void) 10 | } PyNetsplitServer; 11 | 12 | extern PyTypeObject PyNetsplitServerType; 13 | 14 | int netsplit_server_object_init(void); 15 | PyObject *pynetsplit_server_new(void *nss); 16 | #define pynetsplit_server_check(op) PyObject_TypeCheck(op, &PyNetsplitServerType) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/objects/logitem-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOG_ITEM_OBJECT_H_ 2 | #define _LOG_ITEM_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyObject_HEAD 10 | PyObject *type; 11 | PyObject *name; 12 | PyObject *servertag; 13 | } PyLogitem; 14 | 15 | extern PyTypeObject PyLogitemType; 16 | 17 | int logitem_object_init(void); 18 | PyObject *pylogitem_new(void *log); 19 | #define pylogitem_check(op) PyObject_TypeCheck(op, &PyLogitemType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/rawlog-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _RAWLOG_OBJECT_H_ 2 | #define _RAWLOG_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _RAWLOG_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssiFinal_HEAD(struct _RAWLOG_REC) 13 | int owned; 14 | } PyRawlog; 15 | 16 | extern PyTypeObject PyRawlogType; 17 | 18 | int rawlog_object_init(void); 19 | PyObject *pyrawlog_new(void *rlog); 20 | #define pyrawlog_check(op) PyObject_TypeCheck(op, &PyRawlogType) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/objects/irc-server-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _IRC_SERVER_OBJECT_H_ 2 | #define _IRC_SERVER_OBJECT_H_ 3 | 4 | #include 5 | #include "server-object.h" 6 | 7 | /* forward */ 8 | struct _IRC_SERVER_REC; 9 | 10 | typedef struct 11 | { 12 | PyServer_HEAD(struct _IRC_SERVER_REC) 13 | } PyIrcServer; 14 | 15 | extern PyTypeObject PyIrcServerType; 16 | 17 | int irc_server_object_init(void); 18 | PyObject *pyirc_server_new(void *server); 19 | #define pyirc_server_check(op) PyObject_TypeCheck(op, &PyIrcServerType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/main-window-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAIN_WINDOW_OBJECT_H_ 2 | #define _MAIN_WINDOW_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | #include "pyirssi.h" 7 | 8 | typedef struct 9 | { 10 | PyIrssiFinal_HEAD(void) 11 | PyObject *active; 12 | } PyMainWindow; 13 | 14 | extern PyTypeObject PyMainWindowType; 15 | 16 | int main_window_object_init(void); 17 | PyObject *pymain_window_new(MAIN_WINDOW_REC *mw); 18 | #define pymain_window_check(op) PyObject_TypeCheck(op, &PyMainWindowType) 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/objects/nick-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _NICK_OBJECT_H_ 2 | #define _NICK_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _NICK_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssi_HEAD(struct _NICK_REC) 13 | } PyNick; 14 | 15 | extern PyTypeObject PyNickType; 16 | 17 | int nick_object_init(void); 18 | PyObject *pynick_sub_new(void *nick, PyTypeObject *subclass); 19 | PyObject *pynick_new(void *nick); 20 | #define pynick_check(op) PyObject_TypeCheck(op, &PyNickType) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/objects/process-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROCESS_OBJECT_H_ 2 | #define _PROCESS_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct PROCESS_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssiFinal_HEAD(struct PROCESS_REC) 13 | PyObject *target_win; 14 | } PyProcess; 15 | 16 | extern PyTypeObject PyProcessType; 17 | 18 | int process_object_init(void); 19 | PyObject *pyprocess_new(void *process); 20 | #define pyprocess_check(op) PyObject_TypeCheck(op, &PyProcessType) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/objects/irc-channel-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _IRC_CHANNEL_OBJECT_H_ 2 | #define _IRC_CHANNEL_OBJECT_H_ 3 | 4 | #include 5 | #include "window-item-object.h" 6 | 7 | /* forward */ 8 | struct _IRC_CHANNEL_REC; 9 | 10 | typedef struct 11 | { 12 | PyWindowItem_HEAD(struct _IRC_CHANNEL_REC) 13 | } PyIrcChannel; 14 | 15 | extern PyTypeObject PyIrcChannelType; 16 | 17 | int irc_channel_object_init(void); 18 | PyObject *pyirc_channel_new(void *chan); 19 | #define pyirc_channel_check(op) PyObject_TypeCheck(op, &PyIrcChannelType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/chatnet-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHATNET_OBJECT_H_ 2 | #define _CHATNET_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _CHATNET_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssi_HEAD(struct _CHATNET_REC) 13 | } PyChatnet; 14 | 15 | extern PyTypeObject PyChatnetType; 16 | 17 | int chatnet_object_init(void); 18 | PyObject *pychatnet_sub_new(void *cn, PyTypeObject *subclass); 19 | PyObject *pychatnet_new(void *cn); 20 | #define pychatnet_check(op) PyObject_TypeCheck(op, &PyChatnetType) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/objects/irc-connect-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _IRC_CONNECT_OBJECT_H_ 2 | #define _IRC_CONNECT_OBJECT_H_ 3 | 4 | #include 5 | #include "connect-object.h" 6 | 7 | /* forward */ 8 | struct _IRC_SERVER_CONNECT_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssi_HEAD(struct _IRC_SERVER_CONNECT_REC) 13 | } PyIrcConnect; 14 | 15 | extern PyTypeObject PyIrcConnectType; 16 | 17 | int irc_connect_object_init(void); 18 | PyObject *pyirc_connect_new(void *connect, int managed); 19 | #define pyirc_connect_check(op) PyObject_TypeCheck(op, &PyIrcConnectType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/reconnect-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _RECONNECT_OBJECT_H_ 2 | #define _RECONNECT_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /*XXX: no Reconnect cleanup/destroy sig. Maybe value copy the two members? */ 8 | typedef struct 9 | { 10 | PyIrssiFinal_HEAD(void) 11 | PyObject *connect; 12 | } PyReconnect; 13 | 14 | extern PyTypeObject PyReconnectType; 15 | 16 | int reconnect_object_init(void); 17 | PyObject *pyreconnect_new(void *recon); 18 | #define pyreconnect_check(op) PyObject_TypeCheck(op, &PyReconnectType) 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/objects/netsplit-channel-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _NETSPLIT_CHANNEL_OBJECT_H_ 2 | #define _NETSPLIT_CHANNEL_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | typedef struct 8 | { 9 | PyObject_HEAD 10 | PyObject *name; 11 | int op, halfop; 12 | int voice, other; 13 | } PyNetsplitChannel; 14 | 15 | extern PyTypeObject PyNetsplitChannelType; 16 | 17 | int netsplit_channel_object_init(void); 18 | PyObject *pynetsplit_channel_new(void *ns); 19 | #define pynetsplit_channel_check(op) PyObject_TypeCheck(op, &PyNetsplitChannelType) 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/objects/statusbar-item-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _SBAR_ITEM_OBJECT_H_ 2 | #define _SBAR_ITEM_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct SBAR_ITEM_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssiFinal_HEAD(struct SBAR_ITEM_REC) 13 | PyObject *window; 14 | } PyStatusbarItem; 15 | 16 | extern PyTypeObject PyStatusbarItemType; 17 | 18 | int statusbar_item_object_init(void); 19 | PyObject *pystatusbar_item_new(void *sbar_item); 20 | #define pystatusbar_item_check(op) PyObject_TypeCheck(op, &PyStatusbarItemType) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/objects/textdest-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEXTDEST_OBJECT_H_ 2 | #define _TEXTDEST_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _TEXT_DEST_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssiFinal_HEAD(struct _TEXT_DEST_REC) 13 | PyObject *window; 14 | PyObject *server; 15 | int owned; 16 | } PyTextDest; 17 | 18 | extern PyTypeObject PyTextDestType; 19 | 20 | int textdest_object_init(void); 21 | PyObject *pytextdest_new(void *td); 22 | #define pytextdest_check(op) PyObject_TypeCheck(op, &PyTextDestType) 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/objects/channel-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHANNEL_OBJECT_H_ 2 | #define _CHANNEL_OBJECT_H_ 3 | 4 | #include 5 | #include "window-item-object.h" 6 | 7 | /* forward */ 8 | struct _CHANNEL_REC; 9 | 10 | typedef struct 11 | { 12 | PyWindowItem_HEAD(struct _CHANNEL_REC) 13 | } PyChannel; 14 | 15 | extern PyTypeObject PyChannelType; 16 | 17 | int channel_object_init(void); 18 | PyObject *pychannel_sub_new(void *chan, const char *name, PyTypeObject *type); 19 | PyObject *pychannel_new(void *chan); 20 | #define pychannel_check(op) PyObject_TypeCheck(op, &PyChannelType) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/objects/connect-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONNECT_OBJECT_H_ 2 | #define _CONNECT_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _SERVER_CONNECT_REC; 9 | 10 | typedef struct 11 | { 12 | PyIrssi_HEAD(struct _SERVER_CONNECT_REC) 13 | } PyConnect; 14 | 15 | extern PyTypeObject PyConnectType; 16 | 17 | int connect_object_init(void); 18 | PyObject *pyconnect_sub_new(void *connect, PyTypeObject *subtype, int managed); 19 | PyObject *pyconnect_new(void *connect, int managed); 20 | #define pyconnect_check(op) PyObject_TypeCheck(op, &PyConnectType) 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/objects/dcc-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _DCC_OBJECT_H_ 2 | #define _DCC_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | #define PyDcc_HEAD(type) \ 8 | PyIrssi_HEAD(type) \ 9 | PyObject *server; \ 10 | PyObject *chat; 11 | 12 | typedef struct 13 | { 14 | PyDcc_HEAD(void) 15 | } PyDcc; 16 | 17 | extern PyTypeObject PyDccType; 18 | 19 | PyObject *pydcc_sub_new(void *dcc, const char *name, PyTypeObject *subclass); 20 | PyObject *pydcc_new(void *dcc); 21 | #define pydcc_check(op) PyObject_TypeCheck(op, &PyDccType) 22 | int dcc_object_init(void); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/irssi_startup.py: -------------------------------------------------------------------------------- 1 | import sys, imp, __builtin__ 2 | import _irssi 3 | 4 | class Output: 5 | def __init__(self, level): 6 | self.level = level 7 | self.buf = [] 8 | def write(self, text): 9 | if not text: 10 | return 11 | self.buf.append(text) 12 | if '\n' == text[-1]: 13 | text = ''.join(self.buf)[:-1] 14 | for line in text.split('\\n'): 15 | _irssi.active_win().prnt(line, self.level) 16 | self.buf = [] 17 | 18 | sys.stdout = Output(level = _irssi.MSGLEVEL_CLIENTCRAP) 19 | sys.stderr = Output(level = _irssi.MSGLEVEL_CLIENTERROR) 20 | -------------------------------------------------------------------------------- /src/pyloader.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYLOADER_H_ 2 | #define _PYLOADER_H_ 3 | 4 | typedef struct 5 | { 6 | char *name; 7 | char *file; 8 | } PY_LIST_REC; 9 | 10 | void pyloader_add_script_path(const char *path); 11 | int pyloader_load_script_argv(char **argv); 12 | int pyloader_load_script(char *name); 13 | int pyloader_unload_script(const char *name); 14 | PyObject *pyloader_find_script_obj(void); 15 | char *pyloader_find_script_name(void); 16 | 17 | GSList *pyloader_list(void); 18 | void pyloader_list_destroy(GSList **list); 19 | 20 | int pyloader_init(void); 21 | void pyloader_auto_load(void); 22 | void pyloader_deinit(void); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | loafier, 2006-08-14: 2 | first release, test1 3 | 4 | loafier, 2006-08-16: 5 | second release, test2 6 | fixed up links in irssi-python.html 7 | changed intstallation location of docs (irssi/docs/irssi-python.html -> doc/irssi/irssi-python.html) 8 | added online help document ( -> irssi/help/py) 9 | changed name of shared library from libirssi_python.so to libpython.so 10 | 11 | loafier, 2006-08-17: 12 | added a few simple scripts 13 | added settings_add_* wrappers to irssi.py 14 | 15 | loafier, 2006-08-20: 16 | added autoload 17 | changed behavior of load to reload previously loaded scripts 18 | 19 | loafier, 2006-08-21: 20 | test3 21 | 22 | -------------------------------------------------------------------------------- /src/objects/server-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _SERVER_OBJECT_H_ 2 | #define _SERVER_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | /* forward */ 8 | struct _SERVER_REC; 9 | 10 | #define PyServer_HEAD(type) \ 11 | PyIrssi_HEAD(type) \ 12 | PyObject *connect; \ 13 | PyObject *rawlog; 14 | 15 | typedef struct 16 | { 17 | PyServer_HEAD(struct _SERVER_REC) 18 | } PyServer; 19 | 20 | extern PyTypeObject PyServerType; 21 | 22 | int server_object_init(void); 23 | PyObject *pyserver_sub_new(void *server, PyTypeObject *subclass); 24 | PyObject *pyserver_new(void *server); 25 | 26 | #define pyserver_check(op) PyObject_TypeCheck(op, &PyServerType) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/objects/window-item-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _WITEM_OBJECT_H_ 2 | #define _WITEM_OBJECT_H_ 3 | 4 | #include 5 | #include "base-objects.h" 6 | 7 | #define PyWindowItem_HEAD(type) \ 8 | PyIrssi_HEAD(type) \ 9 | PyObject *server; 10 | 11 | /* forward */ 12 | struct _WI_ITEM_REC; 13 | 14 | typedef struct 15 | { 16 | PyWindowItem_HEAD(struct _WI_ITEM_REC) 17 | } PyWindowItem; 18 | 19 | extern PyTypeObject PyWindowItemType; 20 | 21 | int window_item_object_init(void); 22 | PyObject *pywindow_item_sub_new(void *witem, const char *name, PyTypeObject *subclass); 23 | PyObject *pywindow_item_new(void *witem); 24 | #define pywindow_item_check(op) PyObject_TypeCheck(op, &PyWindowItemType) 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /scripts/hello.py: -------------------------------------------------------------------------------- 1 | # type /pyload hello 2 | 3 | import irssi 4 | 5 | # data - contains the parameters for /HELLO 6 | # server - the active server in window 7 | # witem - the active window item (eg. channel, query) 8 | # or None if the window is empty 9 | def cmd_hello(data, server, witem): 10 | if not server or not server.connected: 11 | irssi.prnt("Not connected to server") 12 | 13 | if data: 14 | server.command("MSG %s Hello!" % data) 15 | elif isinstance(witem, irssi.Channel) or isinstance(witem, irssi.Query): 16 | witem.command("MSG %s Hello!" % witem.name) 17 | else: 18 | irssi.prnt("Nick not given, and no active channel/query in window") 19 | 20 | irssi.command_bind('hello', cmd_hello) 21 | -------------------------------------------------------------------------------- /src/pyirssi.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYIRSSI_H_ 2 | #define _PYIRSSI_H_ 3 | 4 | #define MODULE_NAME "python" 5 | #include "config.h" 6 | #include "core.h" 7 | #include "common.h" 8 | #include "modules.h" 9 | #include "commands.h" 10 | #include "settings.h" 11 | #include "printtext.h" 12 | #include "statusbar.h" 13 | #include "mainwindows.h" 14 | #include "window-items.h" 15 | #include "window-activity.h" 16 | #include "levels.h" 17 | #include "servers.h" 18 | #include "chat-protocols.h" 19 | #include "channels.h" 20 | #include "queries.h" 21 | #include "nicklist.h" 22 | #include "chatnets.h" 23 | #include "servers-reconnect.h" 24 | #include "masks.h" 25 | #include "misc.h" 26 | #include "rawlog.h" 27 | #include "log.h" 28 | #include "ignore.h" 29 | #include "fe-exec.h" 30 | #include "pidwait.h" 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | irssi-python test3 2 | 3 | irssi-python embeds Python into an Irssi module, providing most of the 4 | functionality of the Perl wrapper to Python scripts using a similar interface. 5 | Read INSTALL for setup instructions. 6 | 7 | Currently, all of the objects and functions are accessible through the irssi 8 | module. See docs/irssi-python.html for a listing. Basic docs are also available 9 | online in Irssi, as well. Use the /py exec command to send commands to the Python 10 | interpreter while in Irssi. 11 | 12 | This will print help for the Window object: 13 | /py exec import irssi 14 | /py exec help(irssi.Window) 15 | 16 | Other commands: 17 | /py load load a Python script 18 | /py unload unload a Python script 19 | /py list list loaded scripts 20 | 21 | 22 | -------------------------------------------------------------------------------- /scripts/dccmove.py: -------------------------------------------------------------------------------- 1 | """ 2 | Translation of Perl script by Peder Stray 3 | """ 4 | 5 | import irssi 6 | import os 7 | from os import path 8 | import shutil 9 | 10 | def sig_dcc_closed(dcc): 11 | if not isinstance(dcc, irssi.DccGet) or not path.isfile(dcc.file): 12 | return 13 | 14 | dir = path.dirname(dcc.file) 15 | dir = path.join(dir, 'done') 16 | file = path.basename(dcc.file) 17 | 18 | if dcc.transfd < dcc.size: 19 | remain = 0 20 | if dcc.size: 21 | remain = 100 - dcc.transfd / dcc.size * 100 22 | print '%%gDCC aborted %%_%s%%_, %%R%d%%%%%%g remaining%%n' % \ 23 | (file, remain) 24 | return 25 | 26 | if not path.isdir(dir): 27 | os.mkdir(dir, 0755) 28 | 29 | shutil.move(dcc.file, dir) 30 | 31 | print '%%gDCC moved %%_%s%%_ to %%_%s%%_%%n' % (file, dir) 32 | 33 | irssi.signal_add('dcc closed', sig_dcc_closed) 34 | -------------------------------------------------------------------------------- /src/constants.txt: -------------------------------------------------------------------------------- 1 | IO_IN G_IO_IN 2 | IO_OUT G_IO_OUT 3 | IO_PRI G_IO_PRI 4 | IO_ERR G_IO_ERR 5 | IO_HUP G_IO_HUP 6 | IRSSI_GUI_GNOME 7 | IRSSI_GUI_GTK 8 | IRSSI_GUI_KDE 9 | IRSSI_GUI_NONE 10 | IRSSI_GUI_QT 11 | IRSSI_GUI_TEXT 12 | IRC_MASK_DOMAIN 13 | IRC_MASK_HOST 14 | IRC_MASK_NICK 15 | IRC_MASK_USER 16 | MSGLEVEL_ACTIONS 17 | MSGLEVEL_ALL 18 | MSGLEVEL_CLIENTCRAP 19 | MSGLEVEL_CLIENTERROR 20 | MSGLEVEL_CLIENTNOTICE 21 | MSGLEVEL_CRAP 22 | MSGLEVEL_CTCPS 23 | MSGLEVEL_DCC 24 | MSGLEVEL_DCCMSGS 25 | MSGLEVEL_HILIGHT 26 | MSGLEVEL_INVITES 27 | MSGLEVEL_JOINS 28 | MSGLEVEL_KICKS 29 | MSGLEVEL_LASTLOG 30 | MSGLEVEL_MODES 31 | MSGLEVEL_MSGS 32 | MSGLEVEL_NEVER 33 | MSGLEVEL_NICKS 34 | MSGLEVEL_NO_ACT 35 | MSGLEVEL_NOHILIGHT 36 | MSGLEVEL_NOTICES 37 | MSGLEVEL_PARTS 38 | MSGLEVEL_PUBLIC 39 | MSGLEVEL_QUITS 40 | MSGLEVEL_SNOTES 41 | MSGLEVEL_TOPICS 42 | MSGLEVEL_WALLOPS 43 | SIGNAL_PRIORITY_DEFAULT 44 | SIGNAL_PRIORITY_HIGH 45 | SIGNAL_PRIORITY_LOW 46 | -------------------------------------------------------------------------------- /scripts/beep_beep.py: -------------------------------------------------------------------------------- 1 | """ 2 | Translation of Perl script by Georg Lukas 3 | """ 4 | 5 | import irssi 6 | import os 7 | 8 | might_beep = True 9 | 10 | def beep_overflow_timeout(): 11 | global might_beep 12 | might_beep = True 13 | 14 | return False 15 | 16 | def sig_beep(): 17 | global might_beep 18 | 19 | beep_cmd = irssi.settings_get_str('beep_cmd') 20 | if not beep_cmd: 21 | return 22 | 23 | beep_flood = irssi.settings_get_int('beep_flood') 24 | if beep_flood <= 0: 25 | beep_flood = 1000 26 | 27 | if might_beep: 28 | os.system(beep_cmd) 29 | might_beep = False 30 | irssi.timeout_add(beep_flood, beep_overflow_timeout) 31 | 32 | irssi.signal_stop() 33 | 34 | irssi.settings_add_str("lookandfeel", "beep_cmd", "play ~/.irssi/scripts/beep_beep.wav 2>&1 > /dev/null &") 35 | irssi.settings_add_int("lookandfeel", "beep_flood", 250) 36 | irssi.signal_add("beep", sig_beep) 37 | 38 | -------------------------------------------------------------------------------- /src/sig2code.txt: -------------------------------------------------------------------------------- 1 | Conversion codes notes 2 | I = int *arg IN/OUT 3 | G = string GList **arg IN/OUT (list must be reconstructed) 4 | L = list of nicks 5 | 6 | Scalars 7 | s -> char * 8 | u -> ulong * 9 | I -> int * 10 | i -> int 11 | 12 | Lists of things (completion.c and massjoin.c) 13 | G -> GList * of char* 14 | L -> GSList of NICK_RECs 15 | 16 | Chat objects 17 | c -> CHATNET_REC 18 | S -> SERVER_REC 19 | C -> CHANNEL_REC 20 | q -> QUERY_REC 21 | n -> NICK_REC 22 | W -> WI_ITEM_REC 23 | 24 | Irssi objects 25 | d -> DCC_REC 26 | 27 | Other objects 28 | r -> RECONNECT_REC 29 | o -> COMMAND_REC 30 | l -> LOG_REC 31 | a -> RAWLOG_REC 32 | g -> IGNORE_REC 33 | ? -> MODULE_REC 34 | b -> BAN_REC 35 | N -> NETSPLIT_REC 36 | e -> NETSPLIT_SERVER_REC 37 | ? -> AUTOIGNORE_REC 38 | O -> NOTIFYLIST_REC 39 | ? -> THEME_REC 40 | ? -> KEYINFO_REC 41 | p -> PROCESS_REC 42 | t -> TEXT_DEST_REC 43 | w -> WINDOW_REC 44 | 45 | -------------------------------------------------------------------------------- /scripts/df.py: -------------------------------------------------------------------------------- 1 | """ 2 | Translation of script by Jochem Meyers 3 | """ 4 | 5 | import irssi 6 | import os 7 | 8 | output = '' 9 | 10 | def get_disk_info(): 11 | fp = os.popen('/bin/df -h') 12 | lines = fp.readlines() 13 | ret = [] 14 | 15 | #dev, size, used, avail, pct, mnt_on 16 | maxm = irssi.settings_get_int('df_max_mounts') 17 | for line in lines[1:maxm + 1]: 18 | ret.append(line.split()) 19 | 20 | return ret 21 | 22 | def sb_df(item, get_size): 23 | item.default_handler(get_size, '{sb %s}' % output) 24 | 25 | def refresh_df(): 26 | global output 27 | 28 | tmp = [] 29 | for dev, size, used, avail, pct, mnt_on in get_disk_info(): 30 | tmp.append(' [%s: A: %s U%%%%: %s]' % (dev, avail, pct)) 31 | 32 | output = 'DF' + ''.join(tmp) 33 | irssi.statusbar_items_redraw('df') 34 | irssi.timeout_add(irssi.settings_get_int('df_refresh_time') * 1000, refresh_df) 35 | 36 | return False 37 | 38 | irssi.statusbar_item_register('df', func=sb_df) 39 | irssi.settings_add_int('misc', 'df_refresh_time', 60) 40 | irssi.settings_add_int('misc', 'df_max_mounts', 6) 41 | refresh_df() 42 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | moduledir = $(libdir)/irssi/modules 2 | wrappersdir = $(datadir)/irssi/scripts 3 | module_LTLIBRARIES = libpython.la 4 | 5 | libpython_la_DEPENDENCIES = objects/libobjects.la 6 | libpython_la_LIBADD = $(PYTHON_LDFLAGS) objects/libobjects.la 7 | libpython_la_LDFLAGS = -avoid-version 8 | 9 | INCLUDES = $(IRSSI_PYTHON_INCLUDES) \ 10 | -I$(top_srcdir)/src/objects \ 11 | -DSCRIPTDIR=\""$(datadir)/irssi/scripts"\" 12 | 13 | libpython_la_SOURCES = \ 14 | pycore.c \ 15 | pyutils.c \ 16 | pymodule.c \ 17 | pyloader.c \ 18 | pysignals.c\ 19 | pysource.c \ 20 | pythemes.c \ 21 | pystatusbar.c \ 22 | pyconstants.c 23 | 24 | noinst_HEADERS = \ 25 | pyconstants.h \ 26 | pycore.h \ 27 | pyirssi.h \ 28 | pyirssi_irc.h \ 29 | pyloader.h \ 30 | pymodule.h \ 31 | pysigmap.h \ 32 | pysignals.h \ 33 | pysource.h \ 34 | pystatusbar.h \ 35 | pythemes.h \ 36 | pyutils.h 37 | 38 | wrappers_DATA = irssi.py irssi_startup.py 39 | EXTRA_DIST = $(wrappers_DATA) 40 | 41 | SUBDIRS = objects 42 | 43 | signalmap: 44 | awk -f sig2code.awk $(IRSSI_DIST)/docs/signals.txt > pysigmap.h 45 | 46 | constants: 47 | awk -f constants.awk constants.txt > pyconstants.c 48 | -------------------------------------------------------------------------------- /src/sig2code.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "[ \t]*->[ \t]*"; 3 | 4 | #read in codes 5 | while (getline < "sig2code.txt") 6 | { 7 | sub(/^[ \t]*/, ""); 8 | if (NF < 2) 9 | continue; 10 | 11 | #print $1, $2 12 | sigmap[$2] = $1 13 | } 14 | 15 | close("sig2code.txt"); 16 | 17 | FS = "[ \t]*,[ \t]*"; 18 | 19 | print "/* Include in your C module */"; 20 | print "static PY_SIGNAL_SPEC_REC py_sigmap[] = {"; 21 | } 22 | 23 | function match_type(t) 24 | { 25 | for (type in sigmap) 26 | { 27 | if (index(t, type) != 0) 28 | return sigmap[type]; 29 | } 30 | 31 | return "?"; 32 | } 33 | 34 | $1 ~ /^[ \t]*"/ && $1 !~ /"script error"/ { 35 | sub(/^[ \t]*/, ""); 36 | 37 | signal = $1 38 | if (signal ~ /.*$/) 39 | { 40 | varsig = 1; 41 | sub(//, "", signal); 42 | } 43 | else 44 | varsig = 0; 45 | 46 | args = ""; 47 | for (i = 2; i <= NF; i++) 48 | { 49 | args = args""match_type($i); 50 | } 51 | 52 | printf(" {%s, \"%s\", 0, 0, %d},\n", signal, args, varsig); 53 | } 54 | 55 | END { 56 | print " {NULL}" ; 57 | print "};"; 58 | print ""; 59 | print "#define py_sigmap_len() (sizeof(py_sigmap) / sizeof(py_sigmap[0]) - 1)"; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/objects/pyscript-object.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYSCRIPT_OBJECT_H_ 2 | #define _PYSCRIPT_OBJECT_H_ 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | PyObject_HEAD 8 | PyObject *module; /* module object */ 9 | PyObject *argv; /* list of argument strings from the load command */ 10 | PyObject *modules; /* dict of imported modules for script */ 11 | GSList *signals; /* list of bound signals and commands */ 12 | GSList *registered_signals; /* list of signal names registered */ 13 | GSList *sources; /* list of io and timeout sources */ 14 | GSList *settings; /* list of settings from settings_add_*() */ 15 | } PyScript; 16 | 17 | extern PyTypeObject PyScriptType; 18 | 19 | int pyscript_init(void); 20 | PyObject *pyscript_new(PyObject *module, char **argv); 21 | void pyscript_remove_signals(PyObject *script); 22 | void pyscript_remove_sources(PyObject *script); 23 | void pyscript_remove_settings(PyObject *script); 24 | void pyscript_remove_themes(PyObject *script); 25 | void pyscript_remove_statusbars(PyObject *script); 26 | void pyscript_clear_modules(PyObject *script); 27 | void pyscript_cleanup(PyObject *script); 28 | #define pyscript_check(op) PyObject_TypeCheck(op, &PyScriptType) 29 | #define pyscript_get_name(scr) PyModule_GetName(((PyScript*)scr)->module) 30 | #define pyscript_get_filename(scr) PyModule_GetFilename(((PyScript*)scr)->module) 31 | #define pyscript_get_module(scr) (((PyScript*)scr)->module) 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/objects/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_LTLIBRARIES = libobjects.la 2 | 3 | INCLUDES = $(IRSSI_PYTHON_INCLUDES) \ 4 | -I$(top_srcdir)/src 5 | 6 | libobjects_la_SOURCES = \ 7 | pyscript-object.c base-objects.c window-item-object.c channel-object.c \ 8 | query-object.c server-object.c connect-object.c irc-server-object.c \ 9 | irc-connect-object.c irc-channel-object.c ban-object.c nick-object.c \ 10 | chatnet-object.c reconnect-object.c window-object.c textdest-object.c \ 11 | rawlog-object.c log-object.c logitem-object.c ignore-object.c \ 12 | dcc-object.c dcc-chat-object.c dcc-get-object.c dcc-send-object.c \ 13 | netsplit-object.c netsplit-server-object.c netsplit-channel-object.c \ 14 | notifylist-object.c process-object.c command-object.c theme-object.c \ 15 | statusbar-item-object.c main-window-object.c factory.c 16 | 17 | noinst_HEADERS = \ 18 | ban-object.h base-objects.h channel-object.h chatnet-object.h \ 19 | command-object.h connect-object.h dcc-chat-object.h dcc-get-object.h \ 20 | dcc-object.h dcc-send-object.h factory.h ignore-object.h \ 21 | irc-channel-object.h irc-connect-object.h irc-server-object.h logitem-object.h \ 22 | log-object.h main-window-object.h netsplit-channel-object.h netsplit-object.h \ 23 | netsplit-server-object.h nick-object.h notifylist-object.h process-object.h \ 24 | pyscript-object.h query-object.h rawlog-object.h reconnect-object.h \ 25 | server-object.h statusbar-item-object.h textdest-object.h theme-object.h \ 26 | window-item-object.h window-object.h 27 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Prior to building irssi-python, you'll need Python 2.4, glib 2.0, and Irssi 2 | installed. 3 | 4 | 1. Download and unpack the irssi source (ie irssi-0.8.10a.tar.gz) if you haven't 5 | done so already. irssi-python will need access to Irssi's headers. 6 | 7 | 2. Run the configure script, making sure to specify the correct location of 8 | Irssi's distribution with the --with-irssi switch. For example: 9 | 10 | $ configure --with-irssi=~/irssi-0.8.10 11 | 12 | If configure has trouble linking a Python test program due to missing pthread 13 | symbols (occasionally on FreeBSD), try: 14 | 15 | $ LDFLAGS="-pthread" configure --with-irssi= 16 | 17 | Make sure the prefix for irssi-python matches Irssi's (/usr, /usr/local, 18 | etc) so that the module and scripts are installed in the right places. 19 | 20 | 3. As usual, run make. 21 | 22 | 4. make install if OK. libpython.so should be copied to irssi/modules/, 23 | scripts to irssi/scripts/ and irssi-python.html to doc/irssi/. 24 | 25 | 5. You should be able to load the module in Irssi after installing, IE: 26 | 27 | /load python 28 | 29 | If you get missing pthread symbols, you may have to preload the thread safe 30 | C library before running irssi. export LD_PRELOAD=/usr/lib/libc_r.so seems to 31 | work on FreeBSD. 32 | 33 | You may want to load one of the example scripts like hello or fork: 34 | 35 | /py load fork 36 | /forkoff 37 | 38 | Also check out README and docs/irssi-python.html 39 | -------------------------------------------------------------------------------- /src/pysignals.h: -------------------------------------------------------------------------------- 1 | #ifndef _PYSIGNALS_H_ 2 | #define _PYSIGNALS_H_ 3 | #include 4 | 5 | /* forward */ 6 | struct _PY_SIGNAL_SPEC_REC; 7 | 8 | typedef struct _PY_SIGNAL_REC 9 | { 10 | struct _PY_SIGNAL_SPEC_REC *signal; 11 | char *command; /* used for command and variable signal */ 12 | PyObject *handler; 13 | int is_signal; 14 | } PY_SIGNAL_REC; 15 | 16 | typedef enum 17 | { 18 | PSG_COMMAND, 19 | PSG_SIGNAL, 20 | PSG_ALL, 21 | } PSG_TYPE; 22 | 23 | PY_SIGNAL_REC *pysignals_command_bind(const char *cmd, PyObject *func, 24 | const char *category, int priority); 25 | PY_SIGNAL_REC *pysignals_signal_add(const char *signal, PyObject *func, 26 | int priority); 27 | int pysignals_command_bind_list(GSList **list, const char *command, 28 | PyObject *func, const char *category, int priority); 29 | int pysignals_signal_add_list(GSList **list, const char *signal, 30 | PyObject *func, int priority); 31 | void pysignals_command_unbind(PY_SIGNAL_REC *rec); 32 | void pysignals_signal_remove(PY_SIGNAL_REC *rec); 33 | void pysignals_remove_generic(PY_SIGNAL_REC *rec); 34 | int pysignals_remove_search(GSList **siglist, const char *name, 35 | PyObject *func, PSG_TYPE type); 36 | void pysignals_remove_list(GSList *siglist); 37 | int pysignals_emit(const char *signal, PyObject *argtup); 38 | int pysignals_continue(PyObject *argtup); 39 | int pysignals_register(const char *name, const char *arglist); 40 | int pysignals_unregister(const char *name); 41 | void pysignals_init(void); 42 | void pysignals_deinit(void); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /scripts/fork.py: -------------------------------------------------------------------------------- 1 | import irssi 2 | import os 3 | import time 4 | import sys 5 | 6 | child_pid = 0 7 | 8 | def sig_pidwait(pid, status): 9 | if child_pid != pid: 10 | print 'pidwait dont know',pid 11 | return 12 | 13 | if os.WIFSIGNALED(status): 14 | print '%d killed by signal' % pid 15 | elif os.WIFEXITED(status): 16 | print '%d exited(%d)' % (pid, os.WEXITSTATUS(status)) 17 | 18 | irssi.signal_remove('pidwait') 19 | 20 | def read_child(fd, condition, out): 21 | data = os.read(fd, 512) 22 | if not data: 23 | return False 24 | out.write(data) 25 | return True 26 | 27 | def childfunc(): 28 | """ do your stuff """ 29 | for i in xrange(30): 30 | print 'ME CHILD', i 31 | time.sleep(1) 32 | 33 | 34 | def cmd_forkoff(data, server, witem): 35 | global child_pid 36 | 37 | rs, ws = os.pipe() 38 | re, we = os.pipe() 39 | 40 | pid = os.fork() 41 | if pid > 0: 42 | #parent 43 | child_pid = pid 44 | irssi.pidwait_add(pid) 45 | print 'forked off',pid 46 | irssi.signal_add('pidwait', sig_pidwait) 47 | 48 | #redirect child output 49 | irssi.io_add_watch(rs, read_child, sys.stdout) 50 | irssi.io_add_watch(re, read_child, sys.stderr) 51 | 52 | else: 53 | #child 54 | sys.stdout = os.fdopen(ws, 'w', 0) 55 | sys.stderr = os.fdopen(we, 'w', 0) 56 | 57 | childfunc() 58 | 59 | sys.stdout.close() 60 | sys.stderr.close() 61 | os._exit(5) 62 | 63 | irssi.command_bind('forkoff', cmd_forkoff) 64 | -------------------------------------------------------------------------------- /scripts/test_window.py: -------------------------------------------------------------------------------- 1 | import irssi 2 | 3 | win0 = None 4 | win1 = None 5 | 6 | def cmd_wintest(data, server, witem): 7 | act_win = irssi.active_win() 8 | act_server = irssi.active_server() 9 | 10 | print 'active_win', act_win, 'ref', act_win.refnum 11 | print 'active_server', act_server 12 | 13 | items = act_win.items() 14 | print 'win.items()', items 15 | 16 | for i in items: 17 | print i, 'window ref', i.window().refnum, 'window name', i.window().name 18 | 19 | print 20 | print 'all windows' 21 | for i in irssi.windows(): 22 | print 'window refnum', i.refnum, 'window name', i.name 23 | print 24 | 25 | f0 = irssi.window_find_name('melbo') 26 | f1 = irssi.window_find_name('(status)') 27 | print 'irssi.window_find_name(melbo)', f0 28 | print 'irssi.window_find_name(status)', f1 29 | 30 | def cmd_opentest(data, server, witem): 31 | global win0, win1 32 | win0 = irssi.window_create(automatic=True) 33 | print 'window_create(automatic=True) ->', win0 34 | win1 = irssi.window_create(automatic=False) 35 | print 'window_create(automatic=False) ->', win1 36 | 37 | def cmd_closetest(data, server, witem): 38 | print 'destroy win0 && win1' 39 | win0.destroy() 40 | win1.destroy() 41 | 42 | def cmd_postclose(*args): 43 | print 'post-close access' 44 | print win0.items() 45 | print win1.items() 46 | 47 | irssi.command_bind('wintest', cmd_wintest) 48 | irssi.command_bind('closetest', cmd_closetest) 49 | irssi.command_bind('postclose', cmd_postclose) 50 | irssi.command_bind('opentest', cmd_opentest) 51 | -------------------------------------------------------------------------------- /src/irssi.py: -------------------------------------------------------------------------------- 1 | """ 2 | """ 3 | 4 | import sys 5 | import _irssi 6 | from _irssi import * 7 | 8 | def command_bind(*args, **kwargs): 9 | """ see Script.command_bind() """ 10 | get_script().command_bind(*args, **kwargs) 11 | 12 | def command_unbind(*args, **kwargs): 13 | """ see Script.command_unbind() """ 14 | get_script().command_unbind(*args, **kwargs) 15 | 16 | def signal_add(*args, **kwargs): 17 | """ see Script.signal_add() """ 18 | get_script().signal_add(*args, **kwargs) 19 | 20 | def signal_remove(*args, **kwargs): 21 | """ see Script.signal_remove() """ 22 | get_script().signal_remove(*args, **kwargs) 23 | 24 | def timeout_add(*args, **kwargs): 25 | """ see Script.timeout_add() """ 26 | get_script().timeout_add(*args, **kwargs) 27 | 28 | def io_add_watch(*args, **kwargs): 29 | """ see Script.io_add_watch() """ 30 | get_script().io_add_watch(*args, **kwargs) 31 | 32 | def statusbar_item_register(*args, **kwargs): 33 | """ see Script.statusbar_item_register() """ 34 | get_script().statusbar_item_register(*args, **kwargs) 35 | 36 | def settings_add_str(*args, **kwargs): 37 | """ see Script.settings_add_str() """ 38 | get_script().settings_add_str(*args, **kwargs) 39 | 40 | def settings_add_int(*args, **kwargs): 41 | """ see Script.settings_add_int() """ 42 | get_script().settings_add_int(*args, **kwargs) 43 | 44 | def settings_add_bool(*args, **kwargs): 45 | """ see Script.settings_add_bool() """ 46 | get_script().settings_add_bool(*args, **kwargs) 47 | 48 | def settings_add_time(*args, **kwargs): 49 | """ see Script.settings_add_time() """ 50 | get_script().settings_add_time(*args, **kwargs) 51 | 52 | def settings_add_level(*args, **kwargs): 53 | """ see Script.settings_add_level() """ 54 | get_script().settings_add_level(*args, **kwargs) 55 | 56 | def settings_add_size(*args, **kwargs): 57 | """ see Script.settings_add_size() """ 58 | get_script().settings_add_size(*args, **kwargs) 59 | -------------------------------------------------------------------------------- /src/objects/factory.h: -------------------------------------------------------------------------------- 1 | #ifndef _FACTORY_H_ 2 | #define _FACTORY_H_ 3 | 4 | #include 5 | #include "pyscript-object.h" 6 | #include "base-objects.h" 7 | #include "window-item-object.h" 8 | #include "channel-object.h" 9 | #include "query-object.h" 10 | #include "server-object.h" 11 | #include "connect-object.h" 12 | #include "irc-server-object.h" 13 | #include "irc-connect-object.h" 14 | #include "irc-channel-object.h" 15 | #include "ban-object.h" 16 | #include "nick-object.h" 17 | #include "chatnet-object.h" 18 | #include "reconnect-object.h" 19 | #include "window-object.h" 20 | #include "textdest-object.h" 21 | #include "rawlog-object.h" 22 | #include "log-object.h" 23 | #include "logitem-object.h" 24 | #include "ignore-object.h" 25 | #include "dcc-object.h" 26 | #include "dcc-chat-object.h" 27 | #include "dcc-get-object.h" 28 | #include "dcc-send-object.h" 29 | #include "netsplit-object.h" 30 | #include "netsplit-server-object.h" 31 | #include "netsplit-channel-object.h" 32 | #include "notifylist-object.h" 33 | #include "process-object.h" 34 | #include "command-object.h" 35 | #include "theme-object.h" 36 | #include "statusbar-item-object.h" 37 | #include "main-window-object.h" 38 | 39 | int factory_init(void); 40 | void factory_deinit(void); 41 | 42 | /*managed == 1: object invalidates itself 43 | *managed == 0: caller responsible for invalidating object 44 | *XXX: most objects invalidate themselves, ignoring "managed" switch, 45 | * and some are never managed (Reconnect) 46 | */ 47 | 48 | /* For objects with a type member but no chat_type */ 49 | PyObject *py_irssi_new(void *typeobj, int managed); 50 | /* For objects with both type and chat_type members */ 51 | PyObject *py_irssi_chat_new(void *typeobj, int managed); 52 | 53 | typedef PyObject *(*InitFunc)(void *, int); 54 | PyObject *py_irssi_objlist_new(GSList *node, int managed, InitFunc init); 55 | #define py_irssi_chatlist_new(n, m) py_irssi_objlist_new(n, m, py_irssi_chat_new) 56 | #define py_irssi_list_new(n, m) py_irssi_objlist_new(n, m, py_irssi_new) 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /configure.in: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | #AC_PREREQ(2.59) 5 | AC_INIT(irssi-python, test3, loafier@gmail.com) 6 | AC_CONFIG_SRCDIR([src/pyconstants.c]) 7 | AC_CONFIG_HEADER([pyirssi-config.h]) 8 | AM_INIT_AUTOMAKE([irssi-python], [test3]) 9 | AM_DISABLE_STATIC 10 | AM_PROG_LIBTOOL 11 | 12 | # Options 13 | AC_ARG_WITH(irssi, 14 | [ --with-irssi=path/to/distro Specify location of Irssi distribution directory], 15 | irssi_path=$withval, 16 | irssi_path="") 17 | 18 | # Checks for programs. 19 | AC_PROG_CC 20 | AC_PROG_MAKE_SET 21 | 22 | # Checks for libraries. 23 | AC_PYTHON_DEVEL([>= '2.4']) 24 | AM_PATH_GLIB_2_0(2.0.0) 25 | 26 | # Checks for header files. 27 | AC_HEADER_STDC 28 | AC_CHECK_HEADERS([string.h]) 29 | 30 | # Checks for typedefs, structures, and compiler characteristics. 31 | AC_C_CONST 32 | AC_TYPE_SIZE_T 33 | 34 | # Checks for library functions. 35 | AC_TYPE_SIGNAL 36 | AC_CHECK_FUNCS([memset strchr strrchr]) 37 | 38 | #check Irssi path 39 | echo irssi_path = $irssi_path 40 | if test -z $irssi_path; then 41 | AC_MSG_ERROR([Path to Irssi distribution not specified. See --with-irssi option.]) 42 | fi 43 | 44 | # fix relative paths (from modules/icb) 45 | old=`pwd` 46 | irssi_path=`eval cd $irssi_path; pwd` 47 | cd $old 48 | 49 | IRSSI_DIST=$irssi_path 50 | AC_SUBST([IRSSI_DIST]) 51 | IRSSI_PYTHON_INCLUDES="-I${IRSSI_DIST} -I${IRSSI_DIST}/src -I${IRSSI_DIST}/src/fe-common/core \ 52 | -I${IRSSI_DIST}/src/core -I${IRSSI_DIST}/src/fe-text -I${IRSSI_DIST}/src/irc \ 53 | -I${IRSSI_DIST}/src/irc/core -I${IRSSI_DIST}/src/irc/dcc -I${IRSSI_DIST}/src/irc/notifylist \ 54 | ${PYTHON_CPPFLAGS} ${GLIB_CFLAGS}" 55 | 56 | AC_SUBST([IRSSI_PYTHON_INCLUDES]) 57 | 58 | dnl * gcc specific options 59 | if test "x$ac_cv_prog_gcc" = "xyes"; then 60 | CFLAGS="$CFLAGS -Wall -fno-strict-aliasing" 61 | fi 62 | 63 | #AC_CONFIG_FILES([src/Makefile src/objects/Makefile]) 64 | #AC_OUTPUT([Makefile src/Makefile src/objects/Makefile]) 65 | #AC_OUTPUT([Makefile src/Makefile src/objects/Makefile]) 66 | AC_CONFIG_FILES([Makefile scripts/Makefile docs/Makefile src/Makefile src/objects/Makefile]) 67 | AC_OUTPUT 68 | -------------------------------------------------------------------------------- /classes.txt: -------------------------------------------------------------------------------- 1 | Basic types (source): 2 | IrssiObject/ 3 | IrssiChatObject/ 4 | Chatnet/ (core/chatnets.h) 5 | IrcChatnet (irc/core/irc-chatnets.h) 6 | ServerConnect/ (core/servers.h) 7 | IrcServerConnect (irc/core/irc-servers.h) 8 | Server/ (core/servers.h) 9 | IrcServer (irc/core/irc-servers.h) 10 | WindowItem/ (core/window-item*.h) 11 | Channel/ (core/channels.h) 12 | IrcChannel (irc/core/irc-channels.h) 13 | Query/ (core/queries.h) 14 | IrcQuery (irc/core/irc-queries.h NOTE: only one additional method) 15 | Nick/ (core/nick-rec.h) 16 | Dcc/ (irc/dcc/{dcc,dcc-rec}.h) 17 | DccFile/ (irc/dcc/dcc-file.h) 18 | DccGet (irc/dcc/dcc-get.h) 19 | DccSend (irc/dcc/dcc-send.h) 20 | DccServer (irc/dcc/dcc-server.h NOTE: is this needed?) 21 | DccChat (irc/dcc/dcc-chat.h) 22 | 23 | Final Types (source): 24 | Window (fe-common/core/fe-windows.h) 25 | TextDest (fe-common/core/testdest.h) 26 | Reconnect (core/servers-reconnect.h) 27 | Netsplit (irc/core/netsplit.h) 28 | NetsplitServer (irc/core/netsplit.h) 29 | NetsplitChannel (irc/core/netsplit.h) 30 | Notifylist (irc/notifylist/notifylist.h) 31 | Ban (irc/core/modelists.h) 32 | Ignore (core/ignore.h) 33 | Log (core/log.h) 34 | Logitem (core/log.h) 35 | Rawlog (core/rawlog.h) 36 | Masks ** NO STRUCT ** (core/masks.h) 37 | Process (fe-common/core/fe-exec.h NOTE: what about EXEC_WI_REC sub from WI_ITEM?) 38 | -------------------------------------------------------------------------------- /src/pyutils.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi.h" 23 | #include "pyutils.h" 24 | #include "settings.h" 25 | #include "servers.h" 26 | 27 | /* copy paste from perl bindings */ 28 | void py_command(const char *cmd, SERVER_REC *server, WI_ITEM_REC *item) 29 | { 30 | const char *cmdchars; 31 | char *sendcmd = (char *) cmd; 32 | 33 | if (*cmd == '\0') 34 | return; 35 | 36 | cmdchars = settings_get_str("cmdchars"); 37 | if (strchr(cmdchars, *cmd) == NULL) { 38 | /* no command char - let's put it there.. */ 39 | sendcmd = g_strdup_printf("%c%s", *cmdchars, cmd); 40 | } 41 | 42 | signal_emit("send command", 3, sendcmd, server, item); 43 | if (sendcmd != cmd) g_free(sendcmd); 44 | } 45 | 46 | /* return the file extension for a file, or empty string 47 | don't free result */ 48 | char *file_get_ext(const char *file) 49 | { 50 | const char *dot = NULL; 51 | 52 | while (*file) 53 | { 54 | if (*file == '.') 55 | dot = file; 56 | 57 | file++; 58 | } 59 | 60 | if (dot) 61 | return (char *) dot + 1; 62 | 63 | return (char *) file; 64 | } 65 | 66 | int file_has_ext(const char *file, const char *ext) 67 | { 68 | const char *fext = file_get_ext(file); 69 | 70 | return !strcmp(fext, ext); 71 | } 72 | 73 | 74 | /* return whats in the braces -> /path/to/{filename}.py 75 | result must be freed */ 76 | char *file_get_filename(const char *path) 77 | { 78 | const char *begin; 79 | const char *end; 80 | char *name; 81 | size_t len; 82 | 83 | begin = strrchr(path, '/'); 84 | if (!begin) 85 | begin = path; 86 | else 87 | begin++; 88 | 89 | end = strrchr(begin, '.'); 90 | if (end != NULL && end > begin) 91 | len = end - begin; 92 | else 93 | len = strlen(begin); 94 | 95 | name = g_strnfill(len, 0); 96 | 97 | strncpy(name, begin, len); 98 | 99 | return name; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /src/objects/base-objects.h: -------------------------------------------------------------------------------- 1 | #ifndef _BASE_OBJECTS_H_ 2 | #define _BASE_OBJECTS_H_ 3 | 4 | #include 5 | 6 | /* data is a pointer to the underlying Irssi record */ 7 | /* base_name is the type name of the object returned from the type member 8 | it can be SERVER, CHANNEL, QUERY, etc. Note: base_name isn't freed, so 9 | it cannot point to heap memory */ 10 | /* cleanup_installed: 1 = a cleanup signal handler is installed, 0 = not installed */ 11 | #define PyIrssi_HEAD(type) \ 12 | PyObject_HEAD \ 13 | type *data; \ 14 | const char *base_name; \ 15 | int cleanup_installed; 16 | 17 | /* for uninheritable objects without a type id (Ban, Log, etc) */ 18 | #define PyIrssiFinal_HEAD(type) \ 19 | PyObject_HEAD \ 20 | type *data; \ 21 | int cleanup_installed; 22 | 23 | /* to access data from any irssi object */ 24 | typedef struct 25 | { 26 | PyObject_HEAD 27 | void *data; 28 | } PyIrssiObject; 29 | 30 | #define DATA(obj) (obj? ((PyIrssiObject *)obj)->data : NULL) 31 | 32 | /* base for classes with a type */ 33 | typedef struct 34 | { 35 | int type; 36 | } IRSSI_BASE_REC; 37 | 38 | typedef struct 39 | { 40 | PyIrssi_HEAD(IRSSI_BASE_REC) 41 | } PyIrssiBase; 42 | 43 | 44 | /* base for classes with type and a chat type */ 45 | typedef struct 46 | { 47 | int type; 48 | int chat_type; 49 | } IRSSI_CHAT_REC; 50 | 51 | typedef struct 52 | { 53 | PyIrssi_HEAD(IRSSI_CHAT_REC) 54 | } PyIrssiChatBase; 55 | 56 | extern PyTypeObject PyIrssiBaseType; 57 | extern PyTypeObject PyIrssiChatBaseType; 58 | 59 | #define pybase_check(op) PyObject_TypeCheck(op, &PyIrssiBaseType) 60 | #define pychatbase_check(op) PyObject_TypeCheck(op, &PyIrssiChatBaseType) 61 | #define py_instp(tp, to) ((tp *) (to)->tp_alloc(to, 0)) 62 | #define py_inst(tp, to) py_instp(tp, &to) 63 | 64 | int base_objects_init(void); 65 | 66 | #define RET_NULL_IF_INVALID(data) \ 67 | if (data == NULL) \ 68 | return PyErr_Format(PyExc_RuntimeError, "wrapped object is invalid") 69 | 70 | #define RET_N1_IF_INVALID(data) \ 71 | do { \ 72 | if (data == NULL) \ 73 | { \ 74 | PyErr_Format(PyExc_RuntimeError, "wrapped object is invalid"); \ 75 | return -1; \ 76 | } \ 77 | } while (0) 78 | 79 | #define RET_AS_STRING_OR_NONE(str) \ 80 | do { \ 81 | if (str) \ 82 | return PyString_FromString(str); \ 83 | else \ 84 | { \ 85 | Py_INCREF(Py_None); \ 86 | return Py_None; \ 87 | } \ 88 | } while (0) 89 | 90 | 91 | #define RET_AS_STRING_OR_EMPTY(str) return PyString_FromString(str? str : "") 92 | 93 | #define RET_AS_OBJ_OR_NONE(obj) \ 94 | do { \ 95 | PyObject *tmp = obj; \ 96 | if (!tmp) \ 97 | tmp = Py_None; \ 98 | Py_INCREF(tmp); \ 99 | return tmp; \ 100 | } while (0) 101 | 102 | #define INVALID_MEMBER(member) \ 103 | return PyErr_Format(PyExc_RuntimeError, "invalid member id, %d", member) 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /src/objects/irc-connect-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pymodule.h" 23 | #include "base-objects.h" 24 | #include "irc-connect-object.h" 25 | #include "pyirssi_irc.h" 26 | #include "pycore.h" 27 | #include "pyutils.h" 28 | 29 | /* cleanup and deallocation handled by Connect base */ 30 | 31 | /* Getters */ 32 | PyDoc_STRVAR(PyIrcConnect_alternate_nick_doc, 33 | "Alternate nick to use if default nick is taken" 34 | ); 35 | static PyObject *PyIrcConnect_alternate_nick_get(PyIrcConnect *self, void *closure) 36 | { 37 | RET_NULL_IF_INVALID(self->data); 38 | RET_AS_STRING_OR_NONE(self->data->alternate_nick); 39 | } 40 | 41 | /* Get/Set */ 42 | static PyGetSetDef PyIrcConnect_getseters[] = { 43 | {"alternate_nick", (getter)PyIrcConnect_alternate_nick_get, NULL, 44 | PyIrcConnect_alternate_nick_doc, NULL}, 45 | {NULL} 46 | }; 47 | 48 | PyTypeObject PyIrcConnectType = { 49 | PyObject_HEAD_INIT(NULL) 50 | 0, /*ob_size*/ 51 | "irssi.IrcConnect", /*tp_name*/ 52 | sizeof(PyIrcConnect), /*tp_basicsize*/ 53 | 0, /*tp_itemsize*/ 54 | 0, /*tp_dealloc*/ 55 | 0, /*tp_print*/ 56 | 0, /*tp_getattr*/ 57 | 0, /*tp_setattr*/ 58 | 0, /*tp_compare*/ 59 | 0, /*tp_repr*/ 60 | 0, /*tp_as_number*/ 61 | 0, /*tp_as_sequence*/ 62 | 0, /*tp_as_mapping*/ 63 | 0, /*tp_hash */ 64 | 0, /*tp_call*/ 65 | 0, /*tp_str*/ 66 | 0, /*tp_getattro*/ 67 | 0, /*tp_setattro*/ 68 | 0, /*tp_as_buffer*/ 69 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 70 | "PyIrcConnect objects", /* tp_doc */ 71 | 0, /* tp_traverse */ 72 | 0, /* tp_clear */ 73 | 0, /* tp_richcompare */ 74 | 0, /* tp_weaklistoffset */ 75 | 0, /* tp_iter */ 76 | 0, /* tp_iternext */ 77 | 0, /* tp_methods */ 78 | 0, /* tp_members */ 79 | PyIrcConnect_getseters, /* tp_getset */ 80 | &PyConnectType, /* tp_base */ 81 | 0, /* tp_dict */ 82 | 0, /* tp_descr_get */ 83 | 0, /* tp_descr_set */ 84 | 0, /* tp_dictoffset */ 85 | 0, /* tp_init */ 86 | 0, /* tp_alloc */ 87 | 0, /* tp_new */ 88 | }; 89 | 90 | PyObject *pyirc_connect_new(void *connect, int managed) 91 | { 92 | return pyconnect_sub_new(connect, &PyIrcConnectType, managed); 93 | } 94 | 95 | int irc_connect_object_init(void) 96 | { 97 | g_return_val_if_fail(py_module != NULL, 0); 98 | 99 | if (PyType_Ready(&PyIrcConnectType) < 0) 100 | return 0; 101 | 102 | Py_INCREF(&PyIrcConnectType); 103 | PyModule_AddObject(py_module, "IrcConnect", (PyObject *)&PyIrcConnectType); 104 | 105 | return 1; 106 | } 107 | -------------------------------------------------------------------------------- /src/pysource.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi.h" 23 | #include "pysource.h" 24 | 25 | typedef struct _PY_SOURCE_REC 26 | { 27 | int tag; 28 | GSList **tag_list; 29 | int fd; 30 | PyObject *func; 31 | PyObject *data; 32 | } PY_SOURCE_REC; 33 | 34 | static PY_SOURCE_REC *py_source_rec_new(GSList **tag_list, int fd, PyObject *func, PyObject *data) 35 | { 36 | PY_SOURCE_REC *rec; 37 | 38 | rec = g_new0(PY_SOURCE_REC, 1); 39 | rec->tag_list = tag_list; 40 | rec->fd = fd; 41 | rec->func = func; 42 | rec->data = data; 43 | 44 | Py_INCREF(func); 45 | Py_XINCREF(data); 46 | 47 | return rec; 48 | } 49 | 50 | static int py_remove_tag(GSList **list, int handle) 51 | { 52 | GSList *node; 53 | 54 | node = g_slist_find(*list, GINT_TO_POINTER(handle)); 55 | if (!node) 56 | return 0; 57 | 58 | *list = g_slist_delete_link(*list, node); 59 | 60 | return 1; 61 | } 62 | 63 | static void py_source_destroy(PY_SOURCE_REC *rec) 64 | { 65 | g_return_if_fail(py_remove_tag(rec->tag_list, rec->tag) == 1); 66 | Py_DECREF(rec->func); 67 | Py_XDECREF(rec->data); 68 | g_free(rec); 69 | } 70 | 71 | static int py_handle_ret(PyObject *ret) 72 | { 73 | int res; 74 | 75 | if (!ret) 76 | { 77 | PyErr_Print(); 78 | res = FALSE; 79 | } 80 | else 81 | { 82 | res = PyObject_IsTrue(ret); 83 | Py_DECREF(ret); 84 | } 85 | 86 | return res; 87 | } 88 | 89 | static int py_timeout_proxy(PY_SOURCE_REC *rec) 90 | { 91 | PyObject *ret; 92 | 93 | g_return_val_if_fail(rec != NULL, FALSE); 94 | 95 | if (rec->data) 96 | ret = PyObject_CallFunction(rec->func, "O", rec->data); 97 | else 98 | ret = PyObject_CallFunction(rec->func, ""); 99 | 100 | return py_handle_ret(ret); 101 | } 102 | 103 | static int py_io_proxy(GIOChannel *src, GIOCondition condition, PY_SOURCE_REC *rec) 104 | { 105 | PyObject *ret; 106 | 107 | g_return_val_if_fail(rec != NULL, FALSE); 108 | 109 | if (rec->data) 110 | ret = PyObject_CallFunction(rec->func, "iiO", rec->fd, condition, rec->data); 111 | else 112 | ret = PyObject_CallFunction(rec->func, "ii", rec->fd, condition); 113 | 114 | return py_handle_ret(ret); 115 | } 116 | 117 | int pysource_timeout_add_list(GSList **list, int msecs, PyObject *func, PyObject *data) 118 | { 119 | PY_SOURCE_REC *rec; 120 | 121 | g_return_val_if_fail(func != NULL, -1); 122 | 123 | rec = py_source_rec_new(list, -1, func, data); 124 | rec->tag = g_timeout_add_full(G_PRIORITY_DEFAULT, msecs, 125 | (GSourceFunc)py_timeout_proxy, rec, 126 | (GDestroyNotify)py_source_destroy); 127 | 128 | *list = g_slist_append(*list, GINT_TO_POINTER(rec->tag)); 129 | 130 | return rec->tag; 131 | } 132 | 133 | int pysource_io_add_watch_list(GSList **list, int fd, int cond, PyObject *func, PyObject *data) 134 | { 135 | PY_SOURCE_REC *rec; 136 | GIOChannel *channel; 137 | 138 | g_return_val_if_fail(func != NULL, 1); 139 | 140 | rec = py_source_rec_new(list, fd, func, data); 141 | channel = g_io_channel_unix_new(fd); 142 | rec->tag = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, 143 | (GIOFunc)py_io_proxy, rec, 144 | (GDestroyNotify)py_source_destroy); 145 | g_io_channel_unref(channel); 146 | 147 | *list = g_slist_append(*list, GINT_TO_POINTER(rec->tag)); 148 | 149 | return rec->tag; 150 | } 151 | -------------------------------------------------------------------------------- /src/pystatusbar.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include "pystatusbar.h" 22 | #include "pyirssi.h" 23 | #include "factory.h" 24 | 25 | typedef struct 26 | { 27 | char *name; 28 | PyObject *script; 29 | PyObject *handler; 30 | } PY_BAR_ITEM_REC; 31 | 32 | /* Map: item name -> bar item obj */ 33 | static GHashTable *py_bar_items = NULL; 34 | 35 | static void py_add_bar_handler(const char *iname, PyObject *script, PyObject *handler) 36 | { 37 | PY_BAR_ITEM_REC *sitem; 38 | 39 | sitem = g_new0(PY_BAR_ITEM_REC, 1); 40 | sitem->name = g_strdup(iname); 41 | sitem->script = script; 42 | sitem->handler = handler; 43 | Py_INCREF(script); 44 | Py_INCREF(handler); 45 | 46 | g_hash_table_insert(py_bar_items, sitem->name, sitem); 47 | } 48 | 49 | static void py_destroy_handler(PY_BAR_ITEM_REC *sitem) 50 | { 51 | statusbar_item_unregister(sitem->name); 52 | 53 | g_free(sitem->name); /* destroy key */ 54 | Py_DECREF(sitem->script); 55 | Py_DECREF(sitem->handler); 56 | g_free(sitem); 57 | } 58 | 59 | static void py_statusbar_proxy_call(SBAR_ITEM_REC *item, int sizeonly, PY_BAR_ITEM_REC *sitem) 60 | { 61 | PyObject *pybaritem; 62 | PyObject *ret; 63 | 64 | g_return_if_fail(PyCallable_Check(sitem->handler)); 65 | 66 | pybaritem = pystatusbar_item_new(item); 67 | if (!pybaritem) 68 | { 69 | PyErr_Print(); 70 | pystatusbar_item_unregister(sitem->name); 71 | } 72 | 73 | ret = PyObject_CallFunction(sitem->handler, "Oi", pybaritem, sizeonly); 74 | if (!ret) 75 | { 76 | PyErr_Print(); 77 | pystatusbar_item_unregister(sitem->name); 78 | } 79 | else 80 | Py_DECREF(ret); 81 | } 82 | 83 | static void py_statusbar_proxy(SBAR_ITEM_REC *item, int sizeonly) 84 | { 85 | PY_BAR_ITEM_REC *sitem; 86 | 87 | sitem = g_hash_table_lookup(py_bar_items, item->config->name); 88 | if (sitem) 89 | py_statusbar_proxy_call(item, sizeonly, sitem); 90 | else 91 | { 92 | statusbar_item_default_handler(item, sizeonly, NULL, "", TRUE); 93 | g_critical("unknown handler for Python statusbar proxy: %s", item->config->name); 94 | } 95 | } 96 | 97 | void pystatusbar_item_register(PyObject *script, const char *sitem, 98 | const char *value, PyObject *func) 99 | { 100 | if (func) 101 | { 102 | g_return_if_fail(PyCallable_Check(func)); 103 | py_add_bar_handler(sitem, script, func); 104 | } 105 | 106 | statusbar_item_register(sitem, value, func? py_statusbar_proxy : NULL); 107 | } 108 | 109 | /* remove selected status bar item handler */ 110 | void pystatusbar_item_unregister(const char *iname) 111 | { 112 | if (!g_hash_table_remove(py_bar_items, iname)) 113 | statusbar_item_unregister(iname); 114 | } 115 | 116 | /* remove all statusbar item handlers for script */ 117 | /* XXX: Only status bar items registered with a handler are stored in the hash table. 118 | * Items registered with only a value are not stored, so there is no way to unregister 119 | * them when the script is unloaded. 120 | */ 121 | static int py_check_clean(char *key, PY_BAR_ITEM_REC *value, PyObject *script) 122 | { 123 | if (value->script == script) 124 | return 1; 125 | 126 | return 0; 127 | } 128 | 129 | void pystatusbar_cleanup_script(PyObject *script) 130 | { 131 | g_hash_table_foreach_remove(py_bar_items, (GHRFunc)py_check_clean, script); 132 | } 133 | 134 | void pystatusbar_init(void) 135 | { 136 | g_return_if_fail(py_bar_items == NULL); 137 | 138 | /* key is freed by destroy_handler */ 139 | py_bar_items = g_hash_table_new_full(g_str_hash, g_str_equal, 140 | NULL, (GDestroyNotify)py_destroy_handler); 141 | } 142 | 143 | /* XXX: this must be called after cleaning up all the loaded scripts */ 144 | void pystatusbar_deinit(void) 145 | { 146 | g_return_if_fail(py_bar_items != NULL); 147 | g_return_if_fail(g_hash_table_size(py_bar_items) == 0); 148 | 149 | g_hash_table_destroy(py_bar_items); 150 | py_bar_items = NULL; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /src/pycore.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "pyirssi.h" 26 | #include "pycore.h" 27 | #include "pyloader.h" 28 | #include "pymodule.h" 29 | #include "pysignals.h" 30 | #include "pythemes.h" 31 | #include "pystatusbar.h" 32 | #include "pyconstants.h" 33 | #include "factory.h" 34 | 35 | static void cmd_default(const char *data, SERVER_REC *server, void *item) 36 | { 37 | if (!*data) 38 | data = "list"; 39 | 40 | command_runsub("py", data, server, item); 41 | } 42 | 43 | static void cmd_exec(const char *data) 44 | { 45 | PyObject *co; 46 | PyObject *ret; 47 | PyObject *d; 48 | PyObject *m; 49 | char *cmd; 50 | 51 | if (!*data) 52 | cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); 53 | 54 | cmd = g_strconcat(data, "\n", NULL); 55 | 56 | m = PyImport_AddModule("__main__"); 57 | if (!m) 58 | goto error; 59 | 60 | d = PyModule_GetDict(m); 61 | if (!d) 62 | goto error; 63 | 64 | co = Py_CompileString(cmd, "", Py_single_input); 65 | if (!co) 66 | goto error; 67 | 68 | ret = PyEval_EvalCode((PyCodeObject *)co, d, d); 69 | Py_DECREF(co); 70 | Py_XDECREF(ret); 71 | 72 | error: 73 | g_free(cmd); 74 | if (PyErr_Occurred()) 75 | PyErr_Print(); 76 | } 77 | 78 | static void cmd_load(const char *data) 79 | { 80 | char **argv; 81 | 82 | argv = g_strsplit(data, " ", -1); 83 | if (*argv == NULL || **argv == '\0') 84 | { 85 | g_strfreev(argv); 86 | cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); 87 | } 88 | 89 | pyloader_load_script_argv(argv); 90 | g_strfreev(argv); 91 | } 92 | 93 | static void cmd_unload(const char *data) 94 | { 95 | void *free_arg; 96 | char *script; 97 | 98 | if (!cmd_get_params(data, &free_arg, 1, &script)) 99 | return; 100 | 101 | if (*script == '\0') 102 | cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); 103 | 104 | pyloader_unload_script(script); 105 | 106 | cmd_params_free(free_arg); 107 | } 108 | 109 | static void cmd_list() 110 | { 111 | char buf[128]; 112 | GSList *list; 113 | 114 | list = pyloader_list(); 115 | 116 | g_snprintf(buf, sizeof(buf), "%-15s %s", "Name", "File"); 117 | 118 | if (list != NULL) 119 | { 120 | GSList *node; 121 | 122 | printtext_string(NULL, NULL, MSGLEVEL_CLIENTCRAP, buf); 123 | for (node = list; node != NULL; node = node->next) 124 | { 125 | PY_LIST_REC *item = node->data; 126 | g_snprintf(buf, sizeof(buf), "%-15s %s", item->name, item->file); 127 | 128 | printtext_string(NULL, NULL, MSGLEVEL_CLIENTCRAP, buf); 129 | } 130 | } 131 | else 132 | printtext_string(NULL, NULL, MSGLEVEL_CLIENTERROR, "No python scripts are loaded"); 133 | 134 | pyloader_list_destroy(&list); 135 | } 136 | 137 | #if 0 138 | /* why doesn't this get called? */ 139 | static void intr_catch(int sig) 140 | { 141 | printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "got sig %d", sig); 142 | PyErr_SetInterrupt(); 143 | } 144 | #endif 145 | 146 | void python_init(void) 147 | { 148 | Py_InitializeEx(0); 149 | 150 | pysignals_init(); 151 | pystatusbar_init(); 152 | if (!pyloader_init() || !pymodule_init() || !factory_init() || !pythemes_init()) 153 | { 154 | printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Failed to load Python"); 155 | return; 156 | } 157 | pyconstants_init(); 158 | 159 | /*PyImport_ImportModule("irssi_startup");*/ 160 | /* Install the custom output handlers, import hook and reload function */ 161 | /* XXX: handle import error */ 162 | PyRun_SimpleString( 163 | "import irssi_startup\n" 164 | ); 165 | 166 | pyloader_auto_load(); 167 | 168 | /* assert(signal(SIGINT, intr_catch) != SIG_ERR); */ 169 | 170 | command_bind("py", NULL, (SIGNAL_FUNC) cmd_default); 171 | command_bind("py load", NULL, (SIGNAL_FUNC) cmd_load); 172 | command_bind("py unload", NULL, (SIGNAL_FUNC) cmd_unload); 173 | command_bind("py list", NULL, (SIGNAL_FUNC) cmd_list); 174 | command_bind("py exec", NULL, (SIGNAL_FUNC) cmd_exec); 175 | module_register(MODULE_NAME, "core"); 176 | } 177 | 178 | void python_deinit(void) 179 | { 180 | command_unbind("py", (SIGNAL_FUNC) cmd_default); 181 | command_unbind("py load", (SIGNAL_FUNC) cmd_load); 182 | command_unbind("py unload", (SIGNAL_FUNC) cmd_unload); 183 | command_unbind("py list", (SIGNAL_FUNC) cmd_list); 184 | command_unbind("py exec", (SIGNAL_FUNC) cmd_exec); 185 | 186 | pymodule_deinit(); 187 | pyloader_deinit(); 188 | pystatusbar_deinit(); 189 | pysignals_deinit(); 190 | Py_Finalize(); 191 | } 192 | -------------------------------------------------------------------------------- /src/objects/dcc-chat-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "dcc-chat-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | /* inherit destroy and cleanup from DccChat type */ 29 | 30 | /* Getters */ 31 | PyDoc_STRVAR(PyDccChat_id_doc, 32 | "Unique identifier - usually same as nick" 33 | ); 34 | static PyObject *PyDccChat_id_get(PyDccChat *self, void *closure) 35 | { 36 | RET_NULL_IF_INVALID(self->data); 37 | RET_AS_STRING_OR_NONE(self->data->id); 38 | } 39 | 40 | PyDoc_STRVAR(PyDccChat_mirc_ctcp_doc, 41 | "Send CTCPs without the CTCP_MESSAGE prefix" 42 | ); 43 | static PyObject *PyDccChat_mirc_ctcp_get(PyDccChat *self, void *closure) 44 | { 45 | RET_NULL_IF_INVALID(self->data); 46 | return PyBool_FromLong(self->data->mirc_ctcp); 47 | } 48 | 49 | PyDoc_STRVAR(PyDccChat_connection_lost_doc, 50 | "Other side closed connection" 51 | ); 52 | static PyObject *PyDccChat_connection_lost_get(PyDccChat *self, void *closure) 53 | { 54 | RET_NULL_IF_INVALID(self->data); 55 | return PyBool_FromLong(self->data->connection_lost); 56 | } 57 | 58 | /* specialized getters/setters */ 59 | static PyGetSetDef PyDccChat_getseters[] = { 60 | {"id", (getter)PyDccChat_id_get, NULL, 61 | PyDccChat_id_doc, NULL}, 62 | {"mirc_ctcp", (getter)PyDccChat_mirc_ctcp_get, NULL, 63 | PyDccChat_mirc_ctcp_doc, NULL}, 64 | {"connection_lost", (getter)PyDccChat_connection_lost_get, NULL, 65 | PyDccChat_connection_lost_doc, NULL}, 66 | {NULL} 67 | }; 68 | 69 | /* Methods */ 70 | PyDoc_STRVAR(PyDccChat_chat_send_doc, 71 | "chat_send(data) -> None\n" 72 | "\n" 73 | "Send data to a dcc chat session.\n" 74 | ); 75 | static PyObject *PyDccChat_chat_send(PyDccChat *self, PyObject *args, PyObject *kwds) 76 | { 77 | static char *kwlist[] = {"data", NULL}; 78 | char *data = ""; 79 | 80 | RET_NULL_IF_INVALID(self->data); 81 | 82 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, 83 | &data)) 84 | return NULL; 85 | 86 | dcc_chat_send(self->data, data); 87 | 88 | Py_RETURN_NONE; 89 | } 90 | 91 | /* Methods for object */ 92 | static PyMethodDef PyDccChat_methods[] = { 93 | {"chat_send", (PyCFunction)PyDccChat_chat_send, METH_VARARGS | METH_KEYWORDS, 94 | PyDccChat_chat_send_doc}, 95 | {NULL} /* Sentinel */ 96 | }; 97 | 98 | PyTypeObject PyDccChatType = { 99 | PyObject_HEAD_INIT(NULL) 100 | 0, /*ob_size*/ 101 | "irssi.DccChat", /*tp_name*/ 102 | sizeof(PyDccChat), /*tp_basicsize*/ 103 | 0, /*tp_itemsize*/ 104 | 0, /*tp_dealloc*/ 105 | 0, /*tp_print*/ 106 | 0, /*tp_getattr*/ 107 | 0, /*tp_setattr*/ 108 | 0, /*tp_compare*/ 109 | 0, /*tp_repr*/ 110 | 0, /*tp_as_number*/ 111 | 0, /*tp_as_sequence*/ 112 | 0, /*tp_as_mapping*/ 113 | 0, /*tp_hash */ 114 | 0, /*tp_call*/ 115 | 0, /*tp_str*/ 116 | 0, /*tp_getattro*/ 117 | 0, /*tp_setattro*/ 118 | 0, /*tp_as_buffer*/ 119 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 120 | "PyDccChat objects", /* tp_doc */ 121 | 0, /* tp_traverse */ 122 | 0, /* tp_clear */ 123 | 0, /* tp_richcompare */ 124 | 0, /* tp_weaklistoffset */ 125 | 0, /* tp_iter */ 126 | 0, /* tp_iternext */ 127 | PyDccChat_methods, /* tp_methods */ 128 | 0, /* tp_members */ 129 | PyDccChat_getseters, /* tp_getset */ 130 | &PyDccType, /* tp_base */ 131 | 0, /* tp_dict */ 132 | 0, /* tp_descr_get */ 133 | 0, /* tp_descr_set */ 134 | 0, /* tp_dictoffset */ 135 | 0, /* tp_init */ 136 | 0, /* tp_alloc */ 137 | 0, /* tp_new */ 138 | }; 139 | 140 | PyObject *pydcc_chat_new(void *dcc) 141 | { 142 | static const char *name = "DCC CHAT"; 143 | return pydcc_sub_new(dcc, name, &PyDccChatType); 144 | } 145 | 146 | int dcc_chat_object_init(void) 147 | { 148 | g_return_val_if_fail(py_module != NULL, 0); 149 | 150 | if (PyType_Ready(&PyDccChatType) < 0) 151 | return 0; 152 | 153 | Py_INCREF(&PyDccChatType); 154 | PyModule_AddObject(py_module, "DccChat", (PyObject *)&PyDccChatType); 155 | 156 | return 1; 157 | } 158 | -------------------------------------------------------------------------------- /src/objects/command-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi.h" 23 | #include "pymodule.h" 24 | #include "command-object.h" 25 | #include "pycore.h" 26 | 27 | #define COMMAND(cmd) ((COMMAND_REC *)cmd) 28 | 29 | /* monitor "commandlist remove" signal */ 30 | static void command_cleanup(COMMAND_REC *command) 31 | { 32 | PyCommand *pycommand = signal_get_user_data(); 33 | 34 | if (command == pycommand->data) 35 | { 36 | pycommand->data = NULL; 37 | pycommand->cleanup_installed = 0; 38 | signal_remove_data("commandlist remove", command_cleanup, pycommand); 39 | } 40 | } 41 | 42 | static void PyCommand_dealloc(PyCommand *self) 43 | { 44 | if (self->cleanup_installed) 45 | signal_remove_data("commandlist remove", command_cleanup, self); 46 | 47 | self->ob_type->tp_free((PyObject*)self); 48 | } 49 | 50 | static PyObject *PyCommand_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 51 | { 52 | PyCommand *self; 53 | 54 | self = (PyCommand *)type->tp_alloc(type, 0); 55 | if (!self) 56 | return NULL; 57 | 58 | return (PyObject *)self; 59 | } 60 | 61 | /* Getters */ 62 | PyDoc_STRVAR(PyCommand_cmd_doc, 63 | "Command name" 64 | ); 65 | static PyObject *PyCommand_cmd_get(PyCommand *self, void *closure) 66 | { 67 | RET_NULL_IF_INVALID(self->data); 68 | RET_AS_STRING_OR_NONE(COMMAND(self->data)->cmd); 69 | } 70 | 71 | PyDoc_STRVAR(PyCommand_category_doc, 72 | "Category" 73 | ); 74 | static PyObject *PyCommand_category_get(PyCommand *self, void *closure) 75 | { 76 | RET_NULL_IF_INVALID(self->data); 77 | RET_AS_STRING_OR_NONE(COMMAND(self->data)->category); 78 | } 79 | 80 | /* specialized getters/setters */ 81 | static PyGetSetDef PyCommand_getseters[] = { 82 | {"cmd", (getter)PyCommand_cmd_get, NULL, 83 | PyCommand_cmd_doc, NULL}, 84 | {"category", (getter)PyCommand_category_get, NULL, 85 | PyCommand_category_doc, NULL}, 86 | {NULL} 87 | }; 88 | 89 | /* Methods */ 90 | /* Methods for object */ 91 | static PyMethodDef PyCommand_methods[] = { 92 | {NULL} /* Sentinel */ 93 | }; 94 | 95 | PyTypeObject PyCommandType = { 96 | PyObject_HEAD_INIT(NULL) 97 | 0, /*ob_size*/ 98 | "irssi.Command", /*tp_name*/ 99 | sizeof(PyCommand), /*tp_basicsize*/ 100 | 0, /*tp_itemsize*/ 101 | (destructor)PyCommand_dealloc, /*tp_dealloc*/ 102 | 0, /*tp_print*/ 103 | 0, /*tp_getattr*/ 104 | 0, /*tp_setattr*/ 105 | 0, /*tp_compare*/ 106 | 0, /*tp_repr*/ 107 | 0, /*tp_as_number*/ 108 | 0, /*tp_as_sequence*/ 109 | 0, /*tp_as_mapping*/ 110 | 0, /*tp_hash */ 111 | 0, /*tp_call*/ 112 | 0, /*tp_str*/ 113 | 0, /*tp_getattro*/ 114 | 0, /*tp_setattro*/ 115 | 0, /*tp_as_buffer*/ 116 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 117 | "PyCommand objects", /* tp_doc */ 118 | 0, /* tp_traverse */ 119 | 0, /* tp_clear */ 120 | 0, /* tp_richcompare */ 121 | 0, /* tp_weaklistoffset */ 122 | 0, /* tp_iter */ 123 | 0, /* tp_iternext */ 124 | PyCommand_methods, /* tp_methods */ 125 | 0, /* tp_members */ 126 | PyCommand_getseters, /* tp_getset */ 127 | 0, /* tp_base */ 128 | 0, /* tp_dict */ 129 | 0, /* tp_descr_get */ 130 | 0, /* tp_descr_set */ 131 | 0, /* tp_dictoffset */ 132 | 0, /* tp_init */ 133 | 0, /* tp_alloc */ 134 | PyCommand_new, /* tp_new */ 135 | }; 136 | 137 | 138 | /* command factory function */ 139 | PyObject *pycommand_new(void *command) 140 | { 141 | PyCommand *pycommand; 142 | 143 | pycommand = py_inst(PyCommand, PyCommandType); 144 | if (!pycommand) 145 | return NULL; 146 | 147 | pycommand->data = command; 148 | pycommand->cleanup_installed = 1; 149 | signal_add_last_data("commandlist remove", command_cleanup, pycommand); 150 | 151 | return (PyObject *)pycommand; 152 | } 153 | 154 | int command_object_init(void) 155 | { 156 | g_return_val_if_fail(py_module != NULL, 0); 157 | 158 | if (PyType_Ready(&PyCommandType) < 0) 159 | return 0; 160 | 161 | Py_INCREF(&PyCommandType); 162 | PyModule_AddObject(py_module, "Command", (PyObject *)&PyCommandType); 163 | 164 | return 1; 165 | } 166 | -------------------------------------------------------------------------------- /src/objects/logitem-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "logitem-object.h" 25 | #include "pycore.h" 26 | 27 | /* no special cleanup -- value copy is made */ 28 | 29 | static void PyLogitem_dealloc(PyLogitem *self) 30 | { 31 | Py_XDECREF(self->type); 32 | Py_XDECREF(self->name); 33 | Py_XDECREF(self->servertag); 34 | 35 | self->ob_type->tp_free((PyObject*)self); 36 | } 37 | 38 | static PyObject *PyLogitem_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 39 | { 40 | PyLogitem *self; 41 | 42 | self = (PyLogitem *)type->tp_alloc(type, 0); 43 | if (!self) 44 | return NULL; 45 | 46 | return (PyObject *)self; 47 | } 48 | 49 | /* Getters */ 50 | PyDoc_STRVAR(PyLogitem_type_doc, 51 | "0=target, 1=window refnum" 52 | ); 53 | static PyObject *PyLogitem_type_get(PyLogitem *self, void *closure) 54 | { 55 | RET_AS_OBJ_OR_NONE(self->type); 56 | } 57 | 58 | PyDoc_STRVAR(PyLogitem_name_doc, 59 | "Name" 60 | ); 61 | static PyObject *PyLogitem_name_get(PyLogitem *self, void *closure) 62 | { 63 | RET_AS_OBJ_OR_NONE(self->name); 64 | } 65 | 66 | PyDoc_STRVAR(PyLogitem_servertag_doc, 67 | "Server tag" 68 | ); 69 | static PyObject *PyLogitem_servertag_get(PyLogitem *self, void *closure) 70 | { 71 | RET_AS_OBJ_OR_NONE(self->servertag); 72 | } 73 | 74 | /* specialized getters/setters */ 75 | static PyGetSetDef PyLogitem_getseters[] = { 76 | {"type", (getter)PyLogitem_type_get, NULL, 77 | PyLogitem_type_doc, NULL}, 78 | {"name", (getter)PyLogitem_name_get, NULL, 79 | PyLogitem_name_doc, NULL}, 80 | {"servertag", (getter)PyLogitem_servertag_get, NULL, 81 | PyLogitem_servertag_doc, NULL}, 82 | {NULL} 83 | }; 84 | 85 | /* Methods for object */ 86 | static PyMethodDef PyLogitem_methods[] = { 87 | {NULL} /* Sentinel */ 88 | }; 89 | 90 | PyTypeObject PyLogitemType = { 91 | PyObject_HEAD_INIT(NULL) 92 | 0, /*ob_size*/ 93 | "irssi.Logitem", /*tp_name*/ 94 | sizeof(PyLogitem), /*tp_basicsize*/ 95 | 0, /*tp_itemsize*/ 96 | (destructor)PyLogitem_dealloc, /*tp_dealloc*/ 97 | 0, /*tp_print*/ 98 | 0, /*tp_getattr*/ 99 | 0, /*tp_setattr*/ 100 | 0, /*tp_compare*/ 101 | 0, /*tp_repr*/ 102 | 0, /*tp_as_number*/ 103 | 0, /*tp_as_sequence*/ 104 | 0, /*tp_as_mapping*/ 105 | 0, /*tp_hash */ 106 | 0, /*tp_call*/ 107 | 0, /*tp_str*/ 108 | 0, /*tp_getattro*/ 109 | 0, /*tp_setattro*/ 110 | 0, /*tp_as_buffer*/ 111 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 112 | "PyLogitem objects", /* tp_doc */ 113 | 0, /* tp_traverse */ 114 | 0, /* tp_clear */ 115 | 0, /* tp_richcompare */ 116 | 0, /* tp_weaklistoffset */ 117 | 0, /* tp_iter */ 118 | 0, /* tp_iternext */ 119 | PyLogitem_methods, /* tp_methods */ 120 | 0, /* tp_members */ 121 | PyLogitem_getseters, /* tp_getset */ 122 | 0, /* tp_base */ 123 | 0, /* tp_dict */ 124 | 0, /* tp_descr_get */ 125 | 0, /* tp_descr_set */ 126 | 0, /* tp_dictoffset */ 127 | 0, /* tp_init */ 128 | 0, /* tp_alloc */ 129 | PyLogitem_new, /* tp_new */ 130 | }; 131 | 132 | 133 | /* log item factory function */ 134 | PyObject *pylogitem_new(void *log) 135 | { 136 | LOG_ITEM_REC *li = log; 137 | PyLogitem *pylog = NULL; 138 | 139 | pylog = py_inst(PyLogitem, PyLogitemType); 140 | if (!pylog) 141 | return NULL; 142 | 143 | pylog->type = PyInt_FromLong(li->type); 144 | if (!pylog->type) 145 | goto error; 146 | 147 | pylog->name = PyString_FromString(li->name); 148 | if (!pylog->name) 149 | goto error; 150 | 151 | if (li->servertag) 152 | { 153 | pylog->servertag = PyString_FromString(li->servertag); 154 | if (!pylog->servertag) 155 | goto error; 156 | } 157 | 158 | return (PyObject *)pylog; 159 | 160 | error: 161 | Py_XDECREF(pylog); 162 | return NULL; 163 | } 164 | 165 | int logitem_object_init(void) 166 | { 167 | g_return_val_if_fail(py_module != NULL, 0); 168 | 169 | if (PyType_Ready(&PyLogitemType) < 0) 170 | return 0; 171 | 172 | Py_INCREF(&PyLogitemType); 173 | PyModule_AddObject(py_module, "Logitem", (PyObject *)&PyLogitemType); 174 | 175 | return 1; 176 | } 177 | -------------------------------------------------------------------------------- /src/objects/ban-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "ban-object.h" 25 | #include "pycore.h" 26 | 27 | /* monitor "ban remove" signal */ 28 | static void ban_cleanup(CHANNEL_REC *chan, BAN_REC *ban) 29 | { 30 | PyBan *pyban = signal_get_user_data(); 31 | 32 | if (ban == pyban->data) 33 | { 34 | pyban->data = NULL; 35 | pyban->cleanup_installed = 0; 36 | signal_remove_data("ban remove", ban_cleanup, pyban); 37 | } 38 | } 39 | 40 | static void PyBan_dealloc(PyBan *self) 41 | { 42 | if (self->cleanup_installed) 43 | signal_remove_data("ban remove", ban_cleanup, self); 44 | 45 | self->ob_type->tp_free((PyObject*)self); 46 | } 47 | 48 | static PyObject *PyBan_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 49 | { 50 | PyBan *self; 51 | 52 | self = (PyBan *)type->tp_alloc(type, 0); 53 | if (!self) 54 | return NULL; 55 | 56 | return (PyObject *)self; 57 | } 58 | 59 | PyDoc_STRVAR(PyBan_ban_doc, 60 | "The ban" 61 | ); 62 | static PyObject *PyBan_ban_get(PyBan *self, void *closure) 63 | { 64 | BAN_REC *data = self->data; 65 | RET_NULL_IF_INVALID(self->data); 66 | RET_AS_STRING_OR_NONE(data->ban); 67 | } 68 | 69 | PyDoc_STRVAR(PyBan_setby_doc, 70 | "Nick of who set the ban" 71 | ); 72 | static PyObject *PyBan_setby_get(PyBan *self, void *closure) 73 | { 74 | BAN_REC *data = self->data; 75 | RET_NULL_IF_INVALID(self->data); 76 | RET_AS_STRING_OR_NONE(data->setby); 77 | } 78 | 79 | PyDoc_STRVAR(PyBan_time_doc, 80 | "Timestamp when ban was set" 81 | ); 82 | static PyObject *PyBan_time_get(PyBan *self, void *closure) 83 | { 84 | BAN_REC *data = self->data; 85 | RET_NULL_IF_INVALID(self->data); 86 | return PyLong_FromUnsignedLong(data->time); 87 | } 88 | 89 | /* specialized getters/setters */ 90 | static PyGetSetDef PyBan_getseters[] = { 91 | {"ban", (getter)PyBan_ban_get, NULL, 92 | PyBan_ban_doc, NULL}, 93 | {"setby", (getter)PyBan_setby_get, NULL, 94 | PyBan_setby_doc, NULL}, 95 | {"time", (getter)PyBan_time_get, NULL, 96 | PyBan_time_doc, NULL}, 97 | {NULL} 98 | }; 99 | 100 | /* Methods for object */ 101 | static PyMethodDef PyBan_methods[] = { 102 | {NULL} /* Sentinel */ 103 | }; 104 | 105 | PyTypeObject PyBanType = { 106 | PyObject_HEAD_INIT(NULL) 107 | 0, /*ob_size*/ 108 | "irssi.Ban", /*tp_name*/ 109 | sizeof(PyBan), /*tp_basicsize*/ 110 | 0, /*tp_itemsize*/ 111 | (destructor)PyBan_dealloc, /*tp_dealloc*/ 112 | 0, /*tp_print*/ 113 | 0, /*tp_getattr*/ 114 | 0, /*tp_setattr*/ 115 | 0, /*tp_compare*/ 116 | 0, /*tp_repr*/ 117 | 0, /*tp_as_number*/ 118 | 0, /*tp_as_sequence*/ 119 | 0, /*tp_as_mapping*/ 120 | 0, /*tp_hash */ 121 | 0, /*tp_call*/ 122 | 0, /*tp_str*/ 123 | 0, /*tp_getattro*/ 124 | 0, /*tp_setattro*/ 125 | 0, /*tp_as_buffer*/ 126 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 127 | "PyBan objects", /* tp_doc */ 128 | 0, /* tp_traverse */ 129 | 0, /* tp_clear */ 130 | 0, /* tp_richcompare */ 131 | 0, /* tp_weaklistoffset */ 132 | 0, /* tp_iter */ 133 | 0, /* tp_iternext */ 134 | PyBan_methods, /* tp_methods */ 135 | 0, /* tp_members */ 136 | PyBan_getseters, /* tp_getset */ 137 | 0, /* tp_base */ 138 | 0, /* tp_dict */ 139 | 0, /* tp_descr_get */ 140 | 0, /* tp_descr_set */ 141 | 0, /* tp_dictoffset */ 142 | 0, /* tp_init */ 143 | 0, /* tp_alloc */ 144 | PyBan_new, /* tp_new */ 145 | }; 146 | 147 | 148 | /* window item wrapper factory function */ 149 | PyObject *pyban_new(void *ban) 150 | { 151 | PyBan *pyban; 152 | 153 | pyban = py_inst(PyBan, PyBanType); 154 | if (!pyban) 155 | return NULL; 156 | 157 | pyban->data = ban; 158 | pyban->cleanup_installed = 1; 159 | signal_add_last_data("ban remove", ban_cleanup, pyban); 160 | 161 | return (PyObject *)pyban; 162 | } 163 | 164 | int ban_object_init(void) 165 | { 166 | g_return_val_if_fail(py_module != NULL, 0); 167 | 168 | if (PyType_Ready(&PyBanType) < 0) 169 | return 0; 170 | 171 | Py_INCREF(&PyBanType); 172 | PyModule_AddObject(py_module, "Ban", (PyObject *)&PyBanType); 173 | 174 | return 1; 175 | } 176 | -------------------------------------------------------------------------------- /src/objects/dcc-get-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "dcc-get-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | #define DCC_GET_CAST(rec) ((GET_DCC_REC *)rec) 29 | 30 | /* inherit destroy and cleanup from Dcc type */ 31 | 32 | /* Getters */ 33 | PyDoc_STRVAR(PyDccGet_size_doc, 34 | "File size" 35 | ); 36 | static PyObject *PyDccGet_size_get(PyDccGet *self, void *closure) 37 | { 38 | RET_NULL_IF_INVALID(self->data); 39 | return PyLong_FromUnsignedLong(DCC_GET_CAST(self->data)->size); 40 | } 41 | 42 | PyDoc_STRVAR(PyDccGet_skipped_doc, 43 | "Bytes skipped from start (resuming file)" 44 | ); 45 | static PyObject *PyDccGet_skipped_get(PyDccGet *self, void *closure) 46 | { 47 | RET_NULL_IF_INVALID(self->data); 48 | return PyLong_FromUnsignedLong(DCC_GET_CAST(self->data)->skipped); 49 | } 50 | 51 | PyDoc_STRVAR(PyDccGet_get_type_doc, 52 | "What to do if file exists? 0=default, 1=rename, 2=overwrite, 3=resume" 53 | ); 54 | static PyObject *PyDccGet_get_type_get(PyDccGet *self, void *closure) 55 | { 56 | RET_NULL_IF_INVALID(self->data); 57 | return PyInt_FromLong(DCC_GET_CAST(self->data)->get_type); 58 | } 59 | 60 | PyDoc_STRVAR(PyDccGet_file_doc, 61 | "The real file name which we use." 62 | ); 63 | static PyObject *PyDccGet_file_get(PyDccGet *self, void *closure) 64 | { 65 | RET_NULL_IF_INVALID(self->data); 66 | RET_AS_STRING_OR_NONE(DCC_GET_CAST(self->data)->file); 67 | } 68 | 69 | PyDoc_STRVAR(PyDccGet_file_quoted_doc, 70 | "true if file name was received quoted (\"file name\")" 71 | ); 72 | static PyObject *PyDccGet_file_quoted_get(PyDccGet *self, void *closure) 73 | { 74 | RET_NULL_IF_INVALID(self->data); 75 | return PyBool_FromLong(DCC_GET_CAST(self->data)->file_quoted); 76 | } 77 | 78 | /* specialized getters/setters */ 79 | static PyGetSetDef PyDccGet_getseters[] = { 80 | {"size", (getter)PyDccGet_size_get, NULL, 81 | PyDccGet_size_doc, NULL}, 82 | {"skipped", (getter)PyDccGet_skipped_get, NULL, 83 | PyDccGet_skipped_doc, NULL}, 84 | {"get_type", (getter)PyDccGet_get_type_get, NULL, 85 | PyDccGet_get_type_doc, NULL}, 86 | {"file", (getter)PyDccGet_file_get, NULL, 87 | PyDccGet_file_doc, NULL}, 88 | {"file_quoted", (getter)PyDccGet_file_quoted_get, NULL, 89 | PyDccGet_file_quoted_doc, NULL}, 90 | {NULL} 91 | }; 92 | 93 | /* Methods */ 94 | /* Methods for object */ 95 | static PyMethodDef PyDccGet_methods[] = { 96 | {NULL} /* Sentinel */ 97 | }; 98 | 99 | PyTypeObject PyDccGetType = { 100 | PyObject_HEAD_INIT(NULL) 101 | 0, /*ob_size*/ 102 | "irssi.DccGet", /*tp_name*/ 103 | sizeof(PyDccGet), /*tp_basicsize*/ 104 | 0, /*tp_itemsize*/ 105 | 0, /*tp_dealloc*/ 106 | 0, /*tp_print*/ 107 | 0, /*tp_getattr*/ 108 | 0, /*tp_setattr*/ 109 | 0, /*tp_compare*/ 110 | 0, /*tp_repr*/ 111 | 0, /*tp_as_number*/ 112 | 0, /*tp_as_sequence*/ 113 | 0, /*tp_as_mapping*/ 114 | 0, /*tp_hash */ 115 | 0, /*tp_call*/ 116 | 0, /*tp_str*/ 117 | 0, /*tp_getattro*/ 118 | 0, /*tp_setattro*/ 119 | 0, /*tp_as_buffer*/ 120 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 121 | "PyDccGet objects", /* tp_doc */ 122 | 0, /* tp_traverse */ 123 | 0, /* tp_clear */ 124 | 0, /* tp_richcompare */ 125 | 0, /* tp_weaklistoffset */ 126 | 0, /* tp_iter */ 127 | 0, /* tp_iternext */ 128 | PyDccGet_methods, /* tp_methods */ 129 | 0, /* tp_members */ 130 | PyDccGet_getseters, /* tp_getset */ 131 | &PyDccType, /* tp_base */ 132 | 0, /* tp_dict */ 133 | 0, /* tp_descr_get */ 134 | 0, /* tp_descr_set */ 135 | 0, /* tp_dictoffset */ 136 | 0, /* tp_init */ 137 | 0, /* tp_alloc */ 138 | 0, /* tp_new */ 139 | }; 140 | 141 | PyObject *pydcc_get_new(void *dcc) 142 | { 143 | static const char *name = "DCC GET"; 144 | return pydcc_sub_new(dcc, name, &PyDccGetType); 145 | } 146 | 147 | int dcc_get_object_init(void) 148 | { 149 | g_return_val_if_fail(py_module != NULL, 0); 150 | 151 | if (PyType_Ready(&PyDccGetType) < 0) 152 | return 0; 153 | 154 | Py_INCREF(&PyDccGetType); 155 | PyModule_AddObject(py_module, "DccGet", (PyObject *)&PyDccGetType); 156 | 157 | return 1; 158 | } 159 | -------------------------------------------------------------------------------- /src/objects/dcc-send-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "dcc-send-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | #define DCC_SEND_CAST(rec) ((SEND_DCC_REC *)rec) 29 | 30 | /* inherit destroy and cleanup from Dcc type */ 31 | 32 | /* Getters */ 33 | PyDoc_STRVAR(PyDccSend_size_doc, 34 | "File size" 35 | ); 36 | static PyObject *PyDccSend_size_get(PyDccSend *self, void *closure) 37 | { 38 | RET_NULL_IF_INVALID(self->data); 39 | return PyLong_FromUnsignedLong(DCC_SEND_CAST(self->data)->size); 40 | } 41 | 42 | PyDoc_STRVAR(PyDccSend_skipped_doc, 43 | "Bytes skipped from start (resuming file)" 44 | ); 45 | static PyObject *PyDccSend_skipped_get(PyDccSend *self, void *closure) 46 | { 47 | RET_NULL_IF_INVALID(self->data); 48 | return PyLong_FromUnsignedLong(DCC_SEND_CAST(self->data)->skipped); 49 | } 50 | 51 | PyDoc_STRVAR(PyDccSend_file_quoted_doc, 52 | "True if file name was received quoted (\"file name\")" 53 | ); 54 | static PyObject *PyDccSend_file_quoted_get(PyDccSend *self, void *closure) 55 | { 56 | RET_NULL_IF_INVALID(self->data); 57 | return PyBool_FromLong(DCC_SEND_CAST(self->data)->file_quoted); 58 | } 59 | 60 | PyDoc_STRVAR(PyDccSend_waitforend_doc, 61 | "File is sent, just wait for the replies from the other side" 62 | ); 63 | static PyObject *PyDccSend_waitforend_get(PyDccSend *self, void *closure) 64 | { 65 | RET_NULL_IF_INVALID(self->data); 66 | return PyBool_FromLong(DCC_SEND_CAST(self->data)->waitforend); 67 | } 68 | 69 | PyDoc_STRVAR(PyDccSend_gotalldata_doc, 70 | "Got all acks from the other end" 71 | ); 72 | static PyObject *PyDccSend_gotalldata_get(PyDccSend *self, void *closure) 73 | { 74 | RET_NULL_IF_INVALID(self->data); 75 | return PyBool_FromLong(DCC_SEND_CAST(self->data)->gotalldata); 76 | } 77 | 78 | /* specialized getters/setters */ 79 | static PyGetSetDef PyDccSend_getseters[] = { 80 | {"size", (getter)PyDccSend_size_get, NULL, 81 | PyDccSend_size_doc, NULL}, 82 | {"skipped", (getter)PyDccSend_skipped_get, NULL, 83 | PyDccSend_skipped_doc, NULL}, 84 | {"file_quoted", (getter)PyDccSend_file_quoted_get, NULL, 85 | PyDccSend_file_quoted_doc, NULL}, 86 | {"waitforend", (getter)PyDccSend_waitforend_get, NULL, 87 | PyDccSend_waitforend_doc, NULL}, 88 | {"gotalldata", (getter)PyDccSend_gotalldata_get, NULL, 89 | PyDccSend_gotalldata_doc, NULL}, 90 | {NULL} 91 | }; 92 | 93 | /* Methods */ 94 | /* Methods for object */ 95 | static PyMethodDef PyDccSend_methods[] = { 96 | {NULL} /* Sentinel */ 97 | }; 98 | 99 | PyTypeObject PyDccSendType = { 100 | PyObject_HEAD_INIT(NULL) 101 | 0, /*ob_size*/ 102 | "irssi.DccSend", /*tp_name*/ 103 | sizeof(PyDccSend), /*tp_basicsize*/ 104 | 0, /*tp_itemsize*/ 105 | 0, /*tp_dealloc*/ 106 | 0, /*tp_print*/ 107 | 0, /*tp_getattr*/ 108 | 0, /*tp_setattr*/ 109 | 0, /*tp_compare*/ 110 | 0, /*tp_repr*/ 111 | 0, /*tp_as_number*/ 112 | 0, /*tp_as_sequence*/ 113 | 0, /*tp_as_mapping*/ 114 | 0, /*tp_hash */ 115 | 0, /*tp_call*/ 116 | 0, /*tp_str*/ 117 | 0, /*tp_getattro*/ 118 | 0, /*tp_setattro*/ 119 | 0, /*tp_as_buffer*/ 120 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 121 | "PyDccSend objects", /* tp_doc */ 122 | 0, /* tp_traverse */ 123 | 0, /* tp_clear */ 124 | 0, /* tp_richcompare */ 125 | 0, /* tp_weaklistoffset */ 126 | 0, /* tp_iter */ 127 | 0, /* tp_iternext */ 128 | PyDccSend_methods, /* tp_methods */ 129 | 0, /* tp_members */ 130 | PyDccSend_getseters, /* tp_getset */ 131 | &PyDccType, /* tp_base */ 132 | 0, /* tp_dict */ 133 | 0, /* tp_descr_get */ 134 | 0, /* tp_descr_set */ 135 | 0, /* tp_dictoffset */ 136 | 0, /* tp_init */ 137 | 0, /* tp_alloc */ 138 | 0, /* tp_new */ 139 | }; 140 | 141 | PyObject *pydcc_send_new(void *dcc) 142 | { 143 | static const char *name = "DCC SEND"; 144 | return pydcc_sub_new(dcc, name, &PyDccSendType); 145 | } 146 | 147 | int dcc_send_object_init(void) 148 | { 149 | g_return_val_if_fail(py_module != NULL, 0); 150 | 151 | if (PyType_Ready(&PyDccSendType) < 0) 152 | return 0; 153 | 154 | Py_INCREF(&PyDccSendType); 155 | PyModule_AddObject(py_module, "DccSend", (PyObject *)&PyDccSendType); 156 | 157 | return 1; 158 | } 159 | -------------------------------------------------------------------------------- /src/objects/reconnect-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi.h" 23 | #include "pymodule.h" 24 | #include "pycore.h" 25 | #include "factory.h" 26 | #include "reconnect-object.h" 27 | 28 | /*XXX: no Reconnect cleanup/destroy sig. Maybe value copy the two members? */ 29 | 30 | static void PyReconnect_dealloc(PyReconnect *self) 31 | { 32 | Py_XDECREF(self->connect); 33 | self->ob_type->tp_free((PyObject*)self); 34 | } 35 | 36 | static PyObject *PyReconnect_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 37 | { 38 | PyReconnect *self; 39 | 40 | self = (PyReconnect *)type->tp_alloc(type, 0); 41 | if (!self) 42 | return NULL; 43 | 44 | return (PyObject *)self; 45 | } 46 | 47 | /* Getters */ 48 | PyDoc_STRVAR(PyReconnect_tag_doc, 49 | "Unique numeric tag" 50 | ); 51 | static PyObject *PyReconnect_tag_get(PyReconnect *self, void *closure) 52 | { 53 | RECONNECT_REC *data = self->data; 54 | RET_NULL_IF_INVALID(self->data); 55 | 56 | return PyInt_FromLong(data->tag); 57 | } 58 | 59 | PyDoc_STRVAR(PyReconnect_next_connect_doc, 60 | "Unix time stamp when the next connection occurs" 61 | ); 62 | static PyObject *PyReconnect_next_connect_get(PyReconnect *self, void *closure) 63 | { 64 | RECONNECT_REC *data = self->data; 65 | RET_NULL_IF_INVALID(self->data); 66 | 67 | return PyLong_FromUnsignedLong(data->next_connect); 68 | } 69 | 70 | PyDoc_STRVAR(PyReconnect_connect_doc, 71 | "Connection object" 72 | ); 73 | static PyObject *PyReconnect_connect_get(PyReconnect *self, void *closure) 74 | { 75 | RET_NULL_IF_INVALID(self->data); 76 | RET_AS_OBJ_OR_NONE(self->connect); 77 | } 78 | 79 | /* specialized getters/setters */ 80 | static PyGetSetDef PyReconnect_getseters[] = { 81 | {"tag", (getter)PyReconnect_tag_get, NULL, 82 | PyReconnect_tag_doc, NULL}, 83 | {"next_connect", (getter)PyReconnect_next_connect_get, NULL, 84 | PyReconnect_next_connect_doc, NULL}, 85 | {"connect", (getter)PyReconnect_connect_get, NULL, 86 | PyReconnect_connect_doc, NULL}, 87 | {NULL} 88 | }; 89 | 90 | /* Methods for object */ 91 | static PyMethodDef PyReconnect_methods[] = { 92 | {NULL} /* Sentinel */ 93 | }; 94 | 95 | PyTypeObject PyReconnectType = { 96 | PyObject_HEAD_INIT(NULL) 97 | 0, /*ob_size*/ 98 | "irssi.Reconnect", /*tp_name*/ 99 | sizeof(PyReconnect), /*tp_basicsize*/ 100 | 0, /*tp_itemsize*/ 101 | (destructor)PyReconnect_dealloc, /*tp_dealloc*/ 102 | 0, /*tp_print*/ 103 | 0, /*tp_getattr*/ 104 | 0, /*tp_setattr*/ 105 | 0, /*tp_compare*/ 106 | 0, /*tp_repr*/ 107 | 0, /*tp_as_number*/ 108 | 0, /*tp_as_sequence*/ 109 | 0, /*tp_as_mapping*/ 110 | 0, /*tp_hash */ 111 | 0, /*tp_call*/ 112 | 0, /*tp_str*/ 113 | 0, /*tp_getattro*/ 114 | 0, /*tp_setattro*/ 115 | 0, /*tp_as_buffer*/ 116 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 117 | "PyReconnect objects", /* tp_doc */ 118 | 0, /* tp_traverse */ 119 | 0, /* tp_clear */ 120 | 0, /* tp_richcompare */ 121 | 0, /* tp_weaklistoffset */ 122 | 0, /* tp_iter */ 123 | 0, /* tp_iternext */ 124 | PyReconnect_methods, /* tp_methods */ 125 | 0, /* tp_members */ 126 | PyReconnect_getseters, /* tp_getset */ 127 | 0, /* tp_base */ 128 | 0, /* tp_dict */ 129 | 0, /* tp_descr_get */ 130 | 0, /* tp_descr_set */ 131 | 0, /* tp_dictoffset */ 132 | 0, /* tp_init */ 133 | 0, /* tp_alloc */ 134 | PyReconnect_new, /* tp_new */ 135 | }; 136 | 137 | 138 | /* window item wrapper factory function */ 139 | PyObject *pyreconnect_new(void *recon) 140 | { 141 | RECONNECT_REC *rec = recon; 142 | PyObject *connect; 143 | PyReconnect *pyrecon; 144 | 145 | /* XXX: get a managed connect because there's no signals to manage reconnect */ 146 | connect = py_irssi_chat_new(rec->conn, 1); 147 | if (!connect) 148 | return NULL; 149 | 150 | pyrecon = py_inst(PyReconnect, PyReconnectType); 151 | if (!pyrecon) 152 | return NULL; 153 | 154 | pyrecon->data = recon; 155 | pyrecon->connect = connect; 156 | 157 | return (PyObject *)pyrecon; 158 | } 159 | 160 | int reconnect_object_init(void) 161 | { 162 | g_return_val_if_fail(py_module != NULL, 0); 163 | 164 | if (PyType_Ready(&PyReconnectType) < 0) 165 | return 0; 166 | 167 | Py_INCREF(&PyReconnectType); 168 | PyModule_AddObject(py_module, "Reconnect", (PyObject *)&PyReconnectType); 169 | 170 | return 1; 171 | } 172 | -------------------------------------------------------------------------------- /src/objects/netsplit-server-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "netsplit-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | #define NETSPLIT_SERVER(ns) ((NETSPLIT_SERVER_REC*)ns) 29 | 30 | /* monitor "netsplit remove" signal */ 31 | static void netsplit_server_cleanup(NETSPLIT_SERVER_REC *netsplit) 32 | { 33 | PyNetsplitServer *pynetsplit = signal_get_user_data(); 34 | 35 | if (netsplit == pynetsplit->data) 36 | { 37 | pynetsplit->data = NULL; 38 | pynetsplit->cleanup_installed = 0; 39 | signal_remove_data("netsplit remove", netsplit_server_cleanup, pynetsplit); 40 | } 41 | } 42 | 43 | static void PyNetsplitServer_dealloc(PyNetsplitServer *self) 44 | { 45 | if (self->cleanup_installed) 46 | signal_remove_data("netsplit remove", netsplit_server_cleanup, self); 47 | 48 | self->ob_type->tp_free((PyObject*)self); 49 | } 50 | 51 | static PyObject *PyNetsplitServer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 52 | { 53 | PyNetsplitServer *self; 54 | 55 | self = (PyNetsplitServer *)type->tp_alloc(type, 0); 56 | if (!self) 57 | return NULL; 58 | 59 | return (PyObject *)self; 60 | } 61 | 62 | /* Getters */ 63 | PyDoc_STRVAR(PyNetsplitServer_server_doc, 64 | "The server nick was in" 65 | ); 66 | static PyObject *PyNetsplitServer_server_get(PyNetsplitServer *self, void *closure) 67 | { 68 | RET_NULL_IF_INVALID(self->data); 69 | RET_AS_STRING_OR_NONE(NETSPLIT_SERVER(self->data)->server); 70 | } 71 | 72 | PyDoc_STRVAR(PyNetsplitServer_destserver_doc, 73 | "The other server where split occured." 74 | ); 75 | static PyObject *PyNetsplitServer_destserver_get(PyNetsplitServer *self, void *closure) 76 | { 77 | RET_NULL_IF_INVALID(self->data); 78 | RET_AS_STRING_OR_NONE(NETSPLIT_SERVER(self->data)->destserver); 79 | } 80 | 81 | PyDoc_STRVAR(PyNetsplitServer_count_doc, 82 | "Number of splits in server" 83 | ); 84 | static PyObject *PyNetsplitServer_count_get(PyNetsplitServer *self, void *closure) 85 | { 86 | RET_NULL_IF_INVALID(self->data); 87 | return PyInt_FromLong(NETSPLIT_SERVER(self->data)->count); 88 | } 89 | 90 | /* specialized getters/setters */ 91 | static PyGetSetDef PyNetsplitServer_getseters[] = { 92 | {"server", (getter)PyNetsplitServer_server_get, NULL, 93 | PyNetsplitServer_server_doc, NULL}, 94 | {"destserver", (getter)PyNetsplitServer_destserver_get, NULL, 95 | PyNetsplitServer_destserver_doc, NULL}, 96 | {"count", (getter)PyNetsplitServer_count_get, NULL, 97 | PyNetsplitServer_count_doc, NULL}, 98 | {NULL} 99 | }; 100 | 101 | /* Methods */ 102 | /* Methods for object */ 103 | static PyMethodDef PyNetsplitServer_methods[] = { 104 | {NULL} /* Sentinel */ 105 | }; 106 | 107 | PyTypeObject PyNetsplitServerType = { 108 | PyObject_HEAD_INIT(NULL) 109 | 0, /*ob_size*/ 110 | "irssi.NetsplitServer", /*tp_name*/ 111 | sizeof(PyNetsplitServer), /*tp_basicsize*/ 112 | 0, /*tp_itemsize*/ 113 | (destructor)PyNetsplitServer_dealloc, /*tp_dealloc*/ 114 | 0, /*tp_print*/ 115 | 0, /*tp_getattr*/ 116 | 0, /*tp_setattr*/ 117 | 0, /*tp_compare*/ 118 | 0, /*tp_repr*/ 119 | 0, /*tp_as_number*/ 120 | 0, /*tp_as_sequence*/ 121 | 0, /*tp_as_mapping*/ 122 | 0, /*tp_hash */ 123 | 0, /*tp_call*/ 124 | 0, /*tp_str*/ 125 | 0, /*tp_getattro*/ 126 | 0, /*tp_setattro*/ 127 | 0, /*tp_as_buffer*/ 128 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 129 | "PyNetsplitServer objects", /* tp_doc */ 130 | 0, /* tp_traverse */ 131 | 0, /* tp_clear */ 132 | 0, /* tp_richcompare */ 133 | 0, /* tp_weaklistoffset */ 134 | 0, /* tp_iter */ 135 | 0, /* tp_iternext */ 136 | PyNetsplitServer_methods, /* tp_methods */ 137 | 0, /* tp_members */ 138 | PyNetsplitServer_getseters, /* tp_getset */ 139 | 0, /* tp_base */ 140 | 0, /* tp_dict */ 141 | 0, /* tp_descr_get */ 142 | 0, /* tp_descr_set */ 143 | 0, /* tp_dictoffset */ 144 | 0, /* tp_init */ 145 | 0, /* tp_alloc */ 146 | PyNetsplitServer_new, /* tp_new */ 147 | }; 148 | 149 | 150 | /* window item wrapper factory function */ 151 | PyObject *pynetsplit_server_new(void *nss) 152 | { 153 | PyNetsplitServer *pynss; 154 | 155 | pynss = py_inst(PyNetsplitServer, PyNetsplitServerType); 156 | if (!pynss) 157 | return NULL; 158 | 159 | pynss->data = nss; 160 | pynss->cleanup_installed = 1; 161 | signal_add_last_data("netsplit server remove", netsplit_server_cleanup, pynss); 162 | 163 | return (PyObject *)pynss; 164 | } 165 | 166 | int netsplit_server_object_init(void) 167 | { 168 | g_return_val_if_fail(py_module != NULL, 0); 169 | 170 | if (PyType_Ready(&PyNetsplitServerType) < 0) 171 | return 0; 172 | 173 | Py_INCREF(&PyNetsplitServerType); 174 | PyModule_AddObject(py_module, "NetsplitServer", (PyObject *)&PyNetsplitServerType); 175 | 176 | return 1; 177 | } 178 | -------------------------------------------------------------------------------- /src/objects/netsplit-channel-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "netsplit-channel-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | /* value copied -- no special cleanup */ 29 | 30 | static void PyNetsplitChannel_dealloc(PyNetsplitChannel *self) 31 | { 32 | Py_XDECREF(self->name); 33 | 34 | self->ob_type->tp_free((PyObject*)self); 35 | } 36 | 37 | static PyObject *PyNetsplitChannel_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 38 | { 39 | PyNetsplitChannel *self; 40 | 41 | self = (PyNetsplitChannel *)type->tp_alloc(type, 0); 42 | if (!self) 43 | return NULL; 44 | 45 | return (PyObject *)self; 46 | } 47 | 48 | /* Getters */ 49 | PyDoc_STRVAR(PyNetsplitChannel_name_doc, 50 | "Channel name" 51 | ); 52 | static PyObject *PyNetsplitChannel_name_get(PyNetsplitChannel *self, void *closure) 53 | { 54 | RET_AS_OBJ_OR_NONE(self->name); 55 | } 56 | 57 | PyDoc_STRVAR(PyNetsplitChannel_op_doc, 58 | "is op" 59 | ); 60 | static PyObject *PyNetsplitChannel_op_get(PyNetsplitChannel *self, void *closure) 61 | { 62 | return PyBool_FromLong(self->op); 63 | } 64 | 65 | PyDoc_STRVAR(PyNetsplitChannel_halfop_doc, 66 | "is halfop" 67 | ); 68 | static PyObject *PyNetsplitChannel_halfop_get(PyNetsplitChannel *self, void *closure) 69 | { 70 | return PyBool_FromLong(self->halfop); 71 | } 72 | 73 | PyDoc_STRVAR(PyNetsplitChannel_voice_doc, 74 | "is voice" 75 | ); 76 | static PyObject *PyNetsplitChannel_voice_get(PyNetsplitChannel *self, void *closure) 77 | { 78 | return PyBool_FromLong(self->voice); 79 | } 80 | 81 | PyDoc_STRVAR(PyNetsplitChannel_other_doc, 82 | "?" 83 | ); 84 | static PyObject *PyNetsplitChannel_other_get(PyNetsplitChannel *self, void *closure) 85 | { 86 | return PyInt_FromLong(self->other); 87 | } 88 | 89 | /* specialized getters/setters */ 90 | static PyGetSetDef PyNetsplitChannel_getseters[] = { 91 | {"name", (getter)PyNetsplitChannel_name_get, NULL, 92 | PyNetsplitChannel_name_doc, NULL}, 93 | {"op", (getter)PyNetsplitChannel_op_get, NULL, 94 | PyNetsplitChannel_op_doc, NULL}, 95 | {"halfop", (getter)PyNetsplitChannel_halfop_get, NULL, 96 | PyNetsplitChannel_halfop_doc, NULL}, 97 | {"voice", (getter)PyNetsplitChannel_voice_get, NULL, 98 | PyNetsplitChannel_voice_doc, NULL}, 99 | {"other", (getter)PyNetsplitChannel_other_get, NULL, 100 | PyNetsplitChannel_other_doc, NULL}, 101 | {NULL} 102 | }; 103 | 104 | /* Methods */ 105 | /* Methods for object */ 106 | static PyMethodDef PyNetsplitChannel_methods[] = { 107 | {NULL} /* Sentinel */ 108 | }; 109 | 110 | PyTypeObject PyNetsplitChannelType = { 111 | PyObject_HEAD_INIT(NULL) 112 | 0, /*ob_size*/ 113 | "irssi.NetsplitChannel", /*tp_name*/ 114 | sizeof(PyNetsplitChannel), /*tp_basicsize*/ 115 | 0, /*tp_itemsize*/ 116 | (destructor)PyNetsplitChannel_dealloc, /*tp_dealloc*/ 117 | 0, /*tp_print*/ 118 | 0, /*tp_getattr*/ 119 | 0, /*tp_setattr*/ 120 | 0, /*tp_compare*/ 121 | 0, /*tp_repr*/ 122 | 0, /*tp_as_number*/ 123 | 0, /*tp_as_sequence*/ 124 | 0, /*tp_as_mapping*/ 125 | 0, /*tp_hash */ 126 | 0, /*tp_call*/ 127 | 0, /*tp_str*/ 128 | 0, /*tp_getattro*/ 129 | 0, /*tp_setattro*/ 130 | 0, /*tp_as_buffer*/ 131 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 132 | "PyNetsplitChannel objects", /* tp_doc */ 133 | 0, /* tp_traverse */ 134 | 0, /* tp_clear */ 135 | 0, /* tp_richcompare */ 136 | 0, /* tp_weaklistoffset */ 137 | 0, /* tp_iter */ 138 | 0, /* tp_iternext */ 139 | PyNetsplitChannel_methods, /* tp_methods */ 140 | 0, /* tp_members */ 141 | PyNetsplitChannel_getseters, /* tp_getset */ 142 | 0, /* tp_base */ 143 | 0, /* tp_dict */ 144 | 0, /* tp_descr_get */ 145 | 0, /* tp_descr_set */ 146 | 0, /* tp_dictoffset */ 147 | 0, /* tp_init */ 148 | 0, /* tp_alloc */ 149 | PyNetsplitChannel_new, /* tp_new */ 150 | }; 151 | 152 | 153 | /* window item wrapper factory function */ 154 | PyObject *pynetsplit_channel_new(void *netsplit) 155 | { 156 | NETSPLIT_CHAN_REC *rec = netsplit; 157 | PyNetsplitChannel *pynetsplit; 158 | PyObject *name; 159 | 160 | name = PyString_FromString(rec->name); 161 | if (!name) 162 | return NULL; 163 | 164 | pynetsplit = py_inst(PyNetsplitChannel, PyNetsplitChannelType); 165 | if (!pynetsplit) 166 | { 167 | Py_DECREF(name); 168 | return NULL; 169 | } 170 | 171 | pynetsplit->name = name; 172 | pynetsplit->op = rec->op; 173 | pynetsplit->halfop = rec->halfop; 174 | pynetsplit->other = rec->other; 175 | 176 | return (PyObject *)pynetsplit; 177 | } 178 | 179 | int netsplit_channel_object_init(void) 180 | { 181 | g_return_val_if_fail(py_module != NULL, 0); 182 | 183 | if (PyType_Ready(&PyNetsplitChannelType) < 0) 184 | return 0; 185 | 186 | Py_INCREF(&PyNetsplitChannelType); 187 | PyModule_AddObject(py_module, "NetsplitChannel", (PyObject *)&PyNetsplitChannelType); 188 | 189 | return 1; 190 | } 191 | -------------------------------------------------------------------------------- /src/objects/query-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi.h" 23 | #include "pymodule.h" 24 | #include "base-objects.h" 25 | #include "window-item-object.h" 26 | #include "query-object.h" 27 | #include "server-object.h" 28 | #include "pycore.h" 29 | 30 | /* monitor "query destroyed" signal */ 31 | static void query_cleanup(QUERY_REC *query) 32 | { 33 | PyQuery *pyquery = signal_get_user_data(); 34 | 35 | if (query == pyquery->data) 36 | { 37 | pyquery->data = NULL; 38 | pyquery->cleanup_installed = 0; 39 | signal_remove_data("query destroyed", query_cleanup, pyquery); 40 | } 41 | } 42 | 43 | static void PyQuery_dealloc(PyQuery *self) 44 | { 45 | if (self->cleanup_installed) 46 | signal_remove_data("query destroyed", query_cleanup, self); 47 | 48 | self->ob_type->tp_free((PyObject*)self); 49 | } 50 | 51 | /* Getters */ 52 | PyDoc_STRVAR(PyQuery_address_doc, 53 | "Host address of the queries nick" 54 | ); 55 | static PyObject *PyQuery_address_get(PyQuery *self, void *closure) 56 | { 57 | RET_NULL_IF_INVALID(self->data); 58 | RET_AS_STRING_OR_NONE(self->data->address); 59 | } 60 | 61 | PyDoc_STRVAR(PyQuery_server_tag_doc, 62 | "Server tag used for this nick (doesn't get erased if server gets disconnected)" 63 | ); 64 | static PyObject *PyQuery_server_tag_get(PyQuery *self, void *closure) 65 | { 66 | RET_NULL_IF_INVALID(self->data); 67 | RET_AS_STRING_OR_NONE(self->data->server_tag); 68 | } 69 | 70 | PyDoc_STRVAR(PyQuery_unwanted_doc, 71 | "1 if the other side closed or some error occured (DCC chats)" 72 | ); 73 | static PyObject *PyQuery_unwanted_get(PyQuery *self, void *closure) 74 | { 75 | RET_NULL_IF_INVALID(self->data); 76 | return PyBool_FromLong(self->data->unwanted); 77 | } 78 | 79 | /* specialized getters/setters */ 80 | static PyGetSetDef PyQuery_getseters[] = { 81 | {"address", (getter)PyQuery_address_get, NULL, 82 | PyQuery_address_doc, NULL}, 83 | {"server_tag", (getter)PyQuery_server_tag_get, NULL, 84 | PyQuery_server_tag_doc, NULL}, 85 | {"unwanted", (getter)PyQuery_unwanted_get, NULL, 86 | PyQuery_unwanted_doc, NULL}, 87 | {NULL} 88 | }; 89 | 90 | PyDoc_STRVAR(change_server_doc, 91 | "change_server(server) -> None\n" 92 | "\n" 93 | "Change the active server for the query.\n" 94 | ); 95 | static PyObject *PyQuery_change_server(PyQuery *self, PyObject *args, PyObject *kwds) 96 | { 97 | static char *kwlist[] = {"server", NULL}; 98 | PyObject *server; 99 | 100 | RET_NULL_IF_INVALID(self->data); 101 | 102 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &server)) 103 | return NULL; 104 | 105 | if (!pyserver_check(server)) 106 | return PyErr_Format(PyExc_TypeError, "argument must be server object"); 107 | 108 | query_change_server(self->data, ((PyServer*)server)->data); 109 | 110 | Py_RETURN_NONE; 111 | } 112 | 113 | /* Methods for object */ 114 | static PyMethodDef PyQuery_methods[] = { 115 | {"change_server", (PyCFunction)PyQuery_change_server, METH_VARARGS | METH_KEYWORDS, 116 | change_server_doc}, 117 | 118 | {NULL} /* Sentinel */ 119 | }; 120 | 121 | PyTypeObject PyQueryType = { 122 | PyObject_HEAD_INIT(NULL) 123 | 0, /*ob_size*/ 124 | "irssi.Query", /*tp_name*/ 125 | sizeof(PyQuery), /*tp_basicsize*/ 126 | 0, /*tp_itemsize*/ 127 | (destructor)PyQuery_dealloc, /*tp_dealloc*/ 128 | 0, /*tp_print*/ 129 | 0, /*tp_getattr*/ 130 | 0, /*tp_setattr*/ 131 | 0, /*tp_compare*/ 132 | 0, /*tp_repr*/ 133 | 0, /*tp_as_number*/ 134 | 0, /*tp_as_sequence*/ 135 | 0, /*tp_as_mapping*/ 136 | 0, /*tp_hash */ 137 | 0, /*tp_call*/ 138 | 0, /*tp_str*/ 139 | 0, /*tp_getattro*/ 140 | 0, /*tp_setattro*/ 141 | 0, /*tp_as_buffer*/ 142 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 143 | "PyQuery objects", /* tp_doc */ 144 | 0, /* tp_traverse */ 145 | 0, /* tp_clear */ 146 | 0, /* tp_richcompare */ 147 | 0, /* tp_weaklistoffset */ 148 | 0, /* tp_iter */ 149 | 0, /* tp_iternext */ 150 | PyQuery_methods, /* tp_methods */ 151 | 0, /* tp_members */ 152 | PyQuery_getseters, /* tp_getset */ 153 | &PyWindowItemType, /* tp_base */ 154 | 0, /* tp_dict */ 155 | 0, /* tp_descr_get */ 156 | 0, /* tp_descr_set */ 157 | 0, /* tp_dictoffset */ 158 | 0, /* tp_init */ 159 | 0, /* tp_alloc */ 160 | 0, /* tp_new */ 161 | }; 162 | 163 | 164 | /* query factory function */ 165 | PyObject *pyquery_new(void *query) 166 | { 167 | static const char *BASE_NAME = "QUERY"; 168 | PyObject *pyquery; 169 | 170 | pyquery = pywindow_item_sub_new(query, BASE_NAME, &PyQueryType); 171 | if (pyquery) 172 | { 173 | PyQuery *pyq = (PyQuery *)pyquery; 174 | signal_add_last_data("query destroyed", query_cleanup, pyq); 175 | pyq->cleanup_installed = 1; 176 | } 177 | 178 | return pyquery; 179 | } 180 | 181 | int query_object_init(void) 182 | { 183 | g_return_val_if_fail(py_module != NULL, 0); 184 | 185 | if (PyType_Ready(&PyQueryType) < 0) 186 | return 0; 187 | 188 | Py_INCREF(&PyQueryType); 189 | PyModule_AddObject(py_module, "Query", (PyObject *)&PyQueryType); 190 | 191 | return 1; 192 | } 193 | -------------------------------------------------------------------------------- /src/objects/irc-channel-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "pycore.h" 25 | #include "irc-channel-object.h" 26 | #include "factory.h" 27 | 28 | /* PyIrcChannel destructor is inherited from PyChannel */ 29 | 30 | /* specialized getters/setters */ 31 | static PyGetSetDef PyIrcChannel_getseters[] = { 32 | {NULL} 33 | }; 34 | 35 | /* Methods */ 36 | PyDoc_STRVAR(bans_doc, 37 | "bans() -> list of Ban objects\n" 38 | "\n" 39 | "Returns a list of bans in the channel.\n" 40 | ); 41 | static PyObject *PyIrcChannel_bans(PyIrcChannel *self, PyObject *args) 42 | { 43 | RET_NULL_IF_INVALID(self->data); 44 | 45 | return py_irssi_objlist_new(self->data->banlist, 1, (InitFunc)pyban_new); 46 | } 47 | 48 | PyDoc_STRVAR(ban_get_mask_doc, 49 | "ban_get_mask(nick, ban_type=0) -> str\n" 50 | "\n" 51 | "Get ban mask for 'nick'.\n" 52 | ); 53 | static PyObject *PyIrcChannel_ban_get_mask(PyIrcChannel *self, PyObject *args, PyObject *kwds) 54 | { 55 | static char *kwlist[] = {"nick", "ban_type", NULL}; 56 | char *nick, *str; 57 | int ban_type = 0; 58 | PyObject *ret; 59 | 60 | RET_NULL_IF_INVALID(self->data); 61 | 62 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &nick, &ban_type)) 63 | return NULL; 64 | 65 | str = ban_get_mask(self->data, nick, ban_type); 66 | if (!str) 67 | Py_RETURN_NONE; 68 | 69 | ret = PyString_FromString(str); 70 | g_free(str); 71 | 72 | return ret; 73 | } 74 | 75 | PyDoc_STRVAR(banlist_add_doc, 76 | "banlist_add(ban, nick, time) -> Ban object or None\n" 77 | "\n" 78 | "Add a new ban to channel. Return None if duplicate." 79 | ); 80 | static PyObject *PyIrcChannel_banlist_add(PyIrcChannel *self, PyObject *args, PyObject *kwds) 81 | { 82 | static char *kwlist[] = {"ban", "nick", "time", NULL}; 83 | char *ban, *nick; 84 | time_t btime; 85 | BAN_REC *newban; 86 | 87 | RET_NULL_IF_INVALID(self->data); 88 | 89 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "ssk", kwlist, &ban, &nick, &btime)) 90 | return NULL; 91 | 92 | newban = banlist_add(self->data, ban, nick, btime); 93 | /* XXX: return none or throw error? */ 94 | if (!newban) 95 | Py_RETURN_NONE; 96 | 97 | return pyban_new(newban); 98 | } 99 | 100 | PyDoc_STRVAR(banlist_remove_doc, 101 | "banlist_remove(ban, nick) -> None\n" 102 | "\n" 103 | "Remove a new ban from channel.\n" 104 | ); 105 | static PyObject *PyIrcChannel_banlist_remove(PyIrcChannel *self, PyObject *args, PyObject *kwds) 106 | { 107 | static char *kwlist[] = {"ban", "nick", NULL}; 108 | char *ban, *nick; 109 | 110 | RET_NULL_IF_INVALID(self->data); 111 | 112 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist, &ban, &nick)) 113 | return NULL; 114 | 115 | banlist_remove(self->data, ban, nick); 116 | Py_RETURN_NONE; 117 | } 118 | 119 | /* Methods for object */ 120 | static PyMethodDef PyIrcChannel_methods[] = { 121 | {"bans", (PyCFunction)PyIrcChannel_bans, METH_NOARGS, 122 | bans_doc}, 123 | {"ban_get_mask", (PyCFunction)PyIrcChannel_ban_get_mask, METH_VARARGS | METH_KEYWORDS, 124 | ban_get_mask_doc}, 125 | {"banlist_add", (PyCFunction)PyIrcChannel_banlist_add, METH_VARARGS | METH_KEYWORDS, 126 | banlist_add_doc}, 127 | {"banlist_remove", (PyCFunction)PyIrcChannel_banlist_remove, METH_VARARGS | METH_KEYWORDS, 128 | banlist_remove_doc}, 129 | {NULL} /* Sentinel */ 130 | }; 131 | 132 | PyTypeObject PyIrcChannelType = { 133 | PyObject_HEAD_INIT(NULL) 134 | 0, /*ob_size*/ 135 | "irssi.IrcChannel", /*tp_name*/ 136 | sizeof(PyIrcChannel), /*tp_basicsize*/ 137 | 0, /*tp_itemsize*/ 138 | 0, /*tp_dealloc*/ 139 | 0, /*tp_print*/ 140 | 0, /*tp_getattr*/ 141 | 0, /*tp_setattr*/ 142 | 0, /*tp_compare*/ 143 | 0, /*tp_repr*/ 144 | 0, /*tp_as_number*/ 145 | 0, /*tp_as_sequence*/ 146 | 0, /*tp_as_mapping*/ 147 | 0, /*tp_hash */ 148 | 0, /*tp_call*/ 149 | 0, /*tp_str*/ 150 | 0, /*tp_getattro*/ 151 | 0, /*tp_setattro*/ 152 | 0, /*tp_as_buffer*/ 153 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 154 | "PyIrcChannel objects", /* tp_doc */ 155 | 0, /* tp_traverse */ 156 | 0, /* tp_clear */ 157 | 0, /* tp_richcompare */ 158 | 0, /* tp_weaklistoffset */ 159 | 0, /* tp_iter */ 160 | 0, /* tp_iternext */ 161 | PyIrcChannel_methods, /* tp_methods */ 162 | 0, /* tp_members */ 163 | PyIrcChannel_getseters, /* tp_getset */ 164 | &PyChannelType, /* tp_base */ 165 | 0, /* tp_dict */ 166 | 0, /* tp_descr_get */ 167 | 0, /* tp_descr_set */ 168 | 0, /* tp_dictoffset */ 169 | 0, /* tp_init */ 170 | 0, /* tp_alloc */ 171 | 0, /* tp_new */ 172 | }; 173 | 174 | 175 | /* irc channel factory function */ 176 | PyObject *pyirc_channel_new(void *chan) 177 | { 178 | static const char *BASE_NAME = "CHANNEL"; 179 | return pychannel_sub_new(chan, BASE_NAME, &PyIrcChannelType); 180 | } 181 | 182 | int irc_channel_object_init(void) 183 | { 184 | g_return_val_if_fail(py_module != NULL, 0); 185 | 186 | if (PyType_Ready(&PyIrcChannelType) < 0) 187 | return 0; 188 | 189 | Py_INCREF(&PyIrcChannelType); 190 | PyModule_AddObject(py_module, "IrcChannel", (PyObject *)&PyIrcChannelType); 191 | 192 | return 1; 193 | } 194 | -------------------------------------------------------------------------------- /src/objects/chatnet-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pymodule.h" 23 | #include "base-objects.h" 24 | #include "chatnet-object.h" 25 | #include "pyirssi.h" 26 | #include "pycore.h" 27 | #include "pyutils.h" 28 | 29 | static void chatnet_cleanup(CHATNET_REC *cn) 30 | { 31 | PyChatnet *pycn = signal_get_user_data(); 32 | 33 | if (cn == pycn->data) 34 | { 35 | pycn->data = NULL; 36 | pycn->cleanup_installed = 0; 37 | signal_remove_data("chatnet destroyed", chatnet_cleanup, pycn); 38 | } 39 | } 40 | 41 | static void PyChatnet_dealloc(PyChatnet *self) 42 | { 43 | if (self->cleanup_installed) 44 | signal_remove_data("chatnet destroyed", chatnet_cleanup, self); 45 | 46 | self->ob_type->tp_free((PyObject*)self); 47 | } 48 | 49 | /* Getters */ 50 | PyDoc_STRVAR(PyChatnet_name_doc, 51 | "name of chat network" 52 | ); 53 | static PyObject *PyChatnet_name_get(PyChatnet *self, void *closure) 54 | { 55 | RET_NULL_IF_INVALID(self->data); 56 | RET_AS_STRING_OR_NONE(self->data->name); 57 | } 58 | 59 | PyDoc_STRVAR(PyChatnet_nick_doc, 60 | "if not empty, nick preferred in this network" 61 | ); 62 | static PyObject *PyChatnet_nick_get(PyChatnet *self, void *closure) 63 | { 64 | RET_NULL_IF_INVALID(self->data); 65 | RET_AS_STRING_OR_NONE(self->data->nick); 66 | } 67 | 68 | PyDoc_STRVAR(PyChatnet_username_doc, 69 | "if not empty, username preferred in this network" 70 | ); 71 | static PyObject *PyChatnet_username_get(PyChatnet *self, void *closure) 72 | { 73 | RET_NULL_IF_INVALID(self->data); 74 | RET_AS_STRING_OR_NONE(self->data->username); 75 | } 76 | 77 | PyDoc_STRVAR(PyChatnet_realname_doc, 78 | "if not empty, realname preferred in this network" 79 | ); 80 | static PyObject *PyChatnet_realname_get(PyChatnet *self, void *closure) 81 | { 82 | RET_NULL_IF_INVALID(self->data); 83 | RET_AS_STRING_OR_NONE(self->data->realname); 84 | } 85 | 86 | PyDoc_STRVAR(PyChatnet_own_host_doc, 87 | "address to use when connecting to this network" 88 | ); 89 | static PyObject *PyChatnet_own_host_get(PyChatnet *self, void *closure) 90 | { 91 | RET_NULL_IF_INVALID(self->data); 92 | RET_AS_STRING_OR_NONE(self->data->own_host); 93 | } 94 | 95 | PyDoc_STRVAR(PyChatnet_autosendcmd_doc, 96 | "command to send after connecting to this network" 97 | ); 98 | static PyObject *PyChatnet_autosendcmd_get(PyChatnet *self, void *closure) 99 | { 100 | RET_NULL_IF_INVALID(self->data); 101 | RET_AS_STRING_OR_NONE(self->data->autosendcmd); 102 | } 103 | 104 | /* specialized getters/setters */ 105 | static PyGetSetDef PyChatnet_getseters[] = { 106 | {"name", (getter)PyChatnet_name_get, NULL, 107 | PyChatnet_name_doc, NULL}, 108 | {"nick", (getter)PyChatnet_nick_get, NULL, 109 | PyChatnet_nick_doc, NULL}, 110 | {"username", (getter)PyChatnet_username_get, NULL, 111 | PyChatnet_username_doc, NULL}, 112 | {"realname", (getter)PyChatnet_realname_get, NULL, 113 | PyChatnet_realname_doc, NULL}, 114 | {"own_host", (getter)PyChatnet_own_host_get, NULL, 115 | PyChatnet_own_host_doc, NULL}, 116 | {"autosendcmd", (getter)PyChatnet_autosendcmd_get, NULL, 117 | PyChatnet_autosendcmd_doc, NULL}, 118 | {NULL} 119 | }; 120 | 121 | static PyMethodDef PyChatnet_methods[] = { 122 | {NULL} /* Sentinel */ 123 | }; 124 | 125 | PyTypeObject PyChatnetType = { 126 | PyObject_HEAD_INIT(NULL) 127 | 0, /*ob_size*/ 128 | "irssi.Chatnet", /*tp_name*/ 129 | sizeof(PyChatnet), /*tp_basicsize*/ 130 | 0, /*tp_itemsize*/ 131 | (destructor)PyChatnet_dealloc, /*tp_dealloc*/ 132 | 0, /*tp_print*/ 133 | 0, /*tp_getattr*/ 134 | 0, /*tp_setattr*/ 135 | 0, /*tp_compare*/ 136 | 0, /*tp_repr*/ 137 | 0, /*tp_as_number*/ 138 | 0, /*tp_as_sequence*/ 139 | 0, /*tp_as_mapping*/ 140 | 0, /*tp_hash */ 141 | 0, /*tp_call*/ 142 | 0, /*tp_str*/ 143 | 0, /*tp_getattro*/ 144 | 0, /*tp_setattro*/ 145 | 0, /*tp_as_buffer*/ 146 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 147 | "PyChatnet objects", /* tp_doc */ 148 | 0, /* tp_traverse */ 149 | 0, /* tp_clear */ 150 | 0, /* tp_richcompare */ 151 | 0, /* tp_weaklistoffset */ 152 | 0, /* tp_iter */ 153 | 0, /* tp_iternext */ 154 | PyChatnet_methods, /* tp_methods */ 155 | 0, /* tp_members */ 156 | PyChatnet_getseters, /* tp_getset */ 157 | &PyIrssiChatBaseType, /* tp_base */ 158 | 0, /* tp_dict */ 159 | 0, /* tp_descr_get */ 160 | 0, /* tp_descr_set */ 161 | 0, /* tp_dictoffset */ 162 | 0, /* tp_init */ 163 | 0, /* tp_alloc */ 164 | 0, /* tp_new */ 165 | }; 166 | 167 | 168 | /* chatnet factory function */ 169 | PyObject *pychatnet_sub_new(void *cn, PyTypeObject *subclass) 170 | { 171 | static const char *name = "CHATNET"; 172 | PyChatnet *pycn = NULL; 173 | 174 | pycn = py_instp(PyChatnet, subclass); 175 | if (!pycn) 176 | return NULL; 177 | 178 | pycn->data = cn; 179 | pycn->base_name = name; 180 | signal_add_last_data("chatnet destroyed", chatnet_cleanup, pycn); 181 | pycn->cleanup_installed = 1; 182 | 183 | return (PyObject *)pycn; 184 | } 185 | 186 | PyObject *pychatnet_new(void *cn) 187 | { 188 | return pychatnet_sub_new(cn, &PyChatnetType); 189 | } 190 | 191 | int chatnet_object_init(void) 192 | { 193 | g_return_val_if_fail(py_module != NULL, 0); 194 | 195 | if (PyType_Ready(&PyChatnetType) < 0) 196 | return 0; 197 | 198 | Py_INCREF(&PyChatnetType); 199 | PyModule_AddObject(py_module, "Chatnet", (PyObject *)&PyChatnetType); 200 | 201 | return 1; 202 | } 203 | -------------------------------------------------------------------------------- /src/objects/netsplit-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "netsplit-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | #define NETSPLIT(ns) ((NETSPLIT_REC*)ns) 29 | 30 | /* monitor "netsplit remove" signal */ 31 | static void netsplit_cleanup(NETSPLIT_REC *netsplit) 32 | { 33 | PyNetsplit *pynetsplit = signal_get_user_data(); 34 | 35 | if (netsplit == pynetsplit->data) 36 | { 37 | pynetsplit->data = NULL; 38 | pynetsplit->cleanup_installed = 0; 39 | signal_remove_data("netsplit remove", netsplit_cleanup, pynetsplit); 40 | } 41 | } 42 | 43 | static void PyNetsplit_dealloc(PyNetsplit *self) 44 | { 45 | if (self->cleanup_installed) 46 | signal_remove_data("netsplit remove", netsplit_cleanup, self); 47 | 48 | self->ob_type->tp_free((PyObject*)self); 49 | } 50 | 51 | static PyObject *PyNetsplit_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 52 | { 53 | PyNetsplit *self; 54 | 55 | self = (PyNetsplit *)type->tp_alloc(type, 0); 56 | if (!self) 57 | return NULL; 58 | 59 | return (PyObject *)self; 60 | } 61 | 62 | /* Getters */ 63 | PyDoc_STRVAR(PyNetsplit_nick_doc, 64 | "Nick" 65 | ); 66 | static PyObject *PyNetsplit_nick_get(PyNetsplit *self, void *closure) 67 | { 68 | RET_NULL_IF_INVALID(self->data); 69 | RET_AS_STRING_OR_NONE(NETSPLIT(self->data)->nick); 70 | } 71 | 72 | PyDoc_STRVAR(PyNetsplit_address_doc, 73 | "Nick's host" 74 | ); 75 | static PyObject *PyNetsplit_address_get(PyNetsplit *self, void *closure) 76 | { 77 | RET_NULL_IF_INVALID(self->data); 78 | RET_AS_STRING_OR_NONE(NETSPLIT(self->data)->address); 79 | } 80 | 81 | PyDoc_STRVAR(PyNetsplit_destroy_doc, 82 | "Timestamp when this record should be destroyed" 83 | ); 84 | static PyObject *PyNetsplit_destroy_get(PyNetsplit *self, void *closure) 85 | { 86 | RET_NULL_IF_INVALID(self->data); 87 | return PyLong_FromUnsignedLong(NETSPLIT(self->data)->destroy); 88 | } 89 | 90 | PyDoc_STRVAR(PyNetsplit_server_doc, 91 | "Netsplitserver object" 92 | ); 93 | static PyObject *PyNetsplit_server_get(PyNetsplit *self, void *closure) 94 | { 95 | RET_NULL_IF_INVALID(self->data); 96 | RET_AS_OBJ_OR_NONE(self->server); 97 | } 98 | 99 | /* specialized getters/setters */ 100 | static PyGetSetDef PyNetsplit_getseters[] = { 101 | {"nick", (getter)PyNetsplit_nick_get, NULL, 102 | PyNetsplit_nick_doc, NULL}, 103 | {"address", (getter)PyNetsplit_address_get, NULL, 104 | PyNetsplit_address_doc, NULL}, 105 | {"destroy", (getter)PyNetsplit_destroy_get, NULL, 106 | PyNetsplit_destroy_doc, NULL}, 107 | {"server", (getter)PyNetsplit_server_get, NULL, 108 | PyNetsplit_server_doc, NULL}, 109 | {NULL} 110 | }; 111 | 112 | /* Methods */ 113 | PyDoc_STRVAR(PyNetsplit_channels_doc, 114 | "channels() -> list of NetsplitChannel objects\n" 115 | "\n" 116 | "Return list of NetsplitChannel objects\n" 117 | ); 118 | static PyObject *PyNetsplit_channels(PyNetsplit *self, PyObject *args) 119 | { 120 | RET_NULL_IF_INVALID(self->data); 121 | return py_irssi_objlist_new(NETSPLIT(self->data)->channels, 1, 122 | (InitFunc)pynetsplit_channel_new); 123 | } 124 | 125 | /* Methods for object */ 126 | static PyMethodDef PyNetsplit_methods[] = { 127 | {"channels", (PyCFunction)PyNetsplit_channels, METH_NOARGS, 128 | PyNetsplit_channels_doc}, 129 | {NULL} /* Sentinel */ 130 | }; 131 | 132 | PyTypeObject PyNetsplitType = { 133 | PyObject_HEAD_INIT(NULL) 134 | 0, /*ob_size*/ 135 | "irssi.Netsplit", /*tp_name*/ 136 | sizeof(PyNetsplit), /*tp_basicsize*/ 137 | 0, /*tp_itemsize*/ 138 | (destructor)PyNetsplit_dealloc, /*tp_dealloc*/ 139 | 0, /*tp_print*/ 140 | 0, /*tp_getattr*/ 141 | 0, /*tp_setattr*/ 142 | 0, /*tp_compare*/ 143 | 0, /*tp_repr*/ 144 | 0, /*tp_as_number*/ 145 | 0, /*tp_as_sequence*/ 146 | 0, /*tp_as_mapping*/ 147 | 0, /*tp_hash */ 148 | 0, /*tp_call*/ 149 | 0, /*tp_str*/ 150 | 0, /*tp_getattro*/ 151 | 0, /*tp_setattro*/ 152 | 0, /*tp_as_buffer*/ 153 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 154 | "PyNetsplit objects", /* tp_doc */ 155 | 0, /* tp_traverse */ 156 | 0, /* tp_clear */ 157 | 0, /* tp_richcompare */ 158 | 0, /* tp_weaklistoffset */ 159 | 0, /* tp_iter */ 160 | 0, /* tp_iternext */ 161 | PyNetsplit_methods, /* tp_methods */ 162 | 0, /* tp_members */ 163 | PyNetsplit_getseters, /* tp_getset */ 164 | 0, /* tp_base */ 165 | 0, /* tp_dict */ 166 | 0, /* tp_descr_get */ 167 | 0, /* tp_descr_set */ 168 | 0, /* tp_dictoffset */ 169 | 0, /* tp_init */ 170 | 0, /* tp_alloc */ 171 | PyNetsplit_new, /* tp_new */ 172 | }; 173 | 174 | 175 | /* window item wrapper factory function */ 176 | PyObject *pynetsplit_new(void *netsplit) 177 | { 178 | PyNetsplit *pynetsplit; 179 | 180 | //FIXME: add netsplit server 181 | 182 | pynetsplit = py_inst(PyNetsplit, PyNetsplitType); 183 | if (!pynetsplit) 184 | return NULL; 185 | 186 | pynetsplit->data = netsplit; 187 | pynetsplit->cleanup_installed = 1; 188 | signal_add_last_data("netsplit remove", netsplit_cleanup, pynetsplit); 189 | 190 | return (PyObject *)pynetsplit; 191 | } 192 | 193 | int netsplit_object_init(void) 194 | { 195 | g_return_val_if_fail(py_module != NULL, 0); 196 | 197 | if (PyType_Ready(&PyNetsplitType) < 0) 198 | return 0; 199 | 200 | Py_INCREF(&PyNetsplitType); 201 | PyModule_AddObject(py_module, "Netsplit", (PyObject *)&PyNetsplitType); 202 | 203 | return 1; 204 | } 205 | -------------------------------------------------------------------------------- /scripts/dumper.py: -------------------------------------------------------------------------------- 1 | # type /pyload dumper 2 | 3 | import sys 4 | import irssi 5 | 6 | __script = None 7 | __last_witem = None 8 | __last_server = None 9 | 10 | def cmd_pydumper(data, server, witem): 11 | assert isinstance(server, irssi.Server), "This should be a Server" 12 | assert isinstance(witem, irssi.WindowItem), "This should be a WindowItem" 13 | assert isinstance(witem, irssi.Query) or \ 14 | isinstance(witem, irssi.Channel), \ 15 | "... and be a Query or Channel" 16 | 17 | server.channels_join("#neblooh") 18 | #server.disconnect() 19 | sc = server.connect 20 | 21 | print 'witem.server', witem.server 22 | 23 | print 'Server.Connect', sc 24 | print 'connect.type', sc.type 25 | print 'connect.type_id', sc.type_id 26 | print 'connect.chat_type', sc.chat_type 27 | print 'connect.chat_type_id', sc.chat_type_id 28 | print 'connect.address', sc.address 29 | print 'connect.port', sc.port 30 | print 'connect.chatnet', sc.chatnet 31 | print 'connect.password', sc.password 32 | print 'connect.wanted_nick', sc.wanted_nick 33 | print 'connect.username', sc.username 34 | print 'connect.realname', sc.realname 35 | if isinstance(sc, irssi.IrcConnect): 36 | print 'IRC Connect items:' 37 | print 'connect.alternate_nick', sc.alternate_nick 38 | 39 | print 40 | print 41 | print 'Server', server 42 | print 'server.type', server.type 43 | print 'server.type_id', server.type_id 44 | print 'server.chat_type', server.chat_type 45 | print 'server.chat_type_id', server.chat_type_id 46 | print 'server.connect_time', server.connect_time 47 | print 'server.real_connect_time', server.real_connect_time 48 | print 'server.tag', server.tag 49 | print 'server.nick', server.nick 50 | print 'server.connected', server.connected 51 | print 'server.connection_lost', server.connection_lost 52 | print 'server.rawlog', server.rawlog 53 | print 'server.version', server.version 54 | print 'server.last_invite', server.server_operator 55 | print 'server.usermode_away', server.usermode_away 56 | print 'server.away_reason', server.away_reason 57 | print 'server.banned', server.banned 58 | print 'server.lag', server.lag 59 | if isinstance(server, irssi.IrcServer): 60 | print 'IRC Server items:' 61 | print 'server.real_address', server.real_address 62 | print 'server.usermode', server.usermode 63 | print 'server.userhost', server.userhost 64 | 65 | print 66 | print 67 | print 'Witem', witem 68 | print 'witem.type', witem.type 69 | print 'witem.type_id', witem.type_id 70 | print 'witem.chat_type', witem.chat_type 71 | print 'witem.chat_type_id', witem.chat_type_id 72 | print 'witem.server', witem.server 73 | print 'witem.name', witem.name 74 | print 'witem.createtime', witem.createtime 75 | print 'witem.data_level', witem.data_level 76 | print 'witem.hilight_color', witem.hilight_color 77 | 78 | #if witem.type == "CHANNEL": 79 | if isinstance(witem, irssi.Channel): 80 | print 'channel items:' 81 | print 'witem.topic', witem.topic 82 | print 'witem.topic_by', witem.topic_by 83 | print 'witem.topic_time', witem.topic_time 84 | print 'witem.no_modes', witem.no_modes 85 | print 'witem.mode', witem.mode 86 | print 'witem.limit', witem.limit 87 | print 'witem.key', witem.key 88 | print 'witem.chanop', witem.chanop 89 | print 'witem.names_got', witem.names_got 90 | print 'witem.wholist', witem.wholist 91 | print 'witem.synced', witem.synced 92 | #witem.destroy() 93 | print 'witem.joined', witem.joined 94 | print 'witem.left', witem.left 95 | print 'witem.kicked', witem.kicked 96 | if isinstance(witem, irssi.IrcChannel): 97 | print 'IRC channel:' 98 | print 'witem.bans', witem.bans() 99 | for ban in witem.bans(): 100 | print 'ban.ban', ban.ban 101 | print 'ban.setby', ban.setby 102 | print 'ban.time', ban.time 103 | 104 | #elif witem.type == "QUERY": 105 | elif isinstance(witem, irssi.Query): 106 | print 'query items:' 107 | print 'witem.address', witem.address 108 | witem.change_server(server) 109 | #witem.change_server(witem) 110 | print 'witem.server_tag', witem.server_tag 111 | print 'witem.unwanted', witem.unwanted 112 | 113 | print 114 | print 115 | print 'is nick flag "@"?', server.isnickflag('@') 116 | print 'is nick flag "+"?', server.isnickflag('+') 117 | print 'is nick flag "%"?', server.isnickflag('%') 118 | 119 | print 'is channel "#fuggerd"', server.ischannel('#fuggerd') 120 | print 'is channel "&booh"', server.ischannel('&booh') 121 | print 'is channel "xbooh"', server.ischannel('xbooh') 122 | 123 | print 'nick flags', server.get_nick_flags() 124 | 125 | print irssi.chatnets() 126 | for cn in irssi.chatnets(): 127 | print 'cn.type', cn.type 128 | print 'cn.chat_type', cn.chat_type 129 | print 'cn.name', cn.name 130 | print 'cn.nick', cn.nick 131 | print 'cn.username', cn.username 132 | print 'cn.realname', cn.realname 133 | print 'cn.own_host', cn.own_host 134 | print 'cn.autosendcmd', cn.autosendcmd 135 | print 136 | 137 | print irssi.chatnet_find('ircnet') 138 | print irssi.servers() 139 | print irssi.reconnects() 140 | 141 | print irssi.windows() 142 | for win in irssi.windows(): 143 | print 'win.refnum', win.refnum 144 | print 'win.name', win.name 145 | print 'win.width', win.width 146 | print 'win.height', win.height 147 | print 'win.history_name', win.history_name 148 | print 'win.active', win.active 149 | print 'win.active_server', win.active_server 150 | print 'win.servertag', win.servertag 151 | print 'win.level', win.level 152 | print 'win.sticky_refnum', win.sticky_refnum 153 | print 'win.data_level', win.data_level 154 | print 'win.hilight_color', win.hilight_color 155 | print 'win.last_timestamp', win.last_timestamp 156 | print 'win.last_line', win.last_line 157 | print 'win.theme_name', win.theme_name 158 | print 159 | 160 | """ 161 | print 'printing to channel' 162 | server.send_message('#booh', 'test msg chan', 0) 163 | server.send_message('#booh', 'test msg chan ER', 1) 164 | 165 | print 'printing to nick' 166 | server.send_message('melbo', 'test msg nick', 1) 167 | server.send_message('melbo', 'test msg nick ER', 0) 168 | """ 169 | 170 | witem.prnt('hello there') 171 | global __last_witem 172 | __last_witem = witem 173 | global __last_server 174 | __last_server = server 175 | 176 | #new = irssi.IrssiChatBase() 177 | #print 'New', new.type_id 178 | 179 | def cmd_crashme(data, server, witem): 180 | __last_server.prnt('#booh', 'what up??') 181 | __last_witem.prnt('imma crash mebbe?') 182 | 183 | print dir(_script) 184 | print _script.module 185 | print _script.argv 186 | 187 | irssi.command_bind('pydumper', cmd_pydumper) 188 | irssi.command_bind('crashme', cmd_crashme) 189 | -------------------------------------------------------------------------------- /src/objects/theme-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi.h" 23 | #include "pymodule.h" 24 | #include "theme-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | /* monitor "theme destroyed" signal */ 29 | static void theme_cleanup(THEME_REC *rec) 30 | { 31 | PyTheme *pytheme = signal_get_user_data(); 32 | if (pytheme->data == rec) 33 | { 34 | pytheme->data = NULL; 35 | pytheme->cleanup_installed = 0; 36 | signal_remove_data("theme destroyed", theme_cleanup, pytheme); 37 | } 38 | } 39 | 40 | static void PyTheme_dealloc(PyTheme *self) 41 | { 42 | if (self->cleanup_installed) 43 | signal_remove_data("theme destroyed", theme_cleanup, self); 44 | 45 | self->ob_type->tp_free((PyObject*)self); 46 | } 47 | 48 | static PyObject *PyTheme_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 49 | { 50 | PyTheme *self; 51 | 52 | self = (PyTheme *)type->tp_alloc(type, 0); 53 | if (!self) 54 | return NULL; 55 | 56 | return (PyObject *)self; 57 | } 58 | 59 | /* Getters */ 60 | /* specialized getters/setters */ 61 | static PyGetSetDef PyTheme_getseters[] = { 62 | {NULL} 63 | }; 64 | 65 | /* Methods */ 66 | PyDoc_STRVAR(PyTheme_format_expand_doc, 67 | "format_expand(format, flags=0) -> str or None\n" 68 | ); 69 | static PyObject *PyTheme_format_expand(PyTheme *self, PyObject *args, PyObject *kwds) 70 | { 71 | static char *kwlist[] = {"format", "flags", NULL}; 72 | char *format = ""; 73 | int flags = 0; 74 | char *ret; 75 | PyObject *pyret; 76 | 77 | RET_NULL_IF_INVALID(self->data); 78 | 79 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, 80 | &format, &flags)) 81 | return NULL; 82 | 83 | if (flags == 0) 84 | ret = theme_format_expand(self->data, format); 85 | else 86 | ret = theme_format_expand_data(self->data, (const char **)&format, 'n', 'n', 87 | NULL, NULL, EXPAND_FLAG_ROOT | flags); 88 | 89 | if (ret) 90 | { 91 | pyret = PyString_FromString(ret); 92 | g_free(ret); 93 | return pyret; 94 | } 95 | 96 | Py_RETURN_NONE; 97 | } 98 | 99 | PyDoc_STRVAR(PyTheme_get_format_doc, 100 | "get_format(module, tag) -> str\n" 101 | ); 102 | static PyObject *PyTheme_get_format(PyTheme *self, PyObject *args, PyObject *kwds) 103 | { 104 | static char *kwlist[] = {"module", "tag", NULL}; 105 | char *module = ""; 106 | char *tag = ""; 107 | THEME_REC *theme = self->data; 108 | FORMAT_REC *formats; 109 | MODULE_THEME_REC *modtheme; 110 | int i; 111 | 112 | RET_NULL_IF_INVALID(self->data); 113 | 114 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist, 115 | &module, &tag)) 116 | return NULL; 117 | 118 | formats = g_hash_table_lookup(default_formats, module); 119 | if (!formats) 120 | return PyErr_Format(PyExc_KeyError, "unknown module, %s", module); 121 | 122 | for (i = 0; formats[i].def; i++) 123 | { 124 | if (formats[i].tag && !g_strcasecmp(formats[i].tag, tag)) 125 | { 126 | modtheme = g_hash_table_lookup(theme->modules, module); 127 | if (modtheme && modtheme->formats[i]) 128 | return PyString_FromString(modtheme->formats[i]); 129 | else 130 | return PyString_FromString(formats[i].def); 131 | } 132 | } 133 | 134 | return PyErr_Format(PyExc_KeyError, "unknown format tag, %s", tag); 135 | } 136 | 137 | /* Methods for object */ 138 | static PyMethodDef PyTheme_methods[] = { 139 | {"format_expand", (PyCFunction)PyTheme_format_expand, METH_VARARGS | METH_KEYWORDS, 140 | PyTheme_format_expand_doc}, 141 | {"get_format", (PyCFunction)PyTheme_get_format, METH_VARARGS | METH_KEYWORDS, 142 | PyTheme_get_format_doc}, 143 | {NULL} /* Sentinel */ 144 | }; 145 | 146 | PyTypeObject PyThemeType = { 147 | PyObject_HEAD_INIT(NULL) 148 | 0, /*ob_size*/ 149 | "irssi.Theme", /*tp_name*/ 150 | sizeof(PyTheme), /*tp_basicsize*/ 151 | 0, /*tp_itemsize*/ 152 | (destructor)PyTheme_dealloc, /*tp_dealloc*/ 153 | 0, /*tp_print*/ 154 | 0, /*tp_getattr*/ 155 | 0, /*tp_setattr*/ 156 | 0, /*tp_compare*/ 157 | 0, /*tp_repr*/ 158 | 0, /*tp_as_number*/ 159 | 0, /*tp_as_sequence*/ 160 | 0, /*tp_as_mapping*/ 161 | 0, /*tp_hash */ 162 | 0, /*tp_call*/ 163 | 0, /*tp_str*/ 164 | 0, /*tp_getattro*/ 165 | 0, /*tp_setattro*/ 166 | 0, /*tp_as_buffer*/ 167 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 168 | 0, /* tp_doc */ 169 | 0, /* tp_traverse */ 170 | 0, /* tp_clear */ 171 | 0, /* tp_richcompare */ 172 | 0, /* tp_weaklistoffset */ 173 | 0, /* tp_iter */ 174 | 0, /* tp_iternext */ 175 | PyTheme_methods, /* tp_methods */ 176 | 0, /* tp_members */ 177 | PyTheme_getseters, /* tp_getset */ 178 | 0, /* tp_base */ 179 | 0, /* tp_dict */ 180 | 0, /* tp_descr_get */ 181 | 0, /* tp_descr_set */ 182 | 0, /* tp_dictoffset */ 183 | 0, /* tp_init */ 184 | 0, /* tp_alloc */ 185 | PyTheme_new, /* tp_new */ 186 | }; 187 | 188 | /* Theme factory function */ 189 | PyObject *pytheme_new(void *td) 190 | { 191 | PyTheme *pytheme; 192 | 193 | pytheme = py_inst(PyTheme, PyThemeType); 194 | if (!pytheme) 195 | return NULL; 196 | 197 | pytheme->data = td; 198 | signal_add_last_data("theme destroyed", theme_cleanup, pytheme); 199 | pytheme->cleanup_installed = 1; 200 | 201 | return (PyObject *)pytheme; 202 | } 203 | 204 | int theme_object_init(void) 205 | { 206 | g_return_val_if_fail(py_module != NULL, 0); 207 | 208 | if (PyType_Ready(&PyThemeType) < 0) 209 | return 0; 210 | 211 | Py_INCREF(&PyThemeType); 212 | PyModule_AddObject(py_module, "Theme", (PyObject *)&PyThemeType); 213 | 214 | return 1; 215 | } 216 | -------------------------------------------------------------------------------- /src/objects/connect-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pymodule.h" 23 | #include "base-objects.h" 24 | #include "connect-object.h" 25 | #include "pyirssi.h" 26 | #include "pycore.h" 27 | #include "pyutils.h" 28 | 29 | static void connect_cleanup(SERVER_CONNECT_REC *connect) 30 | { 31 | PyConnect *pyconn = signal_get_user_data(); 32 | 33 | /* 34 | if (server == pyconn->data) 35 | { 36 | pyserver->data = NULL; 37 | pyserver->cleanup_installed = 0; 38 | signal_remove_data("server disconnected", connect_cleanup, pyserver); 39 | } 40 | */ 41 | } 42 | 43 | static void PyConnect_dealloc(PyConnect *self) 44 | { 45 | if (self->cleanup_installed) 46 | signal_remove_data("server disconnected", connect_cleanup, self); 47 | 48 | self->ob_type->tp_free((PyObject*)self); 49 | } 50 | 51 | /* Getters */ 52 | PyDoc_STRVAR(PyConnect_address_doc, 53 | "Address where we connected (irc.blah.org)" 54 | ); 55 | static PyObject *PyConnect_address_get(PyConnect *self, void *closure) 56 | { 57 | RET_NULL_IF_INVALID(self->data); 58 | RET_AS_STRING_OR_NONE(self->data->address); 59 | } 60 | 61 | PyDoc_STRVAR(PyConnect_port_doc, 62 | "Port where we're connected" 63 | ); 64 | static PyObject *PyConnect_port_get(PyConnect *self, void *closure) 65 | { 66 | RET_NULL_IF_INVALID(self->data); 67 | return PyInt_FromLong(self->data->port); 68 | } 69 | 70 | PyDoc_STRVAR(PyConnect_chatnet_doc, 71 | "Chat network" 72 | ); 73 | static PyObject *PyConnect_chatnet_get(PyConnect *self, void *closure) 74 | { 75 | RET_NULL_IF_INVALID(self->data); 76 | RET_AS_STRING_OR_NONE(self->data->chatnet); 77 | } 78 | 79 | PyDoc_STRVAR(PyConnect_password_doc, 80 | "Password we used in connection." 81 | ); 82 | static PyObject *PyConnect_password_get(PyConnect *self, void *closure) 83 | { 84 | RET_NULL_IF_INVALID(self->data); 85 | RET_AS_STRING_OR_NONE(self->data->password); 86 | } 87 | 88 | PyDoc_STRVAR(PyConnect_wanted_nick_doc, 89 | "Nick which we would prefer to use" 90 | ); 91 | static PyObject *PyConnect_wanted_nick_get(PyConnect *self, void *closure) 92 | { 93 | RET_NULL_IF_INVALID(self->data); 94 | RET_AS_STRING_OR_NONE(self->data->nick); 95 | } 96 | 97 | PyDoc_STRVAR(PyConnect_username_doc, 98 | "User name" 99 | ); 100 | static PyObject *PyConnect_username_get(PyConnect *self, void *closure) 101 | { 102 | RET_NULL_IF_INVALID(self->data); 103 | RET_AS_STRING_OR_NONE(self->data->username); 104 | } 105 | 106 | PyDoc_STRVAR(PyConnect_realname_doc, 107 | "Real name" 108 | ); 109 | static PyObject *PyConnect_realname_get(PyConnect *self, void *closure) 110 | { 111 | RET_NULL_IF_INVALID(self->data); 112 | RET_AS_STRING_OR_NONE(self->data->realname); 113 | } 114 | 115 | /* Get/Set */ 116 | static PyGetSetDef PyConnect_getseters[] = { 117 | {"address", (getter)PyConnect_address_get, NULL, 118 | PyConnect_address_doc, NULL}, 119 | {"port", (getter)PyConnect_port_get, NULL, 120 | PyConnect_port_doc, NULL}, 121 | {"chatnet", (getter)PyConnect_chatnet_get, NULL, 122 | PyConnect_chatnet_doc, NULL}, 123 | {"password", (getter)PyConnect_password_get, NULL, 124 | PyConnect_password_doc, NULL}, 125 | {"wanted_nick", (getter)PyConnect_wanted_nick_get, NULL, 126 | PyConnect_wanted_nick_doc, NULL}, 127 | {"username", (getter)PyConnect_username_get, NULL, 128 | PyConnect_username_doc, NULL}, 129 | {"realname", (getter)PyConnect_realname_get, NULL, 130 | PyConnect_realname_doc, NULL}, 131 | {NULL} 132 | }; 133 | 134 | PyTypeObject PyConnectType = { 135 | PyObject_HEAD_INIT(NULL) 136 | 0, /*ob_size*/ 137 | "irssi.Connect", /*tp_name*/ 138 | sizeof(PyConnect), /*tp_basicsize*/ 139 | 0, /*tp_itemsize*/ 140 | (destructor)PyConnect_dealloc, /*tp_dealloc*/ 141 | 0, /*tp_print*/ 142 | 0, /*tp_getattr*/ 143 | 0, /*tp_setattr*/ 144 | 0, /*tp_compare*/ 145 | 0, /*tp_repr*/ 146 | 0, /*tp_as_number*/ 147 | 0, /*tp_as_sequence*/ 148 | 0, /*tp_as_mapping*/ 149 | 0, /*tp_hash */ 150 | 0, /*tp_call*/ 151 | 0, /*tp_str*/ 152 | 0, /*tp_getattro*/ 153 | 0, /*tp_setattro*/ 154 | 0, /*tp_as_buffer*/ 155 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 156 | "PyConnect objects", /* tp_doc */ 157 | 0, /* tp_traverse */ 158 | 0, /* tp_clear */ 159 | 0, /* tp_richcompare */ 160 | 0, /* tp_weaklistoffset */ 161 | 0, /* tp_iter */ 162 | 0, /* tp_iternext */ 163 | 0, /* tp_methods */ 164 | 0, /* tp_members */ 165 | PyConnect_getseters, /* tp_getset */ 166 | &PyIrssiChatBaseType, /* tp_base */ 167 | 0, /* tp_dict */ 168 | 0, /* tp_descr_get */ 169 | 0, /* tp_descr_set */ 170 | 0, /* tp_dictoffset */ 171 | 0, /* tp_init */ 172 | 0, /* tp_alloc */ 173 | 0, /* tp_new */ 174 | }; 175 | 176 | 177 | /* server connect factory function (managed == 0, don't do signal cleanup, 1 == do sig cleanup */ 178 | PyObject *pyconnect_sub_new(void *connect, PyTypeObject *subclass, int managed) 179 | { 180 | static const char *CONNECT_TYPE = "SERVER CONNECT"; 181 | PyConnect *pyconn = NULL; 182 | 183 | g_return_val_if_fail(connect != NULL, NULL); 184 | 185 | pyconn = py_instp(PyConnect, subclass); 186 | if (!pyconn) 187 | return NULL; 188 | 189 | pyconn->base_name = CONNECT_TYPE; 190 | pyconn->data = connect; 191 | 192 | if (managed) 193 | { 194 | //XXX: how to handle cleanup? 195 | //signal_add_last_data("server disconnected", connect_cleanup, pyconn); 196 | //pyconn->cleanup_installed = 1; 197 | } 198 | 199 | return (PyObject *)pyconn; 200 | } 201 | 202 | PyObject *pyconnect_new(void *connect, int managed) 203 | { 204 | return pyconnect_sub_new(connect, &PyConnectType, managed); 205 | } 206 | 207 | int connect_object_init(void) 208 | { 209 | g_return_val_if_fail(py_module != NULL, 0); 210 | 211 | if (PyType_Ready(&PyConnectType) < 0) 212 | return 0; 213 | 214 | Py_INCREF(&PyConnectType); 215 | PyModule_AddObject(py_module, "Connect", (PyObject *)&PyConnectType); 216 | 217 | return 1; 218 | } 219 | -------------------------------------------------------------------------------- /src/objects/main-window-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi.h" 23 | #include "pymodule.h" 24 | #include "main-window-object.h" 25 | #include "factory.h" 26 | #include "pycore.h" 27 | 28 | #define MW(data) ((MAIN_WINDOW_REC *) data) 29 | 30 | /* monitor "mainwindow destroyed" signal */ 31 | static void main_window_cleanup(MAIN_WINDOW_REC *mw) 32 | { 33 | PyMainWindow *pymw = signal_get_user_data(); 34 | 35 | if (mw == pymw->data) 36 | { 37 | pymw->data = NULL; 38 | pymw->cleanup_installed = 0; 39 | signal_remove_data("mainwindow destroyed", main_window_cleanup, pymw); 40 | } 41 | } 42 | 43 | static void PyMainWindow_dealloc(PyMainWindow *self) 44 | { 45 | if (self->cleanup_installed) 46 | signal_remove_data("mainwindow destroyed", main_window_cleanup, self); 47 | 48 | Py_XDECREF(self->active); 49 | self->ob_type->tp_free((PyObject*)self); 50 | } 51 | 52 | static PyObject *PyMainWindow_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 53 | { 54 | PyMainWindow *self; 55 | 56 | self = (PyMainWindow *)type->tp_alloc(type, 0); 57 | if (!self) 58 | return NULL; 59 | 60 | return (PyObject *)self; 61 | } 62 | 63 | /* getters */ 64 | PyDoc_STRVAR(PyMainWindow_active_doc, 65 | "active window object" 66 | ); 67 | static PyObject *PyMainWindow_active_get(PyMainWindow *self, void *closure) 68 | { 69 | RET_NULL_IF_INVALID(self->data); 70 | RET_AS_OBJ_OR_NONE(self->active); 71 | } 72 | 73 | PyDoc_STRVAR(PyMainWindow_first_line_doc, 74 | "first line used by this window (0..x) (includes statusbars)" 75 | ); 76 | static PyObject *PyMainWindow_first_line_get(PyMainWindow *self, void *closure) 77 | { 78 | RET_NULL_IF_INVALID(self->data); 79 | return PyInt_FromLong(MW(self->data)->first_line); 80 | } 81 | 82 | PyDoc_STRVAR(PyMainWindow_last_line_doc, 83 | "last line used by this window (0..x) (includes statusbars)" 84 | ); 85 | static PyObject *PyMainWindow_last_line_get(PyMainWindow *self, void *closure) 86 | { 87 | RET_NULL_IF_INVALID(self->data); 88 | return PyInt_FromLong(MW(self->data)->last_line); 89 | } 90 | 91 | PyDoc_STRVAR(PyMainWindow_width_doc, 92 | "width of the window (includes statusbars)" 93 | ); 94 | static PyObject *PyMainWindow_width_get(PyMainWindow *self, void *closure) 95 | { 96 | RET_NULL_IF_INVALID(self->data); 97 | return PyInt_FromLong(MW(self->data)->width); 98 | } 99 | 100 | PyDoc_STRVAR(PyMainWindow_height_doc, 101 | "height of the window (includes statusbars)" 102 | ); 103 | static PyObject *PyMainWindow_height_get(PyMainWindow *self, void *closure) 104 | { 105 | RET_NULL_IF_INVALID(self->data); 106 | return PyInt_FromLong(MW(self->data)->height); 107 | } 108 | 109 | PyDoc_STRVAR(PyMainWindow_statusbar_lines_doc, 110 | "???" 111 | ); 112 | static PyObject *PyMainWindow_statusbar_lines_get(PyMainWindow *self, void *closure) 113 | { 114 | RET_NULL_IF_INVALID(self->data); 115 | return PyInt_FromLong(MW(self->data)->statusbar_lines); 116 | } 117 | 118 | /* specialized getters/setters */ 119 | static PyGetSetDef PyMainWindow_getseters[] = { 120 | {"active", (getter)PyMainWindow_active_get, NULL, 121 | PyMainWindow_active_doc, NULL}, 122 | {"first_line", (getter)PyMainWindow_first_line_get, NULL, 123 | PyMainWindow_first_line_doc, NULL}, 124 | {"last_line", (getter)PyMainWindow_last_line_get, NULL, 125 | PyMainWindow_last_line_doc, NULL}, 126 | {"width", (getter)PyMainWindow_width_get, NULL, 127 | PyMainWindow_width_doc, NULL}, 128 | {"height", (getter)PyMainWindow_height_get, NULL, 129 | PyMainWindow_height_doc, NULL}, 130 | {"statusbar_lines", (getter)PyMainWindow_statusbar_lines_get, NULL, 131 | PyMainWindow_statusbar_lines_doc, NULL}, 132 | {NULL} 133 | }; 134 | 135 | /* Methods for object */ 136 | static PyMethodDef PyMainWindow_methods[] = { 137 | {NULL} /* Sentinel */ 138 | }; 139 | 140 | PyTypeObject PyMainWindowType = { 141 | PyObject_HEAD_INIT(NULL) 142 | 0, /*ob_size*/ 143 | "irssi.MainWindow", /*tp_name*/ 144 | sizeof(PyMainWindow), /*tp_basicsize*/ 145 | 0, /*tp_itemsize*/ 146 | (destructor)PyMainWindow_dealloc, /*tp_dealloc*/ 147 | 0, /*tp_print*/ 148 | 0, /*tp_getattr*/ 149 | 0, /*tp_setattr*/ 150 | 0, /*tp_compare*/ 151 | 0, /*tp_repr*/ 152 | 0, /*tp_as_number*/ 153 | 0, /*tp_as_sequence*/ 154 | 0, /*tp_as_mapping*/ 155 | 0, /*tp_hash */ 156 | 0, /*tp_call*/ 157 | 0, /*tp_str*/ 158 | 0, /*tp_getattro*/ 159 | 0, /*tp_setattro*/ 160 | 0, /*tp_as_buffer*/ 161 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 162 | "PyMainWindow objects", /* tp_doc */ 163 | 0, /* tp_traverse */ 164 | 0, /* tp_clear */ 165 | 0, /* tp_richcompare */ 166 | 0, /* tp_weaklistoffset */ 167 | 0, /* tp_iter */ 168 | 0, /* tp_iternext */ 169 | PyMainWindow_methods, /* tp_methods */ 170 | 0, /* tp_members */ 171 | PyMainWindow_getseters, /* tp_getset */ 172 | 0, /* tp_base */ 173 | 0, /* tp_dict */ 174 | 0, /* tp_descr_get */ 175 | 0, /* tp_descr_set */ 176 | 0, /* tp_dictoffset */ 177 | 0, /* tp_init */ 178 | 0, /* tp_alloc */ 179 | PyMainWindow_new, /* tp_new */ 180 | }; 181 | 182 | 183 | /* main window wrapper factory function */ 184 | PyObject *pymain_window_new(MAIN_WINDOW_REC *mw) 185 | { 186 | PyObject *pyactive = NULL; 187 | PyMainWindow *pymw; 188 | 189 | pyactive = pywindow_new(mw->active); 190 | if (!pyactive) 191 | return NULL; 192 | 193 | pymw = py_inst(PyMainWindow, PyMainWindowType); 194 | if (!pymw) 195 | { 196 | Py_DECREF(pyactive); 197 | return NULL; 198 | } 199 | 200 | pymw->active = pyactive; 201 | pymw->data = mw; 202 | pymw->cleanup_installed = 1; 203 | signal_add_last_data("mainwindow destroyed", main_window_cleanup, pymw); 204 | 205 | return (PyObject *)pymw; 206 | } 207 | 208 | int main_window_object_init(void) 209 | { 210 | g_return_val_if_fail(py_module != NULL, 0); 211 | 212 | if (PyType_Ready(&PyMainWindowType) < 0) 213 | return 0; 214 | 215 | Py_INCREF(&PyMainWindowType); 216 | PyModule_AddObject(py_module, "MainWindow", (PyObject *)&PyMainWindowType); 217 | 218 | return 1; 219 | } 220 | -------------------------------------------------------------------------------- /src/objects/process-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "process-object.h" 25 | #include "pycore.h" 26 | 27 | /* monitor "exec remove" signal */ 28 | static void process_cleanup(PROCESS_REC *process, int status) 29 | { 30 | PyProcess *pyprocess = signal_get_user_data(); 31 | 32 | if (process == pyprocess->data) 33 | { 34 | pyprocess->data = NULL; 35 | pyprocess->cleanup_installed = 0; 36 | signal_remove_data("exec remove", process_cleanup, pyprocess); 37 | } 38 | } 39 | 40 | static void PyProcess_dealloc(PyProcess *self) 41 | { 42 | if (self->cleanup_installed) 43 | signal_remove_data("exec remove", process_cleanup, self); 44 | 45 | Py_XDECREF(self->target_win); 46 | 47 | self->ob_type->tp_free((PyObject*)self); 48 | } 49 | 50 | static PyObject *PyProcess_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 51 | { 52 | PyProcess *self; 53 | 54 | self = (PyProcess *)type->tp_alloc(type, 0); 55 | if (!self) 56 | return NULL; 57 | 58 | return (PyObject *)self; 59 | } 60 | 61 | /* Getters */ 62 | PyDoc_STRVAR(PyProcess_id_doc, 63 | "ID for the process" 64 | ); 65 | static PyObject *PyProcess_id_get(PyProcess *self, void *closure) 66 | { 67 | RET_NULL_IF_INVALID(self->data); 68 | return PyInt_FromLong(self->data->id); 69 | } 70 | 71 | PyDoc_STRVAR(PyProcess_name_doc, 72 | "Name for the process (if given)" 73 | ); 74 | static PyObject *PyProcess_name_get(PyProcess *self, void *closure) 75 | { 76 | RET_NULL_IF_INVALID(self->data); 77 | RET_AS_STRING_OR_NONE(self->data->name); 78 | } 79 | 80 | PyDoc_STRVAR(PyProcess_args_doc, 81 | "The command that is being executed" 82 | ); 83 | static PyObject *PyProcess_args_get(PyProcess *self, void *closure) 84 | { 85 | RET_NULL_IF_INVALID(self->data); 86 | RET_AS_STRING_OR_NONE(self->data->args); 87 | } 88 | 89 | PyDoc_STRVAR(PyProcess_pid_doc, 90 | "PID for the executed command" 91 | ); 92 | static PyObject *PyProcess_pid_get(PyProcess *self, void *closure) 93 | { 94 | RET_NULL_IF_INVALID(self->data); 95 | return PyInt_FromLong(self->data->pid); 96 | } 97 | 98 | PyDoc_STRVAR(PyProcess_target_doc, 99 | "send text with /msg ..." 100 | ); 101 | static PyObject *PyProcess_target_get(PyProcess *self, void *closure) 102 | { 103 | RET_NULL_IF_INVALID(self->data); 104 | RET_AS_STRING_OR_NONE(self->data->target); 105 | } 106 | 107 | PyDoc_STRVAR(PyProcess_target_win_doc, 108 | "print text to this window" 109 | ); 110 | static PyObject *PyProcess_target_win_get(PyProcess *self, void *closure) 111 | { 112 | RET_NULL_IF_INVALID(self->data); 113 | RET_AS_OBJ_OR_NONE(self->target_win); 114 | } 115 | 116 | PyDoc_STRVAR(PyProcess_shell_doc, 117 | "start the program via /bin/sh" 118 | ); 119 | static PyObject *PyProcess_shell_get(PyProcess *self, void *closure) 120 | { 121 | RET_NULL_IF_INVALID(self->data); 122 | return PyBool_FromLong(self->data->shell); 123 | } 124 | 125 | PyDoc_STRVAR(PyProcess_notice_doc, 126 | "send text with /notice, not /msg if target is set" 127 | ); 128 | static PyObject *PyProcess_notice_get(PyProcess *self, void *closure) 129 | { 130 | RET_NULL_IF_INVALID(self->data); 131 | return PyBool_FromLong(self->data->notice); 132 | } 133 | 134 | PyDoc_STRVAR(PyProcess_silent_doc, 135 | "don't print \"process exited with level xx\"" 136 | ); 137 | static PyObject *PyProcess_silent_get(PyProcess *self, void *closure) 138 | { 139 | RET_NULL_IF_INVALID(self->data); 140 | return PyBool_FromLong(self->data->silent); 141 | } 142 | 143 | /* specialized getters/setters */ 144 | static PyGetSetDef PyProcess_getseters[] = { 145 | {"id", (getter)PyProcess_id_get, NULL, 146 | PyProcess_id_doc, NULL}, 147 | {"name", (getter)PyProcess_name_get, NULL, 148 | PyProcess_name_doc, NULL}, 149 | {"args", (getter)PyProcess_args_get, NULL, 150 | PyProcess_args_doc, NULL}, 151 | {"pid", (getter)PyProcess_pid_get, NULL, 152 | PyProcess_pid_doc, NULL}, 153 | {"target", (getter)PyProcess_target_get, NULL, 154 | PyProcess_target_doc, NULL}, 155 | {"target_win", (getter)PyProcess_target_win_get, NULL, 156 | PyProcess_target_win_doc, NULL}, 157 | {"shell", (getter)PyProcess_shell_get, NULL, 158 | PyProcess_shell_doc, NULL}, 159 | {"notice", (getter)PyProcess_notice_get, NULL, 160 | PyProcess_notice_doc, NULL}, 161 | {"silent", (getter)PyProcess_silent_get, NULL, 162 | PyProcess_silent_doc, NULL}, 163 | {NULL} 164 | }; 165 | 166 | /* Methods */ 167 | /* Methods for object */ 168 | static PyMethodDef PyProcess_methods[] = { 169 | {NULL} /* Sentinel */ 170 | }; 171 | 172 | PyTypeObject PyProcessType = { 173 | PyObject_HEAD_INIT(NULL) 174 | 0, /*ob_size*/ 175 | "irssi.Process", /*tp_name*/ 176 | sizeof(PyProcess), /*tp_basicsize*/ 177 | 0, /*tp_itemsize*/ 178 | (destructor)PyProcess_dealloc, /*tp_dealloc*/ 179 | 0, /*tp_print*/ 180 | 0, /*tp_getattr*/ 181 | 0, /*tp_setattr*/ 182 | 0, /*tp_compare*/ 183 | 0, /*tp_repr*/ 184 | 0, /*tp_as_number*/ 185 | 0, /*tp_as_sequence*/ 186 | 0, /*tp_as_mapping*/ 187 | 0, /*tp_hash */ 188 | 0, /*tp_call*/ 189 | 0, /*tp_str*/ 190 | 0, /*tp_getattro*/ 191 | 0, /*tp_setattro*/ 192 | 0, /*tp_as_buffer*/ 193 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 194 | "PyProcess objects", /* tp_doc */ 195 | 0, /* tp_traverse */ 196 | 0, /* tp_clear */ 197 | 0, /* tp_richcompare */ 198 | 0, /* tp_weaklistoffset */ 199 | 0, /* tp_iter */ 200 | 0, /* tp_iternext */ 201 | PyProcess_methods, /* tp_methods */ 202 | 0, /* tp_members */ 203 | PyProcess_getseters, /* tp_getset */ 204 | 0, /* tp_base */ 205 | 0, /* tp_dict */ 206 | 0, /* tp_descr_get */ 207 | 0, /* tp_descr_set */ 208 | 0, /* tp_dictoffset */ 209 | 0, /* tp_init */ 210 | 0, /* tp_alloc */ 211 | PyProcess_new, /* tp_new */ 212 | }; 213 | 214 | 215 | /* process factory function */ 216 | PyObject *pyprocess_new(void *process) 217 | { 218 | PyProcess *pyprocess; 219 | 220 | pyprocess = py_inst(PyProcess, PyProcessType); 221 | if (!pyprocess) 222 | return NULL; 223 | 224 | pyprocess->data = process; 225 | pyprocess->cleanup_installed = 1; 226 | signal_add_last_data("exec remove", process_cleanup, pyprocess); 227 | 228 | return (PyObject *)pyprocess; 229 | } 230 | 231 | int process_object_init(void) 232 | { 233 | g_return_val_if_fail(py_module != NULL, 0); 234 | 235 | if (PyType_Ready(&PyProcessType) < 0) 236 | return 0; 237 | 238 | Py_INCREF(&PyProcessType); 239 | PyModule_AddObject(py_module, "Process", (PyObject *)&PyProcessType); 240 | 241 | return 1; 242 | } 243 | -------------------------------------------------------------------------------- /src/pysigmap.h: -------------------------------------------------------------------------------- 1 | /* Include in your C module */ 2 | static PY_SIGNAL_SPEC_REC py_sigmap[] = { 3 | {"gui exit", "", 0, 0, 0}, 4 | {"gui dialog", "ss", 0, 0, 0}, 5 | {"send command", "sSW", 0, 0, 0}, 6 | {"chat protocol created", "?", 0, 0, 0}, 7 | {"chat protocol updated", "?", 0, 0, 0}, 8 | {"chat protocol destroyed", "?", 0, 0, 0}, 9 | {"channel created", "Ci", 0, 0, 0}, 10 | {"channel destroyed", "C", 0, 0, 0}, 11 | {"chatnet created", "c", 0, 0, 0}, 12 | {"chatnet destroyed", "c", 0, 0, 0}, 13 | {"commandlist new", "o", 0, 0, 0}, 14 | {"commandlist remove", "o", 0, 0, 0}, 15 | {"error command", "is", 0, 0, 0}, 16 | {"send command", "sSW", 0, 0, 0}, 17 | {"send text", "sSW", 0, 0, 0}, 18 | {"command ", "sSW", 0, 0, 1}, 19 | {"default command", "sSW", 0, 0, 0}, 20 | {"ignore created", "g", 0, 0, 0}, 21 | {"ignore destroyed", "g", 0, 0, 0}, 22 | {"ignore changed", "g", 0, 0, 0}, 23 | {"log new", "l", 0, 0, 0}, 24 | {"log remove", "l", 0, 0, 0}, 25 | {"log create failed", "l", 0, 0, 0}, 26 | {"log locked", "l", 0, 0, 0}, 27 | {"log started", "l", 0, 0, 0}, 28 | {"log stopped", "l", 0, 0, 0}, 29 | {"log rotated", "l", 0, 0, 0}, 30 | {"log written", "ls", 0, 0, 0}, 31 | {"module loaded", "??", 0, 0, 0}, 32 | {"module unloaded", "??", 0, 0, 0}, 33 | {"module error", "isss", 0, 0, 0}, 34 | {"nicklist new", "Cn", 0, 0, 0}, 35 | {"nicklist remove", "Cn", 0, 0, 0}, 36 | {"nicklist changed", "Cns", 0, 0, 0}, 37 | {"nicklist host changed", "Cn", 0, 0, 0}, 38 | {"nicklist gone changed", "Cn", 0, 0, 0}, 39 | {"nicklist serverop changed", "Cn", 0, 0, 0}, 40 | {"pidwait", "ii", 0, 0, 0}, 41 | {"query created", "qi", 0, 0, 0}, 42 | {"query destroyed", "q", 0, 0, 0}, 43 | {"query nick changed", "qs", 0, 0, 0}, 44 | {"window item name changed", "W", 0, 0, 0}, 45 | {"query address changed", "q", 0, 0, 0}, 46 | {"query server changed", "qS", 0, 0, 0}, 47 | {"rawlog", "ls", 0, 0, 0}, 48 | {"server looking", "S", 0, 0, 0}, 49 | {"server connected", "S", 0, 0, 0}, 50 | {"server connecting", "Su", 0, 0, 0}, 51 | {"server connect failed", "S", 0, 0, 0}, 52 | {"server disconnected", "S", 0, 0, 0}, 53 | {"server quit", "Ss", 0, 0, 0}, 54 | {"server sendmsg", "Sssi", 0, 0, 0}, 55 | {"setup changed", "", 0, 0, 0}, 56 | {"setup reread", "s", 0, 0, 0}, 57 | {"setup saved", "si", 0, 0, 0}, 58 | {"ban type changed", "s", 0, 0, 0}, 59 | {"channel joined", "C", 0, 0, 0}, 60 | {"channel wholist", "C", 0, 0, 0}, 61 | {"channel sync", "C", 0, 0, 0}, 62 | {"channel topic changed", "C", 0, 0, 0}, 63 | {"ctcp msg", "Sssss", 0, 0, 0}, 64 | {"ctcp msg ", "Sssss", 0, 0, 1}, 65 | {"default ctcp msg", "Sssss", 0, 0, 0}, 66 | {"ctcp reply", "Sssss", 0, 0, 0}, 67 | {"ctcp reply ", "Sssss", 0, 0, 1}, 68 | {"default ctcp reply", "Sssss", 0, 0, 0}, 69 | {"ctcp action", "Sssss", 0, 0, 0}, 70 | {"awaylog show", "lii", 0, 0, 0}, 71 | {"server nick changed", "S", 0, 0, 0}, 72 | {"event connected", "S", 0, 0, 0}, 73 | {"server event", "Ssss", 0, 0, 0}, 74 | {"event ", "Ssss", 0, 0, 1}, 75 | {"default event", "Ssss", 0, 0, 0}, 76 | {"whois default event", "Ssss", 0, 0, 0}, 77 | {"server incoming", "Ss", 0, 0, 0}, 78 | {"redir ", "Ssss", 0, 0, 1}, 79 | {"server lag", "S", 0, 0, 0}, 80 | {"server lag disconnect", "S", 0, 0, 0}, 81 | {"massjoin", "CL", 0, 0, 0}, 82 | {"ban new", "Cb", 0, 0, 0}, 83 | {"ban remove", "Cbs", 0, 0, 0}, 84 | {"channel mode changed", "Cs", 0, 0, 0}, 85 | {"nick mode changed", "Cnsss", 0, 0, 0}, 86 | {"user mode changed", "Ss", 0, 0, 0}, 87 | {"away mode changed", "S", 0, 0, 0}, 88 | {"netsplit server new", "SS", 0, 0, 0}, 89 | {"netsplit server remove", "SS", 0, 0, 0}, 90 | {"netsplit new", "N", 0, 0, 0}, 91 | {"netsplit remove", "N", 0, 0, 0}, 92 | {"dcc ctcp ", "sd", 0, 0, 1}, 93 | {"default dcc ctcp", "sd", 0, 0, 0}, 94 | {"dcc unknown ctcp", "sss", 0, 0, 0}, 95 | {"dcc reply ", "sd", 0, 0, 1}, 96 | {"default dcc reply", "sd", 0, 0, 0}, 97 | {"dcc unknown reply", "sss", 0, 0, 0}, 98 | {"dcc chat message", "ds", 0, 0, 0}, 99 | {"dcc created", "d", 0, 0, 0}, 100 | {"dcc destroyed", "d", 0, 0, 0}, 101 | {"dcc connected", "d", 0, 0, 0}, 102 | {"dcc rejecting", "d", 0, 0, 0}, 103 | {"dcc closed", "d", 0, 0, 0}, 104 | {"dcc request", "ds", 0, 0, 0}, 105 | {"dcc request send", "d", 0, 0, 0}, 106 | {"dcc chat message", "ds", 0, 0, 0}, 107 | {"dcc transfer update", "d", 0, 0, 0}, 108 | {"dcc get receive", "d", 0, 0, 0}, 109 | {"dcc error connect", "d", 0, 0, 0}, 110 | {"dcc error file create", "ds", 0, 0, 0}, 111 | {"dcc error file open", "ssi", 0, 0, 0}, 112 | {"dcc error get not found", "s", 0, 0, 0}, 113 | {"dcc error send exists", "ss", 0, 0, 0}, 114 | {"dcc error unknown type", "s", 0, 0, 0}, 115 | {"dcc error close not found", "sss", 0, 0, 0}, 116 | {"autoignore new", "S?", 0, 0, 0}, 117 | {"autoignore remove", "S?", 0, 0, 0}, 118 | {"flood", "Sssis", 0, 0, 0}, 119 | {"notifylist new", "O", 0, 0, 0}, 120 | {"notifylist remove", "O", 0, 0, 0}, 121 | {"notifylist joined", "Ssssss", 0, 0, 0}, 122 | {"notifylist away changed", "Ssssss", 0, 0, 0}, 123 | {"notifylist unidle", "Ssssss", 0, 0, 0}, 124 | {"notifylist left", "Ssssss", 0, 0, 0}, 125 | {"proxy client connected", "?", 0, 0, 0}, 126 | {"proxy client disconnected", "?", 0, 0, 0}, 127 | {"gui print text", "wiiist", 0, 0, 0}, 128 | {"gui print text finished", "w", 0, 0, 0}, 129 | {"complete word", "?wssi", 0, 0, 0}, 130 | {"irssi init read settings", "", 0, 0, 0}, 131 | {"exec new", "p", 0, 0, 0}, 132 | {"exec remove", "pi", 0, 0, 0}, 133 | {"exec input", "ps", 0, 0, 0}, 134 | {"message public", "Sssss", 0, 0, 0}, 135 | {"message private", "Ssss", 0, 0, 0}, 136 | {"message own_public", "Sss", 0, 0, 0}, 137 | {"message own_private", "Ssss", 0, 0, 0}, 138 | {"message join", "Ssss", 0, 0, 0}, 139 | {"message part", "Sssss", 0, 0, 0}, 140 | {"message quit", "Ssss", 0, 0, 0}, 141 | {"message kick", "Ssssss", 0, 0, 0}, 142 | {"message nick", "Ssss", 0, 0, 0}, 143 | {"message own_nick", "Ssss", 0, 0, 0}, 144 | {"message invite", "Ssss", 0, 0, 0}, 145 | {"message topic", "Sssss", 0, 0, 0}, 146 | {"keyinfo created", "?", 0, 0, 0}, 147 | {"keyinfo destroyed", "?", 0, 0, 0}, 148 | {"print text", "tss", 0, 0, 0}, 149 | {"theme created", "?", 0, 0, 0}, 150 | {"theme destroyed", "?", 0, 0, 0}, 151 | {"window hilight", "w", 0, 0, 0}, 152 | {"window activity", "wi", 0, 0, 0}, 153 | {"window item hilight", "W", 0, 0, 0}, 154 | {"window item activity", "Wi", 0, 0, 0}, 155 | {"window item new", "wW", 0, 0, 0}, 156 | {"window item remove", "wW", 0, 0, 0}, 157 | {"window item changed", "wW", 0, 0, 0}, 158 | {"window item server changed", "wW", 0, 0, 0}, 159 | {"window created", "w", 0, 0, 0}, 160 | {"window destroyed", "w", 0, 0, 0}, 161 | {"window changed", "ww", 0, 0, 0}, 162 | {"window changed automatic", "w", 0, 0, 0}, 163 | {"window server changed", "wS", 0, 0, 0}, 164 | {"window refnum changed", "wi", 0, 0, 0}, 165 | {"window name changed", "w", 0, 0, 0}, 166 | {"window history changed", "ws", 0, 0, 0}, 167 | {"window level changed", "w", 0, 0, 0}, 168 | {"message irc op_public", "Sssss", 0, 0, 0}, 169 | {"message irc own_wall", "Sss", 0, 0, 0}, 170 | {"message irc own_action", "Sss", 0, 0, 0}, 171 | {"message irc action", "Sssss", 0, 0, 0}, 172 | {"message irc own_notice", "Sss", 0, 0, 0}, 173 | {"message irc notice", "Sssss", 0, 0, 0}, 174 | {"message irc own_ctcp", "Ssss", 0, 0, 0}, 175 | {"message irc ctcp", "Ssssss", 0, 0, 0}, 176 | {"message irc mode", "Sssss", 0, 0, 0}, 177 | {"message dcc own", "ds", 0, 0, 0}, 178 | {"message dcc own_action", "ds", 0, 0, 0}, 179 | {"message dcc own_ctcp", "dss", 0, 0, 0}, 180 | {"message dcc", "ds", 0, 0, 0}, 181 | {"message dcc action", "ds", 0, 0, 0}, 182 | {"message dcc ctcp", "dss", 0, 0, 0}, 183 | {"gui key pressed", "i", 0, 0, 0}, 184 | {"beep", "", 0, 0, 0}, 185 | {NULL} 186 | }; 187 | 188 | #define py_sigmap_len() (sizeof(py_sigmap) / sizeof(py_sigmap[0]) - 1) 189 | -------------------------------------------------------------------------------- /src/objects/notifylist-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pyirssi_irc.h" 23 | #include "pymodule.h" 24 | #include "notifylist-object.h" 25 | #include "pycore.h" 26 | 27 | #define NOTIFYLIST(nl) ((NOTIFYLIST_REC *)nl) 28 | 29 | /* monitor "notifylist remove" signal */ 30 | static void notifylist_cleanup(NOTIFYLIST_REC *notifylist) 31 | { 32 | PyNotifylist *pynotifylist = signal_get_user_data(); 33 | 34 | if (notifylist == pynotifylist->data) 35 | { 36 | pynotifylist->data = NULL; 37 | pynotifylist->cleanup_installed = 0; 38 | signal_remove_data("notifylist remove", notifylist_cleanup, pynotifylist); 39 | } 40 | } 41 | 42 | static void PyNotifylist_dealloc(PyNotifylist *self) 43 | { 44 | if (self->cleanup_installed) 45 | signal_remove_data("notifylist remove", notifylist_cleanup, self); 46 | 47 | self->ob_type->tp_free((PyObject*)self); 48 | } 49 | 50 | static PyObject *PyNotifylist_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 51 | { 52 | PyNotifylist *self; 53 | 54 | self = (PyNotifylist *)type->tp_alloc(type, 0); 55 | if (!self) 56 | return NULL; 57 | 58 | return (PyObject *)self; 59 | } 60 | 61 | /* Getters */ 62 | PyDoc_STRVAR(PyNotifylist_mask_doc, 63 | "Notify nick mask" 64 | ); 65 | static PyObject *PyNotifylist_mask_get(PyNotifylist *self, void *closure) 66 | { 67 | RET_NULL_IF_INVALID(self->data); 68 | RET_AS_STRING_OR_NONE(NOTIFYLIST(self->data)->mask); 69 | } 70 | 71 | PyDoc_STRVAR(PyNotifylist_away_check_doc, 72 | "Notify away status changes" 73 | ); 74 | static PyObject *PyNotifylist_away_check_get(PyNotifylist *self, void *closure) 75 | { 76 | RET_NULL_IF_INVALID(self->data); 77 | return PyBool_FromLong(NOTIFYLIST(self->data)->away_check); 78 | } 79 | 80 | PyDoc_STRVAR(PyNotifylist_idle_check_time_doc, 81 | "Notify when idle time is reset and idle was bigger than this (seconds)" 82 | ); 83 | static PyObject *PyNotifylist_idle_check_time_get(PyNotifylist *self, void *closure) 84 | { 85 | RET_NULL_IF_INVALID(self->data); 86 | return PyLong_FromUnsignedLong(NOTIFYLIST(self->data)->idle_check_time); 87 | } 88 | 89 | /* specialized getters/setters */ 90 | static PyGetSetDef PyNotifylist_getseters[] = { 91 | {"mask", (getter)PyNotifylist_mask_get, NULL, 92 | PyNotifylist_mask_doc, NULL}, 93 | {"away_check", (getter)PyNotifylist_away_check_get, NULL, 94 | PyNotifylist_away_check_doc, NULL}, 95 | {"idle_check_time", (getter)PyNotifylist_idle_check_time_get, NULL, 96 | PyNotifylist_idle_check_time_doc, NULL}, 97 | {NULL} 98 | }; 99 | 100 | /* Methods */ 101 | PyDoc_STRVAR(PyNotifylist_ircnets_doc, 102 | "ircnets() -> list of str\n" 103 | "\n" 104 | "Return list of ircnets the notify is checked\n" 105 | ); 106 | static PyObject *PyNotifylist_ircnets(PyNotifylist *self, PyObject *args) 107 | { 108 | PyObject *list; 109 | char **nets; 110 | 111 | RET_NULL_IF_INVALID(self->data); 112 | 113 | nets = NOTIFYLIST(self->data)->ircnets; 114 | list = PyList_New(0); 115 | if (!list) 116 | return NULL; 117 | 118 | while (nets && *nets) 119 | { 120 | int ret; 121 | PyObject *str = PyString_FromString(*nets); 122 | 123 | if (!str) 124 | { 125 | Py_DECREF(list); 126 | return NULL; 127 | } 128 | 129 | ret = PyList_Append(list, str); 130 | Py_DECREF(str); 131 | if (ret != 0) 132 | { 133 | Py_DECREF(list); 134 | return NULL; 135 | } 136 | 137 | nets++; 138 | } 139 | 140 | return list; 141 | } 142 | 143 | PyDoc_STRVAR(PyNotifylist_ircnets_match_doc, 144 | "ircnets_match(ircnet) -> bool\n" 145 | "\n" 146 | "Return True if notify is checked in ircnet\n" 147 | ); 148 | static PyObject *PyNotifylist_ircnets_match(PyNotifylist *self, PyObject *args, PyObject *kwds) 149 | { 150 | static char *kwlist[] = {"ircnet", NULL}; 151 | char *ircnet = ""; 152 | 153 | RET_NULL_IF_INVALID(self->data); 154 | 155 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, 156 | &ircnet)) 157 | return NULL; 158 | 159 | return PyBool_FromLong(notifylist_ircnets_match(self->data, ircnet)); 160 | } 161 | 162 | /* Methods for object */ 163 | static PyMethodDef PyNotifylist_methods[] = { 164 | {"ircnets", (PyCFunction)PyNotifylist_ircnets, METH_NOARGS, 165 | PyNotifylist_ircnets_doc}, 166 | {"ircnets_match", (PyCFunction)PyNotifylist_ircnets_match, METH_VARARGS | METH_KEYWORDS, 167 | PyNotifylist_ircnets_match_doc}, 168 | {NULL} /* Sentinel */ 169 | }; 170 | 171 | PyTypeObject PyNotifylistType = { 172 | PyObject_HEAD_INIT(NULL) 173 | 0, /*ob_size*/ 174 | "irssi.Notifylist", /*tp_name*/ 175 | sizeof(PyNotifylist), /*tp_basicsize*/ 176 | 0, /*tp_itemsize*/ 177 | (destructor)PyNotifylist_dealloc, /*tp_dealloc*/ 178 | 0, /*tp_print*/ 179 | 0, /*tp_getattr*/ 180 | 0, /*tp_setattr*/ 181 | 0, /*tp_compare*/ 182 | 0, /*tp_repr*/ 183 | 0, /*tp_as_number*/ 184 | 0, /*tp_as_sequence*/ 185 | 0, /*tp_as_mapping*/ 186 | 0, /*tp_hash */ 187 | 0, /*tp_call*/ 188 | 0, /*tp_str*/ 189 | 0, /*tp_getattro*/ 190 | 0, /*tp_setattro*/ 191 | 0, /*tp_as_buffer*/ 192 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 193 | "PyNotifylist objects", /* tp_doc */ 194 | 0, /* tp_traverse */ 195 | 0, /* tp_clear */ 196 | 0, /* tp_richcompare */ 197 | 0, /* tp_weaklistoffset */ 198 | 0, /* tp_iter */ 199 | 0, /* tp_iternext */ 200 | PyNotifylist_methods, /* tp_methods */ 201 | 0, /* tp_members */ 202 | PyNotifylist_getseters, /* tp_getset */ 203 | 0, /* tp_base */ 204 | 0, /* tp_dict */ 205 | 0, /* tp_descr_get */ 206 | 0, /* tp_descr_set */ 207 | 0, /* tp_dictoffset */ 208 | 0, /* tp_init */ 209 | 0, /* tp_alloc */ 210 | PyNotifylist_new, /* tp_new */ 211 | }; 212 | 213 | 214 | /* window item wrapper factory function */ 215 | PyObject *pynotifylist_new(void *notifylist) 216 | { 217 | PyNotifylist *pynotifylist; 218 | 219 | pynotifylist = py_inst(PyNotifylist, PyNotifylistType); 220 | if (!pynotifylist) 221 | return NULL; 222 | 223 | pynotifylist->data = notifylist; 224 | pynotifylist->cleanup_installed = 1; 225 | signal_add_last_data("notifylist remove", notifylist_cleanup, pynotifylist); 226 | 227 | return (PyObject *)pynotifylist; 228 | } 229 | 230 | int notifylist_object_init(void) 231 | { 232 | g_return_val_if_fail(py_module != NULL, 0); 233 | 234 | if (PyType_Ready(&PyNotifylistType) < 0) 235 | return 0; 236 | 237 | Py_INCREF(&PyNotifylistType); 238 | PyModule_AddObject(py_module, "Notifylist", (PyObject *)&PyNotifylistType); 239 | 240 | return 1; 241 | } 242 | -------------------------------------------------------------------------------- /src/objects/nick-object.c: -------------------------------------------------------------------------------- 1 | /* 2 | irssi-python 3 | 4 | Copyright (C) 2006 Christopher Davis 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include "pymodule.h" 23 | #include "base-objects.h" 24 | #include "nick-object.h" 25 | #include "pyirssi.h" 26 | #include "pycore.h" 27 | #include "pyutils.h" 28 | 29 | static void nick_cleanup(CHANNEL_REC *chan, NICK_REC *nick) 30 | { 31 | PyNick *pynick = signal_get_user_data(); 32 | 33 | if (nick == pynick->data) 34 | { 35 | pynick->data = NULL; 36 | pynick->cleanup_installed = 0; 37 | signal_remove_data("nicklist remove", nick_cleanup, pynick); 38 | } 39 | } 40 | 41 | static void PyNick_dealloc(PyNick *self) 42 | { 43 | if (self->cleanup_installed) 44 | signal_remove_data("nicklist remove", nick_cleanup, self); 45 | 46 | self->ob_type->tp_free((PyObject*)self); 47 | } 48 | 49 | /* Getters */ 50 | PyDoc_STRVAR(PyNick_send_massjoin_doc, 51 | "Waiting to be sent in a 'massjoin' signal, True or False" 52 | ); 53 | static PyObject *PyNick_send_massjoin_get(PyNick *self, void *closure) 54 | { 55 | RET_NULL_IF_INVALID(self->data); 56 | return PyBool_FromLong(self->data->send_massjoin); 57 | } 58 | 59 | PyDoc_STRVAR(PyNick_nick_doc, 60 | "Plain nick" 61 | ); 62 | static PyObject *PyNick_nick_get(PyNick *self, void *closure) 63 | { 64 | RET_NULL_IF_INVALID(self->data); 65 | RET_AS_STRING_OR_NONE(self->data->nick); 66 | } 67 | 68 | PyDoc_STRVAR(PyNick_host_doc, 69 | "Host address" 70 | ); 71 | static PyObject *PyNick_host_get(PyNick *self, void *closure) 72 | { 73 | RET_NULL_IF_INVALID(self->data); 74 | RET_AS_STRING_OR_NONE(self->data->host); 75 | } 76 | 77 | PyDoc_STRVAR(PyNick_realname_doc, 78 | "Real name" 79 | ); 80 | static PyObject *PyNick_realname_get(PyNick *self, void *closure) 81 | { 82 | RET_NULL_IF_INVALID(self->data); 83 | RET_AS_STRING_OR_NONE(self->data->realname); 84 | } 85 | 86 | PyDoc_STRVAR(PyNick_hops_doc, 87 | "Hop count to the server the nick is using" 88 | ); 89 | static PyObject *PyNick_hops_get(PyNick *self, void *closure) 90 | { 91 | RET_NULL_IF_INVALID(self->data); 92 | return PyInt_FromLong(self->data->hops); 93 | } 94 | 95 | PyDoc_STRVAR(PyNick_gone_doc, 96 | "User status" 97 | ); 98 | static PyObject *PyNick_gone_get(PyNick *self, void *closure) 99 | { 100 | RET_NULL_IF_INVALID(self->data); 101 | return PyBool_FromLong(self->data->gone); 102 | } 103 | 104 | PyDoc_STRVAR(PyNick_serverop_doc, 105 | "User status" 106 | ); 107 | static PyObject *PyNick_serverop_get(PyNick *self, void *closure) 108 | { 109 | RET_NULL_IF_INVALID(self->data); 110 | return PyBool_FromLong(self->data->serverop); 111 | } 112 | 113 | PyDoc_STRVAR(PyNick_op_doc, 114 | "User status" 115 | ); 116 | static PyObject *PyNick_op_get(PyNick *self, void *closure) 117 | { 118 | RET_NULL_IF_INVALID(self->data); 119 | return PyBool_FromLong(self->data->op); 120 | } 121 | 122 | PyDoc_STRVAR(PyNick_voice_doc, 123 | "User status" 124 | ); 125 | static PyObject *PyNick_voice_get(PyNick *self, void *closure) 126 | { 127 | RET_NULL_IF_INVALID(self->data); 128 | return PyBool_FromLong(self->data->voice); 129 | } 130 | 131 | PyDoc_STRVAR(PyNick_halfop_doc, 132 | "User status" 133 | ); 134 | static PyObject *PyNick_halfop_get(PyNick *self, void *closure) 135 | { 136 | RET_NULL_IF_INVALID(self->data); 137 | return PyBool_FromLong(self->data->halfop); 138 | } 139 | 140 | PyDoc_STRVAR(PyNick_last_check_doc, 141 | "timestamp when last checked gone/ircop status." 142 | ); 143 | static PyObject *PyNick_last_check_get(PyNick *self, void *closure) 144 | { 145 | RET_NULL_IF_INVALID(self->data); 146 | return PyLong_FromUnsignedLong(self->data->last_check); 147 | } 148 | 149 | /* specialized getters/setters */ 150 | static PyGetSetDef PyNick_getseters[] = { 151 | {"send_massjoin", (getter)PyNick_send_massjoin_get, NULL, 152 | PyNick_send_massjoin_doc, NULL}, 153 | {"nick", (getter)PyNick_nick_get, NULL, 154 | PyNick_nick_doc, NULL}, 155 | {"host", (getter)PyNick_host_get, NULL, 156 | PyNick_host_doc, NULL}, 157 | {"realname", (getter)PyNick_realname_get, NULL, 158 | PyNick_realname_doc, NULL}, 159 | {"hops", (getter)PyNick_hops_get, NULL, 160 | PyNick_hops_doc, NULL}, 161 | {"gone", (getter)PyNick_gone_get, NULL, 162 | PyNick_gone_doc, NULL}, 163 | {"serverop", (getter)PyNick_serverop_get, NULL, 164 | PyNick_serverop_doc, NULL}, 165 | {"op", (getter)PyNick_op_get, NULL, 166 | PyNick_op_doc, NULL}, 167 | {"voice", (getter)PyNick_voice_get, NULL, 168 | PyNick_voice_doc, NULL}, 169 | {"halfop", (getter)PyNick_halfop_get, NULL, 170 | PyNick_halfop_doc, NULL}, 171 | {"last_check", (getter)PyNick_last_check_get, NULL, 172 | PyNick_last_check_doc, NULL}, 173 | {NULL} 174 | }; 175 | 176 | static PyMethodDef PyNick_methods[] = { 177 | {NULL} /* Sentinel */ 178 | }; 179 | 180 | PyTypeObject PyNickType = { 181 | PyObject_HEAD_INIT(NULL) 182 | 0, /*ob_size*/ 183 | "irssi.Nick", /*tp_name*/ 184 | sizeof(PyNick), /*tp_basicsize*/ 185 | 0, /*tp_itemsize*/ 186 | (destructor)PyNick_dealloc, /*tp_dealloc*/ 187 | 0, /*tp_print*/ 188 | 0, /*tp_getattr*/ 189 | 0, /*tp_setattr*/ 190 | 0, /*tp_compare*/ 191 | 0, /*tp_repr*/ 192 | 0, /*tp_as_number*/ 193 | 0, /*tp_as_sequence*/ 194 | 0, /*tp_as_mapping*/ 195 | 0, /*tp_hash */ 196 | 0, /*tp_call*/ 197 | 0, /*tp_str*/ 198 | 0, /*tp_getattro*/ 199 | 0, /*tp_setattro*/ 200 | 0, /*tp_as_buffer*/ 201 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 202 | "PyNick objects", /* tp_doc */ 203 | 0, /* tp_traverse */ 204 | 0, /* tp_clear */ 205 | 0, /* tp_richcompare */ 206 | 0, /* tp_weaklistoffset */ 207 | 0, /* tp_iter */ 208 | 0, /* tp_iternext */ 209 | PyNick_methods, /* tp_methods */ 210 | 0, /* tp_members */ 211 | PyNick_getseters, /* tp_getset */ 212 | &PyIrssiChatBaseType, /* tp_base */ 213 | 0, /* tp_dict */ 214 | 0, /* tp_descr_get */ 215 | 0, /* tp_descr_set */ 216 | 0, /* tp_dictoffset */ 217 | 0, /* tp_init */ 218 | 0, /* tp_alloc */ 219 | 0, /* tp_new */ 220 | }; 221 | 222 | 223 | /* nick factory function */ 224 | PyObject *pynick_sub_new(void *nick, PyTypeObject *subclass) 225 | { 226 | static const char *name = "NICK"; 227 | PyNick *pynick = NULL; 228 | 229 | pynick = py_instp(PyNick, subclass); 230 | if (!pynick) 231 | return NULL; 232 | 233 | pynick->data = nick; 234 | pynick->base_name = name; 235 | signal_add_last_data("nicklist remove", nick_cleanup, pynick); 236 | pynick->cleanup_installed = 1; 237 | 238 | return (PyObject *)pynick; 239 | } 240 | 241 | PyObject *pynick_new(void *nick) 242 | { 243 | return pynick_sub_new(nick, &PyNickType); 244 | } 245 | 246 | int nick_object_init(void) 247 | { 248 | g_return_val_if_fail(py_module != NULL, 0); 249 | 250 | if (PyType_Ready(&PyNickType) < 0) 251 | return 0; 252 | 253 | Py_INCREF(&PyNickType); 254 | PyModule_AddObject(py_module, "Nick", (PyObject *)&PyNickType); 255 | 256 | return 1; 257 | } 258 | --------------------------------------------------------------------------------