nblock's ~

Subscribe to public calendars with OwnCloud

In this blog post, I'm going to describe the ideas and my solution for subscribing to public calendars and accessing them across all my devices (laptop, mobile phone, web UI). One might think that this is a no-brainer since there are tons of commercial providers like Google/Apple/… out there that can be used to tackle this issue. This is true, but I do not want to rely on commercial providers and their services to handle my private data.

Idea One: Radicale and InfCloud

After a quick internet search, Radicale and InfCloud seem like the ideal solution. Radicale is a rather small piece of Python software which is quite popular in the community. It provides fine grained access control, can keep calendar entries in a Git repository and focuses on CalDAV and CardDAV. Since it has no web UI, InfCloud comes in handy. It is an open source CalDAV/CardDAV web client and the interface looks good enough for me.

All tests worked out well until I hit issue 249 during my tests with DAVdroid. As of now, there is no solution to this issue and not having the public calendars on my mobile phone is a deal breaker for me.

Idea Two: Owncloud and CalendarPlus

Since I already have an Owncloud instance up-and running, I thought about re-using that. The standard OwnCloud calendar app (as of 8.1) does not support subscription of public calendars and has a rather limited UI. There is an alternative available: CalendarPlus for Owncloud 8.1, but it did not work as expected during my tests. The subscription of public Google calendars did not work for me. It can't re-use the data from the existing calendar app and after all, it is a rather fresh piece of software. Maybe CalendarPlus will be an alternative down the road, but for now, I'm going to leave it aside.

Idea Three: Owncloud and vdirsyncer

Vdirsyncer may be used to synchronize calendars and address books between different storages. Typical storages are http, filesystem, CalDAV, CardDAV, …. It has proper documentation and is well-maintained. With vdirsyncer, the missing subscription feature of the OwnCloud calendar app is no longer an issue.

During my tests, I hit two issues which were both fixed quickly by its author, Markus Unterwaditzer:

  • One of the calendars was using strange UIDs for events causing vdirsyncer to crash.
  • Every time one fetches a Google public calendar, the DTSTAMP field of each calendar entry is set to a current timestamp. This caused vdirsyncer to recognize all events as modified and trigger a synchronization of the entire calendar. With each invocation of vdirsyncer, all public Google calendars were re-synchronized.

One remaining issue is that all synchronized calendars are writable for the OwnCloud user on all attached devices. But there is a workaround available: use a separate user that owns the calendar and share them as read-only to other users and groups.

Final solution

This is a quick how to of the solution I'm currently using:

  • Create a separate OwnCloud user that owns all public calendars. In this example: syncuser
  • Login as syncuser and create an OwnCloud calendar for each public calendar you want to synchronize. For example, I have a calendar called VALUG that maps to the public calendar on valug.at.
  • Share the calendar as read-only for all required OwnCloud users or groups.
  • Configure vdirsyncer in ~/.config/vdirsyncer/config
  • Check if the synchronization works: $ vdirsyncer sync
  • Create a cron job to run the synchronization periodically.

Here is my (shortened) vdirsyncer configuration:

status_path = ~/.cache/vdirsyncer/status

# Pairs
[pair valug]
a = valug_upstream
b = valug_owncloud
conflict_resolution = a wins

# Storage entries
[storage valug_upstream]
type = http
url = "http://valug.at/calendar/valug.ics"

[storage valug_owncloud]
type = "caldav"
url = "https://owncloud.example.org/remote.php/caldav/calendars/syncuser/valug"
username = "syncuser"
verify_fingerprint = "AA:BB:CC:..."

Until next time.


tagged calendar, calendarplus, ics, infcloud, owncloud, radicale and vdirsyncer