In older versions of KDE, Kontact used to keep its data in portable formats: iCalendar files for KOrganizer and vCard for KAddressBook. But some time ago, Kontact moved to Akonadi, a more sophisticated backend storage system. By default (at least on my machine), Akonadi uses MySQL (with InnoDB) as the persistent storage. I didn’t consider it thoroughly when moving my data to Gnome, and I got stuck with the data.
To make things worse, somewhere along the update to KDE 4.6, I got some of the data moved to ~/.akonadi.old. Being stuck with the InnoDB tables, I tried the following solutions without much success:
- Loading the InnoDB tables into a MySQL server. It didn’t go well; MySQL complained about weird stuff, and I gave up in search of a simpler solution.
- I booted an openSUSE virtual machine with KDE and tried loading my old data. Apparently, my
~/.akonadifolder contained nothing interesting, and openSUSE’s KDE 4.6 refused to load the data from~/.akonadi.oldafter I renamed it.
So, being upset about Akonadi, I did some grepping and found strings from my contacts and todo lists in the following files:
Binary file .local/share/akonadi.old/db_data/ibdata1 matches
Binary file .local/share/akonadi.old/db_data/akonadi/parttable.ibd matches
Binary file .local/share/akonadi.old/db_data/ib_logfile0 matches
I opened the files with vim and found out they contained vCards and iCalendar blobs. So instead of directly storing them on the file system, where they are easily accessible, they are stored in the DB files. I figured it would be easiest to just extract the data from the binary files. I’ve used the following script:
import sys
START_DELIM = "BEGIN:VCALENDAR"
END_DELIM = "END:VCALENDAR"
def main():
bin_data = sys.stdin.read()
vcards = []
start = bin_data.find(START_DELIM)
while start > -1:
end = bin_data.find(END_DELIM,start+1)
vcards.append(bin_data[start:end + len(END_DELIM)])
start = bin_data.find(START_DELIM, end+1)
print "n".join(vcards)
if __name__=="__main__":
main()
It reads binary files from stdin and outputs iCalendar data that is embedded in them. If you change START_DELIM and END_DELIM to VCARD instead of VCALENDAR, it will extract the contacts’ data.
This migration had me thinking how important it is that an application’s data should be easily portable. It’s something I feel not many projects have high enough on their priorities.