I've happily been using akonadi for my calendars, and
yesterday I added an .ics feed export from Google, as a URL file source. It is
a link in the form: https://www.google.com/calendar/ical/person%40gmail.com/private-12341234123412341234123412341234/basic.ics
After doing that, I noticed that the fan in my laptop was on more often than usual, and I noticed that akonadi-server and postgres were running very often, and doing quite a lot of processing.
The evil
I investigated and realised that Google seems to be doing everything they can to make their ical feeds hard to sync against efficiently. This is the list of what I have observed Gmail doing to an unchanged ical feed:
Date:headers in HTTP replies are always nowIf-Modified-Since:is not supportedDTSTAMPof each element is always nowVTIMEZONEentries appear in random orderORGANIZERCNentries randomly change between full name and plus.google.com user IDATTENDEEentries randomly change between having a CN or not having itTRIGGERentries change spontaneouslyCREATEDentries change spontaneously
This causes akonadi to download and reprocess the entire ical feed at every single poll, and I can't blame akonadi for doing it. In fact, Google is saying that there is a feed with several years worth of daily appointments that all keep being changed all the time.
The work-around
As a work-around, I have configured the akonadi source to point at a local file
on disk, and I have written a script
to update the file only if the .ics feed has actually changed.
Have a look at the script:
I consider it far from trivial, since it needs to do a partial parsing of the
.ics feed to throw away all the nondeterminism that Google pollutes it with.
The setup
The script needs to be run periodically, and I used it as an opportunity to try systemd user timers:
$ cat ~/.config/systemd/user/update-ical-feeds.timer
[Unit]
Description=Updates ical feeds every hour
# Only run when on AC power
ConditionACPower=yes
[Timer]
# Run every hour
OnActiveSec=1h
# Run a minute after boot
OnBootSec=1m
Unit=update-ical-feeds.service
$ cat ~/.config/systemd/user/update-ical-feeds.service
[Unit]
Description=Update ICal feeds
[Service]
# Use oneshot to prevent two updates being run in case the previous one
# runs for more time than the timer interval
Type=oneshot
ExecStart=/home/enrico/tmp/calendars/update
$ systemctl --user start update-ical-feeds.timer
$ systemctl --user list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2015-03-25 22:19:54 CET 59min left Wed 2015-03-25 21:19:54 CET 2s ago update-ical-feeds.timer update-ical-feeds.service
1 timers listed.
Pass --all to see loaded but inactive timers, too.
To reload the configuration after editing: systemctl --user daemon-reload.
Further investigation
I wonder if ConditionACPower needs to be in the .timer or in the
.service, since there is a [Unit] section is in both. Update: I have
been told it can be in the .timer.
I also wonder if there is a way to have the timer trigger only when online.
There is a network-online.target and I do not know if it is applicable. I
also do not know how to ask systemd if all the preconditions are currently met
for a .service/.timer to run.
Finally, I especially wonder if it is worth hoping that Google will ever make
their .ics feeds play nicely with calendar clients.