Lanedo’s Charity Donations

We wanted to thank our customers and to give something back for all the work we had during 2010. So Lanedo decided to give to a chunk of its revenue to charity.

There were 6 charities chosen:

There were a number of reasons to choose these charities. For the King’s College Hopital, Ipswich Hopital and St. Elizabeth’s Hospice, the reasons were very close to my heart. During 2010, my father (Brian Russell) was diagnosed with prostate cancer. This is something his father also suffers from (as do millions of men towards old age). Each of these hospitals have been instrumental in helping my dad beat the cancer and helping both family members with treatments. Additionally, St. Elizabeth’s Hospice has aided the late Alison Clarke who was my piano teacher until she too died of cancer not long ago.

Our world has seen much grief and disasters last year that caught our attention. To help mitigating and future development, half of our donations went to the wider public through Unicef, SOS Children’s Villages and the Red Cross.

We hadn’t announced this until now for a few reasons. One of which was that the new website was not finished and we didn’t have a NEWS page to announce it on either.

So again, thank you to everyone we worked with last year!

Tracker 0.10.0 Released!

So, 2823 commits from over 68 authors, 102 GNOME bugs and 154 Nokia bugs since 0.8.0 was released (in April 2010) and we have our first stable version of the 0.9 branch out.

With the 39 releases of 0.9.x made this last 10.5 months, we’ve been quite regular at pushing tags and I would like to thank everyone involved in making that happen.

Any fixes for 0.10 will be applied to the tracker-0.10 branch and master will start adding new features covered on the roadmap.

The official announcement can be seen here.


GTK+ has had support for Tracker for a while as a backend search engine used in the GtkFileChooser. At GUADEC this year, the Tracker team were asked to update the backend at the GTK+ team meeting. I found time this week to add support and push my changes to the tracker-with-libtracker-sparql branch.

For now, I have dropped support for all older versions of Tracker because it really is a mess to maintain and GTK+ 3.0 should really be using the latest and greatest APIs anyway. The other change I made was to support searching by filenames not the content of files. There is a #define in the .c file (FTS_MATCHING) which allows switching between using FTS (Full Text Search) and filenames (which are usually part of an FTS search anyway). For me, finding a file based on the name itself seems more intuitive for the GtkFileChooser and tends to yield results I am really looking for better than the FTS matching. In most cases, I don’t want to find a file based on some content when choosing a file. I would appreciate any comments on this.

A demonstration of the new functionality:

Tracker Needle Update

What is it? Why? Where?
These questions were all covered in my previous blog about tracker-needle.

What’s changed
Well, a number of small changes have been going on based on user requests and making sure all the tracker-search-tool old features are covered. Specifically:

  • History is saved using a nice new editable combo box
  • Tags can now be seen (though that’s about it for now, more work is needed here)
  • A progress spinner has been added when queries take longer than the user might expect
  • Support for Emails has been added

You can see all these new features in the latest video:

What’s next?
I would love to get tags working better, allowing adding/removing and searching by them. Generally, searching by tags isn’t hard, what is hard is making the search categories include tags and identifying them with files. It can be done, but doing it in a fast way is not quite so trivial. I already have a patch I am working on for this.

Lanedo Sponsoring GTK+ Hackfest

So today the GTK+ hackfest starts and continues on until Friday. Mitch and Carlos are there and have some Lanedo branded mugs to hand out during the week.

Additionally, Lanedo is sponsoring some of the dinners/drinks for the participants (at Mitch’s discretion) during the week! I am sure he will let the guys going know the what, when and where :)

Hope it goes well guys.

Tracker Needle

What is it?
In short it is a replacement for tracker-search-tool. I know the name is a tad lame, but I used that for lack of a better alternative at this point.

We have quite a few people asking for things which are simply not available in tracker-search-tool and I wanted a good excuse to learn Vala. So, tracker-needle was born out of my desire to learn Vala.

Currently, it lives in a branch on GNOME’s Tracker GIT repository. I am hoping we can merge this to master before we start doing stable releases (which is going to be quite soon).

What next?
Well, right now, it is fairly basic and I plan to add more polish and more “views”. I have in mind to add some sort of photo/icon view for images only and perhaps also some sort of category chooser type view. Possibly some way of displaying and setting tags nicely would be good too. Any ideas appreciated. Note, the idea here isn’t to replace Nautilus or Zeitgeist, this is purely a tool for users to try Tracker with and use occasionally. Ultimately many of the Tracker team believe Tracker should be integrated with applications, not a separate application to search and I tend to agree.

Eye candy for anyone interested :)

Tracker: Direct Access branch merged in master

A while back we had this bug from Bastien: 613255 – “Read-only, non-DBus, store access”. For the past 5 or 6 weeks we have been working on this. Initially the idea was just to do direct access, but once we got started, we realised that the libtracker-client API wasn’t really good enough and we would like to extend it. But we didn’t want the old API there either, so we came up with this new library to supersede libtracker-client. For now we package both, but all functions in libtracker-client are marked as deprecated at this point.

So what do we have now? Fundamentally we have ONE API for different backends using different technologies. To summarise:

1. D-Bus (libtracker-bus, backend)
2. Direct Access (libtracker-direct, backend)

D-Bus – Read/Write Access
Depending on the version, we either use FD passing (requires > 1.3.1) to avoid copious memory copies OR we use D-Bus glib marshalling which represents the worst performance you can get from Tracker (though it is still usable).

Direct Access – Read Only Access
This is based on a library we had internally in Tracker called libtracker-data. We merged some things to make this happen (like libtracker-db) but generally, we sit on top of this library in libtracker-direct.

The backends are dynamically loaded at run time depending on the client’s needs (i.e. if you only ever do SELECT type queries, you’ll use the direct-access backend).

How does the API look for libtracker-sparql?
The idea here was to facilitate all the old API needs and some new ones. What we wanted was less API bloat and to incorporate some of the things we had in the code base all spread out in multiple libraries into this libtracker-sparql. These things include:

  • Connections – used in libtracker-client, we wanted some common way to get a connection to Tracker regardless of what backend was in use.
  • Cursors – used in libtracker-db and wanted as a public API for some time, but not possible without WAL (Write Ahead Logging) in SQLite 3.7. Now we share the same API internally and externally.
  • Builder – used in tracker-extract for building SPARQL queries for selecting/inserting data.
  • Utilities – used in tracker-extract, the miners, etc. for escaping text used in SPARQL queries and some other common functionality.
  • Example
    So this is what you might expect with the new API:

    TrackerSparqlConnection *connection;
    GError *error = NULL;
    const gchar *query = "SELECT ?class WHERE { ?class tracker:writeback true }";
    connection = tracker_sparql_connection_get (&error);
    if (!connection) {
    	g_printerr ("%s: %s\n", _("Could not establish a connection to Tracker"), error ? error->message : _("No error given"));
    	g_clear_error (&error);
    /* The NULL below is the GCancellable */
    cursor = tracker_sparql_connection_query (connection, query, NULL, &error);
    if (error) {
    	g_printerr ("%s, %s\n", _("Could not query classes"), error->message);
    	g_error_free (error);
    	g_object_unref (connection);
    if (!cursor) {
    	g_print ("%s\n", _("No classes were found"));
    } else {
    	while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
    		g_print ("%s\n", tracker_sparql_cursor_get_string (cursor, 1, NULL));
    	g_object_unref (cursor);
    g_object_unref (connection);

    So, now we have direct access. I have ported my tracker-needle experimental application to it and it seems faster than tracker-search-tool (which it aims to supersede). I will blog about tracker-needle later, but for now, direct-access is available in master for anyone interested to try it out! This has been a huge team effort with Jürg, Philip and Aleksander Morgado and myself involved. Try it out, any comments about the API are appreciated and it is documented quite nicely too.

Tracker: branches branches branches

Recently, there has been so much work going into Tracker master. For a while now we have been averaging between 1 and 2 branches a week being merged into master. So I thought I would highlight some of the sweet work going into Tracker at the moment:

Dropping libinotify
For some years, we have been using an imported version of libinotify in our source tree to do the things not available in GIO’s monitoring API. One of the main reasons we didn’t move to GIO’s API was that the model we were using didn’t fit the model GIO used. In Tracker, if you monitored a directory and it moved to another location, we moved the monitor to that location. With GIO, if you monitor a directory it doesn’t move, which makes sense. Thanks to Aleksander Morgado, we have now merged his drop-inotify branch into master. It is so nice to be able to remove that imported library now.

D-Bus with file descriptors
We are always trying to reduce the memory footprint of Tracker. Recently Adrien Bustany finished implementing support for DBUS_TYPE_UNIX_FD in Tracker. The nice thing about this, is that we now don’t copy masses of memory from one place to another just for pushing the data between two processes. Adrien and Philip have previously blogged about this, but more recently, Adrien finished support for this by also implementing this for the tracker-miner-fs and tracker-extract communication. Effectively the same data is transported between those as tracker-miner-fs and tracker-store, with the difference that tracker-store also receives file specific information appended to the SPARQL message (like size, modified dates, etc).

To use this you need D-Bus 1.3.1, it is nice to see these sort of performance improvements in Tracker. Great work Adrien thanks!

Direct access
Bastien reported a bug not so long ago about adding support for direct access to the databases via a library API. This week, we started a branch to get this work under way. While we do this, we are considering re-writing the libtracker-client API using Vala and improving the old API substantially.

Git branch management
Due to the high number of branches we create, I decided to do some sort of clean up. I created a script to list all the branches and relevant information about them to be able to email the mailing list and check if everyone was happy with removing old branches. I thought this might be useful to other projects. Here is the script I used:


if ! git rev-parse --git-dir > /dev/null; then
        echo "This is not a git directory"
        exit 1

if test $# -lt 1; then

git ls-remote $remote | while read LINE; do
        commit=`echo $LINE | sed 's/ .*//'`
        name=`echo $LINE | sed 's/.* //'`

        if [ -z $name ]; then

        case $name in
                shortname=`echo $name | sed 's@.*/@@'`
                if ! git log --max-count=1 --pretty=format:"Branch '$shortname' -- last commit was %ar by %an (%h)" $commit 2>/dev/null; then
                        echo "Your checkout doesn't contain commit `echo $commit | sed 's/^\(.......\).*/\1/'` for branch $shortname"
                        exit 1

This produces output like:

Branch 'album-art-to-libtracker-extract' -- last commit was 3 months ago by Martyn Russell (d1f1384)
Branch 'albumart-quill' -- last commit was 8 months ago by Philip Van Hoof (a397a0f)
Branch 'anonymous-file-nodes' -- last commit was 5 months ago by Carlos Garnacho (60658be)
Branch 'async-queries' -- last commit was 2 months ago by Carlos Garnacho (88358dd)
Branch 'async-queries-due' -- last commit was 10 weeks ago by Jürg Billeter (52634ce)

Thanks to Sven Herzberg for some of the improvements to the original script. Most importantly, the use of git ls-remote. This makes sure that local branches are not used which may have been removed in the origin repository.