Updated January 2, 2020 with a clarification of CalDav
Five years ago, I started working towards what I then called Head in the cloud, feet on the ground, but now prefer to describe using Kleppmann’s terminology as Local-first software: you own your data, in spite of the cloud (h/t Adrian Colyer). Among the the first applications for which I tried a Local First solution many years ago was the calendar, but my initial implementation was very crude and unambitious. It consisted simply of using Google Calendar and downloading a local copy of the
ics file every day. Later, I improved this marginally by placing the local copy under version control to provide a complete change history and roll back capability. (This works only if one modifies the DTSTAMP field of each event in the
ics file to prevent spurious differences in the comparison between two calendars). This strategy was more Local Second than Local First. It also did nothing to address the privacy risks of keeping something as sensitive as one’s calendar in the cloud.
A year ago, I discovered
EteSync which encrypts the calendar before uploading to the server. Only the local clients see the plain text calendar as they decrypt what they get from the server and encrypt what they send to the server. Since the server is just a storage facility, it does not need to know the encryption password. The server uses a separate user authentication password to provide read-write access to the encrypted file.
EteSync offers a subscription service in which they host the encrypted calendar on their server. But it is an open source software and it also offers a self hosted solution. The
EteSync mobile phone clients work equally well with the self hosted server. And by then, I had already setup my personal cloud.
EteSync developer (Tom Hacohen) was very prompt in helping me setup my self hosted
EteSync server. The configuration that I used is also available on their GitHub page. It requires
Django and of course the
etesync-server all of which are easy to install on any Linux system.
The major problem that I faced was that while
EteSync has excellent mobile clients, it does not offer much by way of a desktop client. For some time, I used the CalDav and web based solutions that
EteSync suggests, but I was not happy with any of the lightweight
CalDav clients that I could find. Those willing to use heavy clients like Thunderbird might find
etesync-dav perfectly acceptable (
etesync-web provides only read access).
That is when I turned to the command line. Back when I was using Google Calendar, I was an avid user of gcalcli particularly for bulk creation and deletion of events. I also liked its ASCII text graphical calendars (weekly and monthly views). Since this was an open source Python software, I decided to modify it to work with
EteSync. I ended up splitting out the backend interface into a separate module so that the same front end could work with any calendar at the backend. The result was
icalcli which is available on GitHub and on PyPi.
I now use
icalcli regularly on my desktop; in fact,
icalcli is permanently open in a terminal window. The Local First strategy means that searches are extremely fast. Regex searches are also lot more powerful than Google Calendar searches.
EteSync uses a journal and therefore revision history is inbuilt. I do not need a version control overlay on the
ics file to get this functionality.