Cross platform Akonadi video

Here’s my very first screen cast showing the synchronisation between Akonadi applications using different APIs:

OGG link

In the video, I change addresses in KAddressBook, and the entries in gtkAddressBook are immediately updated too. It would work the other way around too if the code was more complete, but python-twisted-akonadi is just getting started, so most features are not implemented yet.

This is a follow up to my previous blog about a Gtk Akonadi library.

Model/View design

The reason the synchronisation works is all down to the design of Akonadi. There is an architecture diagram here showing the basic principle of the design. The main feature is that all communication with Akonadi is done in a platform neutral way using D-Bus for notifications and an IMAP-like protocol for data transfer. One of the principle benefits of that is that most modern platforms already have libraries for dealing with D-Bus and IMAP, so there is a natural starting point for any Akonadi client implementation. The KDE API and the python API hide those implementation details, and provide ways for applications to fetch, delete, change and move items, and to receive notifications when another process or application performs one of those actions. That means that any application written in any language on any platform can access and modify the data in Akonadi, and the changes would be synchronised everywhere else.

The applications are not communicating with each other via plugins. That’s KDE 3 design and it doesn’t scale very well and leads to a lot of duplication. For example, a fully working Kontact has the complete address book in memory 6 times! The applications aren’t even aware that other applications exist. They’re all part of a macro scale Model/View pattern where each application is a View, and Akonadi is the Model.

This could be useful if for example you want to use gtkAddressBook instead of KAddressBook (hypothetically šŸ™‚ ), but you still want auto-completion of your contacts in KMail. Because the contacts are accessed through Akonadi, not the address book application, that would work just fine. For the user, it seems that ‘My contacts are in KAddressBook’, but because the technical reality is different, any other applications can use the same data in a versatile way.

Low level implementation

So how does a motivated developer implement Akonadi support for a new platform? A good starting point is finding existing frameworks for IMAP parsing, asynchronous communication, Unix socket communication (or named pipes on Windows), flexible event loops, and D-Bus support. As I chose to write an Akonadi library in python, I could easily find existing code for all of those pieces. python-dbus provides the D-Bus support, and I was quickly directed to Twisted python which provides the rest.

Twisted has some central components like reactors which provide an event loop and reading/writing to network sockets, deferreds, which fulfil a role similar to KJob in that they make asynchronous programming easy, and implementations of clients and servers in many different protocols. The only one needed for Akonadi is twisted-mail, which provides an IMAP parser and lots of convenience to hide the implementation details of the actual communication of the data.

I’ve written several times that the protocol Akonadi uses is Almost IMAP. The protocol mostly follows the IMAP standard, but it has some non-standard extensions which bring the flexibility and performance needed in a PIM system. One of the benefits of the python language is that all methods on classes behave as if they were virtual methods in C++. They can be overridden in subclasses and the overridden version will always be called. By implementing an overridden method in the twisted.imap4.IMAP4Client, I could implement support for the non-standard extensions and let the base class handle the rest (all the difficult stuff).

The next step was to enable serialisation to and from standard PIM types, like RFC822 messages, vCards, iCal entries etc. Again, python already has several high quality libraries for parsing and generating these types, and thanks to dynamic typing, handling the types can be done in a generic way, leading to even more type independence in the library.

The bit about models

The high level part of the KDE Akonadi libraries is the EntityTreeModel which simplifies data in Akonadi into a tree structure for use in a GUI. High level API will always be toolkit dependent, so I needed to choose a GUI toolkit to get the high level stuff started. PyGtk has a TreeStore class which provide an API somewhat similar to QStandardItemModel in that it allows creation of a tree of items on a conceptual level (the model), a TreeView class, somewhat simliar to QTreeView, and a CellRenderer somewhat similar to a QItemDelegate. Gtk also provides proxy models for sorting and filtering.

The gtkAkonadi.EntityTreeStore is the conceptual equivalent to the EntityTreeModel in the python API. It is a generic model for storing the data from Akonadi. There are also two existing subclasses, the MailTreeStore and ContactsTreeStore, which make a tree of Akonadi.Items appear as emails or contacts respectively. The rest is pure PyGtk code to make a real application out of those classes.

Fin

Akonadi with interfaces in multiple toolkits

Akonadi with interfaces in multiple toolkits

PIM could be shared across the whole free desktop, with cross platform Akonadi at the center of it all. Getting this far with the python API was remarkably simple, considering that I only started writing the code a week and a half ago, and didn’t have a lot of time to spend on it. There’s a long way to go, but if you want to help out on the python API or another client for any other toolkit, we can get you started on kde-pim@kde.org or #akonadi on freenode.

5 Responses to “Cross platform Akonadi video”

  1. Raul Says:

    This is awesome. Akonadi is one of the most exciting developments happening in KDE right now, I can’t wait for a fully akonadi-ported kontact.

  2. James Says:

    I’m curious to hear what you might think about implementing more instantaneous, diverse or high volume backends.

    I’m considering taking a stab at implementing chat protocols such as jabber using akonadi, to write a client that can be expanded in the future, that shares backends through akonadi. Unfortunately I’m too weak in this kind of development to know if it’s a good idea.
    The app would start of kopete/pidgin like, but I’d like to expand it to handle u-blogs, mail notifications and even social networking like myspace and facebook in the future.
    It would be a dream to get something like Googles new system implemented over jabber.
    I figure that a jabber backend would be a good place to start to get to know the akonadi system.

    While akonadi is obviously a great place to store account information and chat contacts, is it too much to ask it to handle such frequent communication such as say 10 chat accounts, 2 blogs, and a facebook account.
    I can imagine that for some people, DBUS would constantly be active to handle the messages for events and messages. Of course, file sharing would have to be handled carefully.

    I like the idea of a single instant communicator, even if it’s mainly for notifications, opening other apps when desired. I just think that if akonadi/dbus would work well with this, then it would be the best place to start

  3. steveire Says:

    @Raul: It’s in heavy development at the moment, and we’re having a developer sprint this weekend, but a Kontact based fully on Akonadi is still some time away.

    @James: There was a summer of code project about storing Kopete chat logs in Akonadi: http://dot.kde.org/2009/09/26/what-i-did-my-summer-holiday.

    I don’t know the details, but I’ll try to find out or convince Kaushik to blog about it.

    Because only notifications are transferred over D-Bus, and not actual data, it’s not too much traffic.

    There’s also optimizations available like http://websvn.kde.org/?view=revision&revision=1032308 and http://websvn.kde.org/?view=revision&revision=1031825, also described here: https://steveire.wordpress.com/2009/10/06/cache-invalidation-in-akonadi-models/

    Depending on how it’s implemented, the impact could be unnoticeable.

  4. Akonadi goes Web2.0 « Steveire’s Blog Says:

    […] Steveire’s Blog Just another WordPress.com weblog « Cross platform Akonadi video […]

  5. Data fragmentation between ‘owning’ services? « Steveire's Blog Says:

    […] they might think it depends on something fictional like the KDE desktop environment, which is clearly not the case. The point is though that non-adoption of common infrastructures between different […]

Leave a comment