Using python-purple with the twisted mainloop

libpurple is the instant messaging library underlying the Pidgin and Adium multi-protocol IM clients. Out of the box libpurple supports a wide variety of protocols accessible via a consistent programmatic interface. The Carman project provides a set of python bindings for libpurple. The source for the bindings can be checked out from SVN at http://vcs.maemo.org/svn/carman/trunk/python-purple/.

The python-purple bindings are provided as a set of .pyx files that must be compiled into a Python module using Cython. Instructions on compiling the module are available at http://briglia.net/wiki/tiki-index.php?page=Python-purple+Howto. Although the instructions mention Python 2.5, they work fine when Python 2.6 is used.

The trunk version of the python-purple bindings utilizes python-ecore (a python abstraction of the core libraries used by Enlightenment) to manage the main loop. If you wish to use the twisted mainloop instead simply apply the following patch (python-purple-twisted.patch) and recompile the module.

Index: python-purple/purple.pyx
===================================================================
--- python-purple/purple.pyx	(revision 2088)
+++ python-purple/purple.pyx	(working copy)
@@ -22,8 +22,8 @@
 cdef extern from "c_purple.h":
     glib.guint glib_input_add(glib.gint fd, eventloop.PurpleInputCondition condition, eventloop.PurpleInputFunction function, glib.gpointer data)
 
-import ecore
 import signal
+from twisted.internet import reactor
 
 cdef glib.GHashTable *c_ui_info
 
@@ -91,8 +91,8 @@
         if default_path:
             util.purple_util_set_user_dir(default_path)
 
-        # adds glib iteration inside ecore main loop
-        ecore.timer_add(0.001, self.__glib_iteration_when_idle)
+        # adds glib iteration inside twisted main loop
+        reactor.callLater(0.001, self.__glib_iteration_when_idle)
 
         # libpurple's built-in DNS resolution forks processes to perform
         # blocking lookups without blocking the main process.  It does not
@@ -171,7 +171,7 @@
 
     def __glib_iteration_when_idle(self):
         glib.g_main_context_iteration(NULL, False)
-        return True
+        reactor.callLater(0.001, self.__glib_iteration_when_idle)
 
     def purple_init(self):
         '''Initializes the purple.
Index: python-purple/conversation_cbs.pxd
===================================================================
--- python-purple/conversation_cbs.pxd	(revision 2088)
+++ python-purple/conversation_cbs.pxd	(working copy)
@@ -104,7 +104,7 @@
         message = None
 
     # FIXME: Maybe we need add more purple flags in the future
-    if flags & conversation.PURPLE_MESSAGE_SEND:
+    if int(flags) & conversation.PURPLE_MESSAGE_SEND:
         flag = "SEND"
     else:
         flag = "RECV"
Index: python-purple/nullclient.py
===================================================================
--- python-purple/nullclient.py	(revision 2088)
+++ python-purple/nullclient.py	(working copy)
@@ -17,7 +17,7 @@
 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-import ecore
+from twisted.internet import reactor
 import getpass
 import purple
 import sys
@@ -60,5 +60,7 @@
     # Enable account (connects automatically)
     account.set_enabled(True)
 
-    # Initializes ecore mainloop
-    ecore.main_loop_begin()
+    # Start twisted mainloop
+    reactor.run()
+
+
Bookmark and Share

Leave a Reply