Calendar bork
By Osma on Friday 14 January 2005, 19:13 - Permalink
While trying to make something out of a boring sick-day, I've been searching for a method to synchronise my Evolution calendar with Nokia 6610 phone. It's amazing how bad Linux calendar tools are..
Gammu, the capable but horrible-to-use and terribly documented phone
backup/management program DOES in the end turn out to have a way of importing
and exporting iCal format. It's just that it's only mentioned in one mailing
list archive I already lost the link to. Anyway, the trick is gammu
--backup calendar.vcs, which outputs iCalendar format! Same
applies to --restore. This puts a new standard to the word esoteric in my
book.
However, my phone will not have memory to deal with the complete calendar in Evolution. So, I'm trying to come up with a way of parsing that and extracting only the last week and a couple of weeks into the future. However, as far as I can see, there are approximately zero point zero tools to do that!
Basically, I only found Perl iCal::Parser, which reads a zero-length hash table from all iCalendar files I have. There's libical, with no tools whatsoever. What the hell? No open source developer anywhere keeps a calendar, do they?
Update: I ended up writing a small a Perl script to filter old calendar entries out of the file to synchronise, and in the process of doing so had to look closer than I would have ever wanted at the internals of Gammu. It's a wonderful program from a device compatibility point of view, but its code structure is even more horrible than its user interface. I particularly like the awful file-reading loop which crashes on pretty much any file above 16KB in size.
Anyway, should someone be interested, the Evolution-to-Gammu calendar parser is in behind the next click...
#!/usr/bin/perl
use POSIX;
my $record = undef;
$calstart = strftime "%Y%m%dT%H%M%s", localtime(time()-7*24*3600);
$calend = strftime "%Y%m%dT%H%M%s", localtime(time()+30*24*3600);
print "BEGIN:VCALENDAR\nVERSION: 1.0\n\n";
while (<>) {
$_ = "$last$1\n", $record = substr($record,0,length($record)-length($last)-1) if (/^ (.*)$/);
$date = "$3$4", $_ = "$1:$3$4\n" if (/^(DTSTART)(;.*)?:(\d+)(T\d+)?/ || /^(DTEND)(;.*)?:(\d+)(T\d+)?/ || /^(DUE):(\d+)(T\d+)?/);
$start = $date if (/^DTSTART/);
if (/^DTEND/) {
$record .= "CATEGORIES:MEETING\n" if ($start ne $date);
}
$record .= $_ if (/^BEGIN:(VEVENT|VTODO)/ || $record);
if (/^END:(VEVENT|VTODO)/) {
print "$record\n" if ($date gt $calstart && $date lt $calend);
$date = $record = $start = undef;
}
chomp;
$last = $_;
}
print "END:VCALENDAR\n";
I run this with
#!/bin/sh cal=`mktemp /tmp/calXXXXXXXXX.vcs` filter-ical <$HOME/.evolution/calendar/local/system/calendar.ics >$cal echo "ALL" | gammu --restore $cal