From 914326e7528712bb501aa9267b4156a4da4ee358 Mon Sep 17 00:00:00 2001 From: Ragner Magalhaes Date: Tue, 2 Dec 2008 20:25:07 +0000 Subject: [PATCH] Added initial support for user-specified conversation callbacks. FIXES: - UiOps structures are now global. - Initial support for user-specified conversation callbacks. Signed-off-by: Bruno Abinader git-svn-id: https://garage.maemo.org/svn/carman/branches/carman-0.7-beta2/python-purple@1301 596f6dd7-e928-0410-a184-9e12fd12cf7e --- conversation_cbs.pxd | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++ nullclient.py | 28 ++++++++- purple.pyx | 96 +++++++++++++++++++---------- 3 files changed, 253 insertions(+), 34 deletions(-) create mode 100644 conversation_cbs.pxd diff --git a/conversation_cbs.pxd b/conversation_cbs.pxd new file mode 100644 index 0000000..3c5aec1 --- /dev/null +++ b/conversation_cbs.pxd @@ -0,0 +1,163 @@ +# +# Copyright (c) 2008 INdT - Instituto Nokia de Tecnologia +# +# This file is part of python-purple. +# +# python-purple is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# python-purple is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +cimport purple + +cdef extern from *: + ctypedef char const_char "const char" + ctypedef glib.guchar const_guchar "const guchar" + +cdef extern from "time.h": + ctypedef long int time_t + +conversations_cbs = {} + +cdef void create_conversation (conversation.PurpleConversation *conv): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "create_conversation\n") + global conversations_cbs + try: + (conversations_cbs["create_conversation"])("create_conversation") + except KeyError: + pass + +cdef void destroy_conversation (conversation.PurpleConversation *conv): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "destroy_conversation\n") + global conversations_cbs + try: + (conversations_cbs["destroy_conversation"])("destroy_conversation") + except KeyError: + pass + +cdef void write_chat (conversation.PurpleConversation *conv, const_char *who, + const_char *message, conversation.PurpleMessageFlags flags, + time_t mtime): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "write_chat\n") + global conversations_cbs + try: + (conversations_cbs["write_chat"])("write_chat") + except KeyError: + pass + +cdef void write_im (conversation.PurpleConversation *conv, const_char *who, + const_char *message, conversation.PurpleMessageFlags flags, + time_t mtime): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "write_im\n") + global conversations_cbs + try: + (conversations_cbs["write_im"])("write_im") + except KeyError: + pass + +cdef void write_conv (conversation.PurpleConversation *conv, const_char *name, + const_char *alias, const_char *message, + conversation.PurpleMessageFlags flags, time_t mtime): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "write_conv\n") + global conversations_cbs + try: + (conversations_cbs["write_conv"])("write_conv") + except KeyError: + pass + +cdef void chat_add_users (conversation.PurpleConversation *conv, + glib.GList *cbuddies, glib.gboolean new_arrivals): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "chat_add_users\n") + global conversations_cbs + try: + (conversations_cbs["chat_add_users"])("chat_add_users") + except KeyError: + pass + +cdef void chat_rename_user (conversation.PurpleConversation *conv, + const_char *old_name, const_char *new_name, + const_char *new_alias): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "chat_rename_user\n") + global conversations_cbs + try: + (conversations_cbs["chat_rename_user"])("chat_rename_user") + except KeyError: + pass + +cdef void chat_remove_users (conversation.PurpleConversation *conv, + glib.GList *users): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "chat_remove_users\n") + global conversations_cbs + try: + (conversations_cbs["chat_remove_users"])("chat_remove_users") + except KeyError: + pass + +cdef void chat_update_user (conversation.PurpleConversation *conv, const_char *user): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "chat_update_user\n") + global conversations_cbs + try: + (conversations_cbs["chat_update_user"])("chat_update_user") + except KeyError: + pass + +cdef void present (conversation.PurpleConversation *conv): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "present\n") + global conversations_cbs + try: + (conversations_cbs["present"])("present") + except KeyError: + pass + +cdef glib.gboolean has_focus (conversation.PurpleConversation *conv): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "has_focus\n") + global conversations_cbs + try: + (conversations_cbs["has_focus"])("has_focus") + return False + except KeyError: + return False + +cdef glib.gboolean custom_smiley_add (conversation.PurpleConversation *conv, + const_char *smile, glib.gboolean remote): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "custom_smiley_add\n") + global conversations_cbs + try: + (conversations_cbs["custom_smiley_add"])("custom_smiley_add") + return False + except KeyError: + return False + +cdef void custom_smiley_write (conversation.PurpleConversation *conv, + const_char *smile, const_guchar *data, + glib.gsize size): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "custom_smiley_write\n") + try: + (conversations_cbs["custom_smiley_write"])("custom_smiley_write") + except KeyError: + pass + + +cdef void custom_smiley_close (conversation.PurpleConversation *conv, + const_char *smile): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "custom_smiley_close\n") + try: + (conversations_cbs["custom_smiley_close"])("custom_smiley_close") + except KeyError: + pass + +cdef void send_confirm (conversation.PurpleConversation *conv, const_char *message): + debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "conversation", "send_confirm\n") + try: + (conversations_cbs["send_confirm"])("send_confirm") + except KeyError: + pass diff --git a/nullclient.py b/nullclient.py index d0fcb9b..2e82c9c 100644 --- a/nullclient.py +++ b/nullclient.py @@ -3,13 +3,38 @@ import ecore import getpass import sys +cbs = {} +conv_cbs = {} + +def callback(name): + print "---- callback example: %s" % name + +conv_cbs["create_conversation"] = callback +conv_cbs["destroy_conversation"] = callback +conv_cbs["write_chat"] = callback +conv_cbs["write_im"] = callback +conv_cbs["write_conv"] = callback +conv_cbs["chat_add_users"] = callback +conv_cbs["chat_rename_user"] = callback +conv_cbs["chat_remove_users"] = callback +conv_cbs["chat_update_user"] = callback +conv_cbs["present"] = callback +conv_cbs["has_focus"] = callback +conv_cbs["custom_smiley_add"] = callback +conv_cbs["custom_smiley_write"] = callback +conv_cbs["custom_smiley_close"] = callback +conv_cbs["send_confirm"] = callback + +cbs["conversation"] = conv_cbs + class NullClient: def __init__(self): self.p = purple.Purple() self.account = None def execute(self): - self.p.purple_init() + global cbs + self.p.purple_init(cbs) def set_protocol(self, protocol): for i in self.p.get_protocols(): @@ -23,7 +48,6 @@ class NullClient: self.account = purple.Account(username, protocol) self.account.set_password(password) self.account.set_enabled("carman-purple-python", True) - def get_buddies(self): buddies = self.account.get_buddies_online() print buddies diff --git a/purple.pyx b/purple.pyx index 79e553a..df17ba0 100644 --- a/purple.pyx +++ b/purple.pyx @@ -28,6 +28,15 @@ __DEFAULT_PATH__ = "/tmp" __APP_NAME__ = "carman-purple-python" __APP_VERSION__ = "0.1" +cdef core.PurpleCoreUiOps c_core_ui_ops +cdef conversation.PurpleConversationUiOps c_conv_ui_ops +cdef eventloop.PurpleEventLoopUiOps c_eventloop_ui_ops +cdef glib.GHashTable *c_ui_info + +c_ui_info = NULL + +include "conversation_cbs.pxd" + cdef class Purple: """ Purple class. @@ -36,13 +45,7 @@ cdef class Purple: @parm default_path: Full path for libpurple user files. """ - cdef core.PurpleCoreUiOps c_core_ui_ops - cdef eventloop.PurpleEventLoopUiOps c_eventloop_ui_ops - cdef glib.GHashTable *c_ui_info - def __init__(self, debug_enabled=True, app_name=__APP_NAME__, default_path=__DEFAULT_PATH__): - self.c_ui_info = NULL - if app_name is not __APP_NAME__: __APP_NAME__ = app_name @@ -71,11 +74,16 @@ cdef class Purple: cdef void __core_ui_ops_ui_init(self): debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "core_ui_ops", "ui_init\n") + global c_conv_ui_ops + + conversation.c_purple_conversations_set_ui_ops(&c_conv_ui_ops) # FIXME: Add core ui initialization here cdef void __core_ui_ops_quit(self): debug.c_purple_debug(debug.PURPLE_DEBUG_INFO, "core_ui_ops", "quit\n") + global c_ui_info + account.c_purple_accounts_set_ui_ops(NULL) connection.c_purple_connections_set_ui_ops(NULL) blist.c_purple_blist_set_ui_ops(NULL) @@ -85,41 +93,65 @@ cdef class Purple: ft.c_purple_xfers_set_ui_ops(NULL) roomlist.c_purple_roomlist_set_ui_ops(NULL) - if self.c_ui_info: - glib.g_hash_table_destroy(self.c_ui_info) + if c_ui_info: + glib.g_hash_table_destroy(c_ui_info) cdef glib.GHashTable *__core_ui_ops_get_ui_info(self): - if self.c_ui_info == NULL: - self.c_ui_info = glib.g_hash_table_new(glib.g_str_hash, glib.g_str_equal) + global c_ui_info - glib.g_hash_table_insert(self.c_ui_info, "name", __APP_NAME__) - glib.g_hash_table_insert(self.c_ui_info, "version", __APP_VERSION__) - return self.c_ui_info + if c_ui_info == NULL: + c_ui_info = glib.g_hash_table_new(glib.g_str_hash, glib.g_str_equal) + + glib.g_hash_table_insert(c_ui_info, "name", __APP_NAME__) + glib.g_hash_table_insert(c_ui_info, "version", __APP_VERSION__) + return c_ui_info def __glib_iteration_when_idle(self): glib.g_main_context_iteration(NULL, False) return True - def purple_init(self): + def purple_init(self, callbacks_dict=None): """ Initializes libpurple """ - # initialize c_core_ui_ops structure - self.c_core_ui_ops.ui_prefs_init = self.__core_ui_ops_ui_prefs_init - self.c_core_ui_ops.debug_ui_init = self.__core_ui_ops_debug_init - self.c_core_ui_ops.ui_init = self.__core_ui_ops_ui_init - self.c_core_ui_ops.quit = self.__core_ui_ops_quit - self.c_core_ui_ops.get_ui_info = self.__core_ui_ops_get_ui_info - - core.c_purple_core_set_ui_ops(&self.c_core_ui_ops) - - # initialize c_eventloop_ui_ops structure - self.c_eventloop_ui_ops.timeout_add = glib.g_timeout_add - self.c_eventloop_ui_ops.timeout_remove = glib.g_source_remove - self.c_eventloop_ui_ops.input_add = glib_input_add - self.c_eventloop_ui_ops.input_remove = glib.g_source_remove - self.c_eventloop_ui_ops.input_get_error = NULL - self.c_eventloop_ui_ops.timeout_add_seconds = glib.g_timeout_add_seconds - - eventloop.c_purple_eventloop_set_ui_ops(&self.c_eventloop_ui_ops) + + global c_conv_ui_ops + global c_core_ui_ops + global c_eventloop_ui_ops + + if callbacks_dict is not None: + global conversations_cbs + conversations_cbs = callbacks_dict["conversation"] + + c_conv_ui_ops.create_conversation = create_conversation + c_conv_ui_ops.destroy_conversation = destroy_conversation + c_conv_ui_ops.write_chat = write_chat + c_conv_ui_ops.write_im = write_im + c_conv_ui_ops.write_conv = write_conv + c_conv_ui_ops.chat_add_users = chat_add_users + c_conv_ui_ops.chat_rename_user = chat_rename_user + c_conv_ui_ops.chat_remove_users = chat_remove_users + c_conv_ui_ops.chat_update_user = chat_update_user + c_conv_ui_ops.present = present + c_conv_ui_ops.has_focus = has_focus + c_conv_ui_ops.custom_smiley_add = custom_smiley_add + c_conv_ui_ops.custom_smiley_write = custom_smiley_write + c_conv_ui_ops.custom_smiley_close = custom_smiley_close + c_conv_ui_ops.send_confirm = send_confirm + + c_core_ui_ops.ui_prefs_init = self.__core_ui_ops_ui_prefs_init + c_core_ui_ops.debug_ui_init = self.__core_ui_ops_debug_init + c_core_ui_ops.ui_init = self.__core_ui_ops_ui_init + c_core_ui_ops.quit = self.__core_ui_ops_quit + c_core_ui_ops.get_ui_info = self.__core_ui_ops_get_ui_info + + c_eventloop_ui_ops.timeout_add = glib.g_timeout_add + c_eventloop_ui_ops.timeout_remove = glib.g_source_remove + c_eventloop_ui_ops.input_add = glib_input_add + c_eventloop_ui_ops.input_remove = glib.g_source_remove + c_eventloop_ui_ops.input_get_error = NULL + c_eventloop_ui_ops.timeout_add_seconds = glib.g_timeout_add_seconds + + core.c_purple_core_set_ui_ops(&c_core_ui_ops) + eventloop.c_purple_eventloop_set_ui_ops(&c_eventloop_ui_ops) # initialize purple core ret = core.c_purple_core_init(__APP_NAME__) -- 1.7.9.5