Jérôme Belleman
Home  •  Tools  •  Posts  •  Talks  •  Travels  •  Graphics  •  About Me

A Filesystem-Based Address Book

15 Jun 2018

I had the project of writing an address book program. Rather than storing the data in a database or even in a single file, I left it all to the filesystem.

1 Not a Database?

When data doesn't grow too big (for some definition of too big) I like using simpler storage formats such as JSON or YAML because they're both readable and editable by both human beings and machines. I once discussed all this at length in the Databases vs. Plain Text Files topic. (Which I wrote exactly 4 years minus 1 day, funnily enough.) I can't emphasise enough how comfortable it is to be able to read and write your data with any tool you fancy, not only while using the software you developed to work with it, but especially as you're developing it. For how do you read and write test data that can only be written and read by a program you haven't written yet? Bit of a chicken-and-egg problem, this.

2 Reinventing the Wheel

Anyway, why in the name of all that's holy did I need to write yet another address book program? Running apt-cache search address book seems to suggest there's already more of these than I can be bothered to test out. Maybe there's that. And maybe it was a case of reinventing the wheel because there's no wheel I could find that was round quite the way I wanted it to be. And because it was just faster to carve a new wheel out than edging an existing one until it got the right shape. And finally because it was an opportunity to innovate in some way, an attempt at making an omni wheel, sort of thing. Like leaving the address book storage to the filesystem.

3 Leaving the Address Book Storage to the Filesystem

As I reflected upon how I was going to implement this address book program, I immediately pictured a form laid out with Qt. PyQt, specifically, because I was going to write it in Python, too. In my mind, I saw the various fields, labels, perhaps a handful of menus, a status bar. And then it occurred to me there would have to be a list view, too. But I wasn't in the mood for this. You have to be in the right mood, when it comes to list views. And I just wasn't.

And then it dawned on me.

Since I might have been accused of reinventing the wheel, I thought I'd mitigate it by leaving the list making to other programs. After all, there's plenty of programs perfectly capable of displaying lists. File managers, the ls command, Excel, the ls command, file managers, ... It occurred to me that the most convenient way of identifying distinct entries in my address book was to make each entry an entity that any program can understand: a file.

And this all makes a lot of sense: it goes beyond the idea of using plain-text files to store data for being able to read and edit it with any tool; it uses the idea of using files in a plain filesystem so that data can be organised and looked up with any tool, too. For better or worse, I chose to give each file the first name and surname of each person in my address book. I gaped at all the advantages and opportunities I saw blossoming before me as I mulled things over:

  1. Sorting address book entries comes for free. Whether you prefer the ls command or clicking on the filename header of your graphical file manager in a detailed list view, sorting works out of the box and I didn't have to implement this for you. And not just sorting by name, by last change time will work too.
  2. One of the reasons I chose to write my own address book program, is that I needed a way to categorise entries. At first, I thought of adding tick boxes to the form. And then it occurred to me that being able to using directories would give me all the flexibility I need. A modern filesystem will let me seamlessly work with a complex hierarchy of files and directories.
  3. A modern filesystem will even let me have the same address book entry belong to multiple categories, in fact: whether I choose to use symbolic or hard links, I will be able to have the same file be present in different places. And I only need to edit one of the links or the original file to see the change be applied everywhere.
  4. Links are also a tremendous way to have the same address book entry be stored under different names. It seems that using the file name as the person's name was a good idea, then. Links will thus allow me to simultaneously point to a given address book entry, whether it'd be stored under the wife's name, or the husband's, or the dog's, or the first name first, or the first name last if it suits sorting better. The sky's the limit.
  5. Address book entries can be looked up with the find command or whichever search feature your file manager will provide. Address book entries can even be searched with any file search engine supporting indexing, or simply grep. Or :vimgrep. Or anything.
  6. Counting how many entries there are is easy with combinations of the wc command and ls, or find -type f or even find -type f,l, or simply what your graphical file manager or file search program will care to show you in their status bars.
  7. The address book can be distributed. Move the whole folder to your Dropbox, AFS home directory, or rsync it left, right and centre, and Bob's your uncle.
  8. If you're starting to have your address book distributed all over the shop and become worried about conflicts and race conditions, why don't you have it version-controlled, while you're at it? This will also give you the means to see it evolve over time and will protect you in case something goes horribly tits up.
  9. I won't have to implement this list view, significantly reducing development time. Opening the address book entails running addr <filename> or:

    for i in *.addr; addr $i
    or simply double-clicking on the icons your graphical file manager will show you, provided somebody taught it what to do in /usr/share/mime. And again, being all plain text, nothing keeps you from opening the address book entry with any tool you like and reading or editing it yourself.
  10. Speaking of any tool, Xfce Custom Actions or the equivalent Nautilus extensions are a fantastic, graphical, user-friendly way to do anything you might need from a collection of addresses. I once wrote without breaking a sweat such an extension to generate printable stickers from a set of selected addresses in Nautilus.

There you go, 10 advantages I came up with, just like that. 10 features I didn't even have to think about as I wrote the few lines making up the program. And I'll leave it now to my potential users to come up with more innovative and unexpected ways to use it. I'm glad I reinvented the wheel again. See how round and smooth it is on GitHub.

4 References