Kontact-Nepomuk Integration: Why data from akonadi is indexed in nepomuk

So Akonadi is already a “cache” for your PIM-data, and now we’re trying hard to feed all that data into a second “cache” called Nepomuk, just for some searching? We clearly must be crazy.

The process of keeping these to caches in sync is not entirely trivial, storing the data in Nepomuk is rather expensive, and obviously we’re duplicating all data. Rest assured we have our reasons though.

  • Akonadi handles the payload of items stored in it transparently, meaning it has no idea what it is actually caching (apart from some hints such as mimetypes). While that is a very good design decision (great flexibility), it has the drawback that we can’t really search for anything inside the payload (because we don’t know what we’re searching through, where to look, etc)
  • The solution to the searching problem is of course building an index, which is a cache of all data optimized for searching. It essentially structures the data in a way that content->item lookups become fast (while normal usage does this the other way round). So that  already means duplicating all your data (more or less), because we’re trading disk-space and memory for searching speed. And Nepomuk is what we’re using as index for that.

Now there would of course be simpler ways to build an index for searching than using Nepomuk, but Nepomuk provides way more opportunities than just a simple, textbased index, allowing us to build awesome features on top of it, while the latter would essentially be a dead end.

To build that cache we’re doing the following:

  • analyze all items in Akonadi
  • split them up into individual parts such as (for an email example): subject, plaintext content, email addresses, flags
  • store that separated data in Nepomuk in a structured way

This results in networks of data stored in Nepomuk:

PersonA [hasEMailAddress] addressA
PersonA [hasEMailAddress] addressB
emailA [hasSender] addressA
emailB [hasSender] addressB

So this “network” relates emails to email-addresses, and email-addresses to contacts, and contacts to actual persons, and suddenly you can ask the system for all emails from a person, no matter which of the person’s email-addresses have been used in the mails. Of course we can add to that IM conversations with the same Person, or documents you exchanged during that conversation, … the possibilities are almost endless.

Based on that information much more powerful interfaces can be written. For instance one could write a communication tool which doesn’t really care anymore which communication channel you’re using and dynamically mixes IM and email depending on whether/where the other person is currently available for a chat or would rather have a mail, which can be read later on, and doing so without splitting the conversation across various mail/chat interfaces.
This is of course just one example of many (neither am I claiming the idea, it’s just a nice example for what is possible).

So that’s basically why we took the difficult route for searching (At least that is why I am working on this).

Now, we’re not quite there yet, but we already start to get the first fruits of our labor;

  • KMail can now automatically complete addresses from all emails you have ever received
  • Filtering in KMail does fulltext searching, making it a lot easier to find old conversations
  • The kpeoples library already uses this data for contacts merging, which will result in a much nicer addressbook
  • And of course having the data available in Nepomuk enables other developers to start working with it

I’ll follow up on that post with some more technical background on how the feeders are working and possibly some information on the problematic areas from a client perspective (such as the address auto-completion in KMail).

Posted in KDE, Uncategorized | 30 Comments

On minimalistic text editors

I think I already mentioned that I’m quite fond of minimalistic UI’s and texteditors with an undisturbing interface.
Recently I stumbled upon FocusWriter (http://gottcode.org/focuswriter/), which is now by far my favorite app for writing. It’s awesome how nice it is to work with such a tool which eleminates all distraction.
I only wish all KDE applications would have such a mode, where fullscreen really means fullscreen. Imagine how awesome this would be in KMail or even better, KDevelop. Especially KDevelop is, while an awesome IDE, just way to cluttered so far. Maybe the Kate devs eventually get around to implement a real fullscreen mode =)

Until then I’ll stick to copy paste from FocusWriter, or to what I created for Zanshin.

Posted in KDE, Uncategorized | 23 Comments

MindMirror/Zanshin

You might have noticed that not a lot happened recently regarding MindMirror, my little Notetaking/Todomanagement application. This was partially due to the fact that I was occupied with things like the Akonadi-Nepomuk-Feeders (after two months of holidays and exams), on which I rely in MindMirror, but also because I started some lengthy discussions with Kevin Ottens from the Zanshin team about a cooperation between MindMirror and Zanshin.

Fortunately he was also attending the PIM sprint, which allowed for another brainstorming, and it turns out that our ideas align that much that I decided to stop working on MindMirror and focus my development time on Zanshin instead. Of course that was a difficult decision since it is quite a bit of work to integrate my work from MindMirror into Zanshin and because I no longer have the full control over the project. On the other hand they did really good work on Zanshin so far, and it only makes sense to work together since we’re trying to build essentially the same application. This way I want to ensure that the project is a bit more future proof (with a community instead of a single developer), and no (scarce) development time goes to waste.

Most of my work on MindMirror can be reused in Zanshin and anyways I needed this project to develop the idea of the application. Kind of a hands on brainstroming, so no regrets here =)
As a first step I’m going to integrate the notetaking into Zanshin, so I hope to release the notetaking part with the next Zanshin release. Today I hacked together a first crude version, which is already functional, but as you can see there’s still some work to do.

I’m really looking forward to finally get a releasable version of what I started with project MindMirror, and hope I made the right call with killing my project before the first release in favor of another one ;-)

Posted in KDE | 8 Comments

PIM developer sprint

Last weekend we had a PIM developer sprint in Berlin, with the aim to give KMail a little boost. The sprint was hosted by KDAB and my employer (Kolab Systems) took care of my expenses, so there was nothing holding me from joining =)

While many concentrated on squashing KMail/Akonadi bugs I focused on yet another rewrite of the Akonadi-Nepomuk feeders, which are supposed to make the information stored in Akonadi available in Nepomuk.

Previously we had an agent for each mimetype, which made it difficult to control the resources which were used by the agents to index the data. To improve this situtation we decided on a plugin based architecture, where we can write plugins to index a certain mimetype, but the indexing is done by a single agent. This gives us a much better control of the used resources, so the indexing of the emails doesn’t bring down your whole system. It also allows us to index various items at different priorities. For instance the initial indexing of all your email (which can take rather long), has a lower priority than an item which you just changed. This is important so applications can rely on the feeder to bring changed items into nepomuk within reasonable time, so they are i.e. retrieved by fulltext search.

The first version already landed in master, but there are still some features of the old agent missing, such as the indexing of email attachments. However I think the new architecture is a real improvement over the old one and should give us a much better situation than before.

Just need to work out the last few kinks…

Posted in KDE | 7 Comments

Updates from MindMirror

From time to time I need a little feature for my own motivation, especially after spending quite some time with the, somewhat boring, implementation of datamodels.

So this time I chose the fullscreen editor as my little feature, which allows you to use the whole screen to write some text. I use this i.e. to draft this blogpost, which gives me exactly what I need (a texteditor), and no distractions.

The mode can easily be toggled with a shortcut, which allows to go back and forth in a snap.
Just after I implemented this, I stumbled upon this neat little tool (http://www.golem.de/1105/83651.html, or just google iA Writer), which is unfortunately for mac only.
However I like the approach of the minimalistic UI and  the focus mode, which highlights always the latest sentence. Also the auto markup looks like a good way of writing structured text without spending to much time on the layout.
Overall I believe they did a very good job on stripping down an application to the essentials for a usecase, and I think this would make for some nice additions to the kde texteditor components, which are also used by MindMirror.
The limiting of the text to an area in the middle of the screen is also something which I want to add to mindmirror, otherwise the lines get very long in fullscreen mode, and/or your sticking on the left half of your monitor.

Also in MindMirror I tried to strip down the UI a bit:
It is now possible to hide the toolbar, which really clutters the UI quite a bit and is not for everyone essential.
In fullscreenmode, where the toolbar is normally shown on top, you can get now a completely white screen, which I really like for writing.
Further I replaced the toolbox on the bottom of the editor component with a custom one, which allows to collapse all boxes, instead of one being always open. As a side effect, the resizing of the toolbox works now properly, meaning there is no space wasted anymore.
I’m now relatively happy with the editor part UI (except for the edit buttons next to title and due date, etc.), but I’m sure there is still a lot to improve.


The control pane on the left on the other hand, is nowhere near where I’d like to have it, and really bad looking. I find I somewhat difficult to get it into shape though.
One thing that really bugs me, is the greyish look of almost all UI’s. I’m not aware of a remedy though, without breaking with the KDE style, or using lots of white boxes, which doesn’t look much better either.
If you have some ideas for the current UI, or know of techniques to alter the look of KDE applications, please tell me.

Apart from the UI bits, the next steps on the way to a first releasable version is a rewrite of the akonadi nepomukfeeders and the fixing of the kreparentingproxymodel so the todo hierarchy works. Also a searchview which uses the relevancy of the matches to sort the items is in the works.

I’m on holiday for the next few weeks, and afterwards I’ll have my exams, so don’t expect too much activity from my side. But afterwards I will get all parts into a releasable shape, to make sure there is a decent release ready for KDE 4.8.

On a side note: I just got a part-time employment (next to my studies) with Kolab Systems, which means I will earn my money with OpenSource software from now on!
About as awesome as it gets =)

Posted in KDE, Uncategorized | 4 Comments

Akonadi Trashhandling

End of February I attended the annual pim meeting in osnabrück for the first time. There I started the akonadi trashhandling, which I need for MindMirror. The idea is to have a uniform way of handling trashed/deleted items in akonadi.

The general idea is to have to ways to separate trash from you normal items:

  • Mark them as trash but keep them in the same akonadi collection:
    This would i.e. allow a resource to map the deleted flag to i.e. the imap deleted flag.
    Of course, if the resource doesn’t support that, all items will remain visible for remote locations (i.e. gmail).
  • Mark them as trash and move them to a separate collection:
    This can be configured on a per resource basis, and allows to collect trash in i.e. another resource.
    This allows that trash is effectively hidden also to synchronised resources, but the downside is that your trash is not available on remote locations (except if you use another resource with sync as trash location).

Of course it is up to the application to use either way, but it should be quite easy to add trash support to applications, including standard actions to move to trash and restore from trash.

Heres what it consists of and what it can do for you(developers):

TrashJob
Marks an entity as trash with the EntityDeletedAttribute and moves it to a configured trash collection (if configured).

The default behaviour is to move the item to the trash collection which is configured in TrashSettings. If this trash collection is not available, the entity is kept in place.

All sub entites of a collection which is marked as trash are also marked as trash, and get the parent collection of the collection which was marked as trash as restore collection. This ensures that it is possible to restore items from trash, which were originally moved to trash together with the parent collection.

The job has also an option to automatically delete items which are already marked as trash.

RestoreJob
Restore the entity from the trash collection to the original collection and remove the EntityDeletedAttribute.

By default the RestoreJob tries to move the entity back to the original location, which is saved in the EntityDeletedAttribute.
If this collection is not available anymore, it tries the original resource root as fallback, if also not available it aborts.

For this case it is possible to configure a special restore collection on the job, to which the item is restored.

If the move was successful the EntityDeletedAttribute is removed from the entity (and from all subentities).

EntityDeletedAttribute
Marks the entity as deleted and stores the restore collection/resource.
Resources could map this flag to an appropriate flag as the MarkAsDeleted flag in IMAP.

TrashSettings
Store a trashcollection for a resource.

In the future further trash related settings, as the time before the janitor agent deletes items could be stored here.

TODO: atm. the settings are never removed. Even if the configured resource or trash collection is removed (not sure if this is ever done).

TrashFilterProxyModel
Either shows all items with the EntityDeletedAttribute or hides all entities with the EntityDeletedAttribute.
It is using a KRecursiveProxyModel, so also trash items which are in a non trash collection are shown in the trash.

StandardActions
Provides 6 standard actions:

  • MoveItemToTrash
  • MoveCollectionToTrash
  • RestoreItemFromTrash
  • RestoreCollectionFromTrash
  • MoveToTrashRestoreCollection
  • MoveToTrashRestoreItem

While the first 4 are trivial, the last two provide a single action, which changes its behaviour depending if the EntityDeletedAttribute is set or not. As it doesn’t make sense to restore entites which are not in trash or move entities to trash which are in trash, I believe it is the most common usecase and what I use myself.
All new actions need the EntityDeletedAttribute fetched in order to work properly.
I had to add some bits to the internal structure of the standardactionmanager to make it possible to change description/icon/etc. for a single action, everything existing should continue to work as expected though.

Trash Janitor Agent (TODO)
Goes trough all collections, and deletes items after a configured period of time, if they are marked as trash.
This configuration is in TrashSettings on a per resource basis, but could be overridden by a configuration in the EntityDeletedAttribute

This is not work in progress atm. but more a concept. I also don’t plan to add this anytime soon, so feel free to do it if you need it now, I’d be happy to help.

Posted in KDE | 1 Comment

Announcing Project MindMirror

So MindMirror is the Project I’ve been working towards for the last couple of months.
Steven already mentioned it in the report from the kdepim meeting in osnabrück, I named it notetaker back then as I couldn’t decide for a name, but here’s finally my first blog post about it.

History/Motivation

I was always unhappy with the available solutions for taskmanagement and notetaking. I tried various online tools (which just don’t cut it if you’re sitting in a train…) like evernote, toodledo, doit and some others. After figuring out that online tools are definitely not for me, I decided looking for desktop apps.

Chandler and KJots were the ones I liked the most, KJots being super simple and fast for notes, Chandler has bit more to offer (including todos) but is not really fast, and doesn’t integrate with any webservice.

So I figured out already two years ago that I will have to create my own app, to help my ridcolously bad memory and my habit of being as unorganized as possible.
What I really wanted was an application which does not differentiate between notes and todos, as the frequently evolve from one to another (at least in my world). I wanted a place where I can store my thoughts, todos, events without having to think where it belongs.
Basically just a place where I can dump everything, and retrieve it later on as needed.

Further I wanted it to integrate well with existing solutions, such as KOrganizer, GMail, Evernote, etc.

With akonadi and nepomuk slowly evolving I was finally given the tools to start this task.
So I started last year the project MindMirror.

While the inital development started at a quick pace, I soon faced difficulties in the akonadi and nepomuk internals which occupied me for quite some time.
I spent a lot of time hacking on QProxyModels (the ETM, my own section model, …), also a conceptually proper Nepomuk integration was not easy and is still work in progress. Further I got sidetracked by the trashhandling implementation in akonadi (not yet in master), after attending the kdepim meeting, but more on that in another post.

Now that the needed fixes and additions slowly make their way into master, I feel that I can start spreading the word about this new tool.

MindMirror

MindMirror is supposed to be an interface to store everything you have to remember in form of Notes, Todos and Events. It is designed to be an additional Interface to the calendarview of KOrganizer and not to replace anything.
I try to keep the UI minimalistic, far from the full blown Interface of the KOrganizer Incidence editor. This means also ignoring some features, at least for now (I’ll probably add the option to open the fullblown editor).

Idea is, that a minimum effort is needed to enter something. You can simply create a new item (note/todo/event) and start typing right away, without another click needed. The focus will automatically move to the right fields to minimize user interaction. The UI is reduced to the minimum: title, text, an (optional) due date and a status are all that is usually needed IMHO. The status is the simplified version of the 10 priority levels a task can have in korganizer (States being Later/Now/Done). This gives some simple priority management, which is actually useful.

Organizing/Workflow

So the idea is, that you don’t have to organize the information when you enter it but rather later on (i.e. end of the day), if organisation is needed at all. This avoids breaking your workflow. To further improve this i.e. a krunner can be written so you don’t even need to open MindMirror.

For simple, short term notes, fulltext search and a list of the latest created notes should be enough to find your item again (I hope at least).

If you’re working on a long term project thought, it can be useful to organize your items in a treelike structure, which is typically solved using folders and alike.

MindMirror is not much different, you can organize your items into “Topics” (which can have subtopics and so on). The main difference to a folderstructure is, that you can add an item to several topics at the same time (the UI-parts are still missing currently), which should allow for a little more flexibilty.

Also the organisation of items is done through nepomuk, meaning that the “Topics” are actually pimo:topics and the whole structure is stored in nepomuk. Of course it is also possible to tag you items in MindMirror, so I hope this allows to fill Nepomuk with some more useful information.

With the means of nepomuk it is also possible to attach/link arbitrary documents, emails, to your notes/todos, which gets us one step closer to have everything at hand to fulfil a task.

When you’re done editing an item, don’t even bother saving, everything is already saved as you finish typing.

UI

 

The Userinterface consists of a single view, with the left pane for control/sorting, the listview in the middle for display of the items, and the editor on the right. I’m not a big fan of interfaces consiting of many tabs and different windows, so I try too keep everything together.

The “Views” which you can see on the topleft control mainly the organisation of the items in the listview:

  • Work Layout:
    This layout is for crossing of items on your todo, list. Only uncompleted todos are shown and your notes are there to support what you’re doing.
  • Organize:
    The organize layout shows all items sorted by date. It’s there to organize your items.
  • Upcoming:
    A list of upcoming events/todos

In the custom view you can control the sections and the shown items manually.

The listview in the middle groups the items in sections, currently we have there ItemType (Todo/Event/Note), Status (Done, Later, Now), and Date. If I manage that items can appear in multiple sections we will have some more possibilities like:

  • by subtopics of the current topic
  • by tags

While the listview already supports showing the todos in their hierarchy, this part is still very buggy and needs quite a bit of work first.

The editor is a normal KRichTextWidget, which allows you to enter RichText. Below you can see some toolviews, most interesting is probably the “Context” view which allows you to relate notes/todos/files/etc. to this item.
Instead of using a tabbed interface or windows when opening notes from there, the breadcrumbs on top are used to navigate back.

I don’t plan to add much more to the UI, as this should be all which is needed. There probably will be a couple of changes, and the UI could use some designer’s love (It’s a bit too grey atm.), but from a feature point of view thats more or less it.
I’ll probably add a fullscreen-mode to the editor and a search view for some more searching options though.

Current State

While it is not yet releaseable and I plan the first release earliest with KDE 4.8 (because of the required dependencies), I already use it in my daily notetaking and todo management (i.e. I drafted this blogpost in MindMirror), and I’m quite happy with the result.

There is still some work to be done until it’s fully stable though.

Integration / Collaboration with other applications

Using akonadi for datastorage, namely the akonotes resource for notes and the ical resource for calendar items, you can have the same items in KOrganizer, KJots and MindMirror (and of course every other application which uses akonadi).
This is of course key for event and todo management, as MindMirror does not have it’s own calendarview: KOrganizer is the calendarview.

I do think akonadi is the way to go for data which should be synchronisable to cellphones, webservices, etc.
Nepomuk is also good candidate, but it makes perfectly sense to separate the synchronisation part in akonadi
(maybe as a long term future nepomuk could completely encapsulate akonadi, but thats another story).
Anyways thats why I do not plan to intergrate with applications not using akonadi (in short term).
Since the nepomuk feeders feed the data from akonadi to nepomuk, most of the data is also available trough nepomuk (which might be a way to work with other apps using nepomuk only).

Of course I looked at many other programs like basket, semnotes, kjots, korganizer, zanshin, etc. to see if a couple of modifications would bring my to my target, but I don’t think so. Neither interface wise nor functionality wise any of those programs suits my needs, although all of them have some very nice ideas.

Future Plans

Apart from the obvious plans like having an awsome ui and being super userfriendly, there are also some plans for akonadi in general:

  • Inline pictures in notes
  • Synchronisation plugin for evernote (akonotes resource)
  • krunner (I read there is already something cooking in the zanshin project)
  • Search View with an additional list of item (files, emails, etc.) related to the search (aka. “Contextview”)

I’m sure I won’t run out of work =)

Codebase

While the codebase is generally in an ok state, it needs some cleanup and documentation.
There are still some classes with names that don’t really make much sense anymore, but that will be fixed.

Also for building some kdelibs code is needed (trashhandling and some etm fixes), which is partially only available in my private repos. Anyways, if anyone really feels like building, contact me, but be prepared =)

The code is currently here.

Also, contributions are, as always, more than welcome =)

Posted in KDE, Uncategorized | 33 Comments