The Power To Change

Posted on by Chris Warburton

As I've blogged about before, I'm currently working on a general purpose Python library which implements an entity in the XMPP/Jabber Publish/Subscribe specification XEP-0060. The library itself can currently send equivalent stanzas to all of the examples given in the specification. It does not yet handle the replies from everything, doesn't handle incoming messages (ie. updates) and its error handling consists of printing the error stanza to the terminal. However, at around 1,500 lines it's already a bit too much to grasp with only a specification to go on. For this reason, once I had implemented every needed method I decided to take a pragmatic approach to the reply and message handling.

This originally started as a PubSub reader application, similar in form and function to current news reader applications like Akregator and Liferea but using PubSub nodes instead of RSS or ATOM files. This proceeded quite nicely until I hit a bit of a wall: There wasn't anything to read!

To fix this I started to write a PubSub writer application, similar in form and function to current offline blogging applications like KBlogger and Gnome Blog but once again using PubSub nodes instead of RSS or ATOM files, or Web service APIs. This was a bit premature of me, however, since there was nowhere to write things TO, and then I came across x60br and thought it would be the perfect kind of tool to make next, thus I started a simple PubSub browser.

The concept of the PubSub browser I am making is simple, and I have blogged about it before. You're presented with a window containing minimal controls. Into a text box at the top the address of a PubSub-capable server is put, then the "Get" button next to it is pressed. The browser then adds this server to a tree view and uses the PubSub library to send a message to the given server, asking for a list of the nodes it contains. When a reply is received any nodes are added to the tree in a level below the server. Each of these nodes is then queried for any nodes that they may contain, and when the replies come in they are added to a level below their respective parents. This isn't quite a perfect way of doing things since it doesn't take into account the loops which the PubSub system allows, but is good enough for this tool's purposes.

With a tree of nodes available the next step to take was implementing some ability to alter the structure, ie. add, remove, change parents, etc. I've now achieved this, as can be seen in the following screenshot of my current ejabberd server.

Until this point the choice of server hadn't mattered to me (it's all standardised), and since ejabberd is a) packaged in Debian and b) all the rage these days, I figured it was worth using. There are currently VERY few servers which can actually understand PubSub, the most popular being ejabberd and OpenFire (the former being used by jabber.org and the latter being used by the University of Sheffield), but since it's such a new technology there are issues arising with its server-side implementation (which my library is not designed to address). Essentially ejabberd is currently a bit broken, the most important deviations from the standard being that it allows items to be published to a collection (analogous to writing text to a folder, rather than to a file inside the folder), it allows leaf nodes to contain children (analogous to a file containing other files and folders (OK this is possible with archives, but that's not the point :P )) and it doesn't allow subscribing to a collection. Aside from those, a rather obvious restriction (although still standards-compliant, as far as I can tell) is that a rigid filesystem-like structure must be adhered to, with node names following the structure /home/servername/username/... This means that pressing the Add button when the server, /home, /pubsub or /pubsub/nodes is selected will result in a failure, and with /home/localhost selected only one name is allowed, /home/localhost/test1 (since the browser is logged in as the user test1). However, it does work as can be seen (I've created the node /home/localhost/test1), and in the process I've managed to delete quite a lot of code from the library (note for non-programmers: The more code you can throw away, the easier your life becomes :P )

Next on the agenda is deleting nodes. If I can't get that done today, however, then I probably won't get it done until Wednesday. I'm going to see Jooooooooooooooooooooooooooooooooooooooooooooooo...ingtons.

PS: If you want to get the code I've set up a git repository here.