Zeitgeist daemon extensions explained

While working on this Zeitgeist bug #612344 I recalled that Stuart Langridge had once quoted

Zeitgeist has extensions. These aren’t brilliantly documented yet, but you can drop a Python file into .local/share/zeitgeist/extensions and if it’s got the right sort of class in it then that class will get run as a part of Zeitgeist.

Sometimes it is said that code is the best documentation. This becomes the only solution when there is no documentation available on wikis or help pages. When working on that bug, I started hunting for documentation on the web. After a few minutes I understood that looking at the extension code is the best way to go ahead.

How extensions are searched and loaded

Every extension needs to inherit Extension base class which is present in _zeitgeist.engine.extension namespace. So basically the first line has to be

from _zeitgeist.engine.extension import Extension

When the daemon is started, it looks for the environment variable named ZEITGEIST_DEFAULT_EXTENSIONS to hunt the extensions which are supposed to be loaded. If this is not set then extensiondir variable contains the path of all the extensions. You can know about this

>>> from zeitgeist._config import extensiondir

>>> extensiondir


It even searches for the extensions in your local path. This means an extension can be enabled globally as well as locally. The path in your local home directory is the one fetched by

>>> from _zeitgeist.engine import constants



All these files are then scanned for class which inherits Extension class.

The structure of an Extension

Extension has a few methods

1. pre_insert_event(self, event, sender) – The control passes through this method before every time an event is going to be inserted. So the method gets the instance of the event and the dbus Busname of the client which logged the event. If it wants to block the event from being inserted, this method simply returns None. The fields of the event can also be modified if required (probably useful for privacy control). Before using the event, please check it for None since another extension which has the event instance might have set it to None.

For this hook, the event enters one extension and the output of this extension(ie. event) is then passed to another extension.

2. post_insert_event(self, event, sender) – Same as pre_insert_event except that it is called after the event has been inserted. In this method the nothing needs to be changes or returned as the event has already been inserted.

3. get_event(self, event, sender) – This method/hook is called everything an event is fetched and to be sent to the client. This hook also behaves like pre_insert_event in the sense that the even returned from this method is then passed to other extension’s get_insert_event and can be changes similarly to pre_insert_event.

4. pre_delete event(self, ids, sender) – This method/hook is called before an event is to be deleted. Please note that the input argument is not event but a list of event ids. Event id is the unique way to identify an event within a zeitgeist database instance. It does not return anything

5. post_delete_event(self, ids, sender) – This method/hook is called after the event having the event ids in the input argument ids has been deleted. It returns nothing.

Example extensions

By default zeitgeist has two official extensions which is shipped with the daemon. It is

The project Zeitgeist extensions is for hosting the extensions. One excellent extension for zeitgeist is full-text-search extension which can also be installed in Ubuntu by installing the package named zeitgeist-fts-extension

Right now Blacklist, Datasource Registry and fts also expose their functionality via DBus. For that, the only magic you have to do is to also inherit dbus.service.Object


I don’t think writing zeitgeist extension is a rocket science from any angle. All your need is patience and courage to poke the zeitgeist engine developers on IRC.

Happy hacking!

One thought on “Zeitgeist daemon extensions explained

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s