This post is a quick follow-up on my previous post about decentralized synchronization. Back then, I had more or less solved the replacement of all basic functions one might need on a smartphone while avoiding centralized services like Google. On some aspects I had to take a step back - e.g., I cannot enter events on my mobile devices anymore, I just edit my calendar on my Debian machines and display it on the web and on my mobile devices after.
The one thing I had not really fixed at all was contacts or address books. I had already created an online address book using the exported vCards of my old centrally synchronized address book (which I subsequently emptied). As I was writing about it, I got more motivated to find a solution that also works while I am offline.
So I did some research. Among the standalone address book programs that I could find in the Debian repository, abook looked by far the best. Unfortunately, the documentation does not seem to state how exactly the contacts are stored. Since I only have extremely slow Internet access here, I thus refrained from trying it out. Instead I decided to write my own address book tool. Again, this doubled as a training session in programming in Rust.
My little address book tool
As I am kind of a flat file fetishist when it comes to programs I use myself, the most important aspect about my contact manager/address book tool is that it stores contacts directly as vCards in a dedicated folder. I don't open source the tool yet, as I hard-coded the folder into the program. In my case, it's
It then saves each contacts as an own vCard, that are parsed, searched, displayed, and edited to my wishes. A short overview of the available functions can be found when passing the help argument (in this case, not typing any argument apparently):
|listall||Lists all available contacts|
|show||name||Displays contact with the specified name|
|search||search term||Searches your contacts by name only|
|fsearch||search term||Searches through all your contact information|
This will search the full contact.
You may e.g. be searching for a place's name.
|add||name||Adds a contact by the specified name|
|insert||name key value||Adds a value at key for contact specified in name|
|rmline||name key||Removes all values specified for this key from the specified contact. E.g., it will remove all phone numbers from a contact.|
|open||name||Opens the contact in your preferred application|
|rm||name||Deletes the specified contact|
|availablekeys||Lists all available keys that can be specified in a contact to keep it compliant with the vCard specifications.|
Unfortunately, some functions are not yet included. The program does, for instance, not yet decode specially encoded vCards. This might be the cause of the problem I ran into while synchronizing.
Once one has full control of one's contact data, stored using an open standard, synchronizing them should, theoretically at least, an easy task. Indeed, synchronization to the server works incredibly easy, using the same method I use to keep my calendar up to date on the server. As I, again, have no shell access to the server, I synchronize using lftp, updating any changed files while keeping the unchanged ones as they are. For this I wrote a little shell script, that I run on a cron job.
Synchronization with Android however still fails without a CardDav server. On F-Droid, there is an application Import Contacts. It fortunately has a batch-import function for full folders of vCards, just as the one I am using to store my contact information. It thus looked almost like what I'd wanted (even if it again does not synchronize back, it would have been sufficient). However, it did not parse my vCards properly.
ORG values were interpreted as contacts, while the name tag of a vCard (
N) was considered a separate contact unrelated to the additional information in the vCard. My Android contact list now does include all my contacts' names. I do, however, not have the phone numbers etc. linked to these in it.
There is still a long way to go, I guess...