More on exporting and importing

Playing around some more with Oracle Calendar’s export feature, and the resulting data file, to try to get my all-day events to show up properly in iCal. First off, Oracle Calendar can actually export into two different formats, vCal and iCalendar. iCalendar is actually a newer spec that grew out of vCal. Apple’s iCal can import either format. This is significant, because when I export in iCalendar format, the all-day events get imported into iCal properly. When I use vCal, they show up as one-minute meetings starting at midnight.

So… let’s just use iCalendar instead of vCal, right? Wrong. First off, I have no problem exporting a small date range (say, a month) in iCalendar format. When I try to export a 3-year date range, Oracle Calendar goes off into la-la land and never comes back. OK, well maybe it eventually comes back, but I gave up after about 20 minutes and killed it. This happened with multiple clients on multiple machines, so it’s not just the Mac. It’s either having a problem with one of my entries (which would be a bug), or it just plain takes forever. Either way, this makes it unusable for my purposes.

Not only that, when I managed to successfully export an iCalendar file, iCal wouldn’t import it. It imports the first entry and then seems to quit. Not sure which app is at fault here, but don’t really care.

That leaves me with vCal. Oracle Calendar will export three years of data in vCal format in about a minute or so. Not exactly lightning fast, but usable. Now, how to get iCal to treat my events as events and not 1-minute meetings?

Here’s the deal: the vCal spec uses the DTSTART and DTEND fields to identify meeting start and end times, respectively. If you leave out DTEND, it treats the entry as an untimed event. And it works. If I edit the vCal file and remove DTEND from an untimed event, iCal imports it properly. Here’s a Perl script to do it:

#!/usr/bin/perl
#
while (<>) {
    print;
    if (/^BEGIN:VEVENT/) {
        printEvent();
    }
}
exit 0;


sub printEvent() {
    my @evData = ();
    my $miscFlag = undef;
    while (<>) {
        push(@evData, $_);
        if (/^CATEGORIES:MISCELLANEOUS/) {
           nbsp;$miscFlag = 1;
        }
        elsif (/^END:VEVENT/) {
            foreach (@evData) {
                print unless (/^DTEND:/ && $miscFlag);
            }
            last;
        }
    }
  }

iCal seems promising

iCal is the calendaring app that Apple includes with MacOS X. It comes bundled with another app, iSync, which handles synchronization with the Palm. On MacOS 10.4 (Tiger), iCal’s app data lives under $HOME/Library/Application Support/iCal. It appears that the calendar data itself is stored in iCal format (.ics), while the metadata is stored in XML format. Separate calendar categories are stored in separate files, unlike the single monolithic binary file Palm Desktop uses. All data files appear to be flat ASCII. That means that, if I wanted to, I could easily maniuplate the files using Perl or somesuch. However, not knowing the interrelationships between the various files, I feel like I should probably avoid this. So, let’s look at the app and see what kind of import features it offers.

iCal calls calendar categories “Calendars”. When I go to import a vCal file, it asks me to select a destination calendar. I can pick an existing calendar, or tell it to create a new one. In the latter case, iCal creates a calendar with the same name as the vCal file (minus extension). It appears to ignore the category data in the vCal file, which for my purposes is good.

To delete a calendar, I just select it in the left pane and press the “Delete” key. It warns me that all entries under that calendar will be deleted, then does it. Everything is undoable.

This seems to work great. The import process is smooth. It creates a new calendar category for me automatically. Deleting the data (prior to a subsequent import) requires only one keystroke. It appears to import locations and attendees too. The only drawback is the handling of “daily notes” and “day events” from Oracle Calendar. However, this problem is on the export side. Ideally I’d like these to come in as “all day” events rather than 12:00am-12:01am meetings. If I can’t configure things this way on the export side, I should be able to write a perl script to modify the vCal import file.

iCal also includes sharing features. I can subscribe to a calendar on the internet, and also publish my calendar to a WebDAV server. I haven’t researched this much, but I hopefully I can use this to access my calendar from anywhere on the net (read: my desktop machine at work).