Rate this:

just a note to self for when my android samaung galaxy s2 i9100 (I think) says it’s run out of space to install updates but the storage manager says apps are only using up half the internal space.
dial *#9900# and a system menu will appear. select ‘delete dumpstate/logcat’ too free up space.
feel free to tell me what that actually does!
took me months to find this on the web .. was just about to upgrade purely over this issue!

next up is the Channel Manager. here we extend the telepathy-python ChannelManager by specifying which channel types can be created (just the text type here) and by providing a callback to create a new channel of that type.

you can see at the end there that the callback returns a caveTextChannel object. can you guess what that is?! yup, we’re extending telepathy-python’s ChannelTypeText class in order to provide a Channel.Type.Text interface for our Channel object. here we add the following:

override the Send method to issue the appropriate signals including the received ‘echo’ of the sent message

override the Close method to shut things down nicely and issue signals

we really ought to use the newer SendMessage method but the old Send is simpler and, i think, sufficient for this demonstration.

save that lot and fire up empathy (or equivalent) and add an ‘echo’ account. since we haven’t implemented a contact list (as there aren’t actually any real contacts out there) you need to start conversations ‘blind’ – go to ‘New Conversation…’ in the ‘Chat’ menu, make up a contact name and click ‘Chat’. a chat window should appear and any message you ‘send’ should get sent right back to you.

the "five year old child" chat protocol

next up, extend the Connection and Channel to talk to a Real Thing – any Real Thing you like! i’m using email. 🙂

do leave a comment if you use this to ‘chat’ with any other non-chat things.

so, several days of experimentation, reading telepathy-python and butterfly source got me a working email connector and i thought it’d be useful to strip that down even further to an “echo” connector – which just repeats anything you say, like an annoying kid brother, as a reference and example.

what i’ve NOT created is a “reference implementation” – i don’t understand the dbus API docs well enough for that. i think i’ve left out lots of required elements. but it Works™ – at least empathy will let me create an account, start a new conversation and type stuff, which gets repeated. i can disable and re-enable the account without breaking anything – which is nice.

so, today:

step 1 – advertising the service

the spec says we should have a name for the messaging protocol we’re implementing and a different name for the program which implements it. so i’m calling the protocol “echo” and the program “cave”. the actual script will be called “telepathy-cave” in line with similar programs.

here’s the code for the main program:

#!/usr/bin/python
# IMPORTANT! makes asynchronous dbus things work
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
# get the mainloop before creating the ConnectionManager
# so that dbus (telepathy) can use it
from gobject import MainLoop
ml = MainLoop()
from cave import caveConnectionManager
# get telepathy to start listening for our dbus stuff via the mainloop
caveConnectionManager()
# and ... Go!
ml.run()

the most obvious thing is that it’s running a gobject MainLoop – you wouldn’t want it setting up the Connection Manager and then quitting! the dbus python library uses the mainloop to do it’s event-driven stuff.

that DBusGMainLoop() had me foxed for days. the error message you get if you miss it out:

RuntimeError: To make asynchronous calls, receive signals or export objects, D-Bus connections must be attached to a main loop by passing mainloop=… to the constructor or calling dbus.set_default_main_loop(…)

isn’t all that helpful – since we can’t fix it by “passing mainloop=” or by “calling dbus.set_default_main_loop” because it’s telepathy-python that’s doing that bit. googling for telepathy gets a whole bunch of unhelpful E.S.P. articles! and the butterfly code uses the old way of doing this .. which is Evil™! – it goes like this:

# DON'T DO THIS!
import dbus.glib

nope, i haven’t missed anything out there – just importing the module makes a critical something happen. like i said, not good. glad they’ve got rid of that – just need to update butterfly to use the new method! once i’d figured this out i noticed that all the current examples in the documentation do this right – it’s even the very first piece of example code – unfortunately i’d given up looking there because it all seemed client-based.

anyhoo, the last thing that happens before we kick off the MainLoop is we import and create the caveConnectionManager. that’s my telepathy Connection Manager which looks like this (you can save this as cave.py):

the connection manager sets itself up on the dbus session bus letting the world know that it can create telepathy connections to handle a certain set of protocols – in this case, only “echo”. when a client requests (over dbus) a ‘echo’ connection the connection manager will create a new Connection instance to handle the request.

you can see that the telepathy module has done plenty of the work for us – there’s no code here for talking to dbus or handling client requests – we just need to tell it our name and what protocol we’re providing and what class does the actual work. it’s even set up the GetParameters dbus method for us – we just override it to provide the correct response.

to complete the picture we need a couple more files – Constants.py and Connection.py. Constants is nice and easy:

#!/usr/bin/python
PROTOCOL = 'echo'
PROGRAM = 'cave'

i just put them there so they didn’t get duplicated across files. Connection.py will get a bit more involved later on but here’s what it looks like for now while it’s not doing anything at all:

#!/usr/bin/python
from telepathy.server import Connection
from Constants import PROTOCOL, PROGRAM
class caveConnection(Connection):
def __init__(self, manager, parameters):
# assume we have an 'account' name passed to us
Connection.__init__(self, PROTOCOL, parameters['account'], PROGRAM)

so, much like the Connection Manager, we let the telepathy module do the work, implementing the basis of the Connection interface API for us.

if you save that lot and run telepathy-cave then you should see “echo” in the list of protocols available in empathy’s “add new account” interface and you should be able to create a new account using it.