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 supportedDTSTAMP
of each element is always nowVTIMEZONE
entries appear in random orderORGANIZER
CN
entries randomly change between full name and plus.google.com user IDATTENDEE
entries randomly change between having a CN or not having itTRIGGER
entries change spontaneouslyCREATED
entries 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.