Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Make iCal subscribable calendar from Exchange data UNIX
If you're a Mac user in a Windows office, you may get a lot of meeting invitations through Exchange. In, you can click on the iCalendar attachments and have them added to iCal, but iCal doesn't understand Exchange-generated time zones, so you have to manually change them to US/Eastern, or they will get mangled after syncing with .Mac. I was thinking of ways to automate the process, and came up with the following way to generate a calendar you can subscribe to from the Exchange calendar data.

You can access all the calendar events from IMAP, if your Exchange installation is configured for that, through a folder named Calendar. The basic idea is to grovel through all the messages in that folder, and generate one iCalendar file with all the events. While we're at it, we can also translate Exchange's time zone IDs to ones that iCal understands. This script is ruby code that functions as a CGI script to do just that. Make it available from a web server, and subscribe to, for example (enter as one line, not two, with no spaces, and replace all the obvious buts with your specific info):
A few caveats:
  • If you have a lot of calendar items going back years, this is going to be pretty slow; it does no caching.
  • I'm not entirely clear on when new invitations get added to your calendar. You may need to leave Outlook running on a Windows machine somewhere.
  • You can run the script by hand on the command line (ruby script_name.cgi) and type in the parameters by hand to test it.
  • This gives you a read-only view of your Exchange calendar; you will not be able to edit events from iCal.
  • If you don't want your email account information going into web server logs, edit the script to hard code the values.
  • If you live somewhere other than the US East Coast, add appropriate regexps to the clean_timezone function to translate whatever time zones you encounter.
[robg adds: I haven't tested this one...]
  • Currently 2.75 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (4 votes cast)

Make iCal subscribable calendar from Exchange data | 6 comments | Create New Account
Click here to return to the 'Make iCal subscribable calendar from Exchange data' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Make iCal subscribable calendar from Exchange data
Authored by: xevious on Nov 12, '04 11:45:23AM

If you need read/write access to your Exhange calendar, you can try Snerdware's GroupCal.


[ Reply to This | # ]
What Exchange versions does this method support?
Authored by: smanzo on Nov 12, '04 02:58:29PM

I'm still stuck on an Exchange 5.5 server, and was wondering if this tip is 200x specific. I've yet to find a happy way to sync up without having to use the OS 9 Outlook client.

[ Reply to This | # ]
Make iCal subscribable calendar from Exchange data
Authored by: raster on Nov 12, '04 04:33:35PM

Try vCalendar Extractor for getting the data out of Exchange.

Otherwise here's a hack I did in perl to yank the data out using IMAP.

[ Reply to This | # ]
Make iCal subscribable calendar from Exchange data
Authored by: Ptitboul on Jan 22, '08 04:41:04AM

Another approach could be to use to connect to the IMAP server, and to browse the Calendar.imapbox/Messages directory in ~/Library/Mail to extract the calendar information and create the ics file.
Did anyone implement this approach?

[ Reply to This | # ]
Make iCal subscribable calendar from Exchange data
Authored by: Ptitboul on Jan 23, '08 02:07:36PM
It works for me. Either you can run the following script in a crontab, or (if you have Leopard) you can use the new WatchFolder possibility of launchd. It creates an ics calendar file that you can subscribe to if you have a web server running on your machine.
#! /usr/bin/perl
sub isUTF8;

my $dir = '/Users/xxxx/Library/Mail/IMAP-xxxx/Calendar.imapmbox/Messages';
my $ics = '/Library/WebServer/Documents/Calendars/outlook.ics';

if ((stat($dir))[9] < (stat($ics))[9]) {
  # Nothing to update
  exit 0;

opendir DIR, $dir or die "opendir $dir: $!";
open ICS, ">$ics" or die "open $ics: $!";
select ICS;
foreach my $msg (readdir DIR) {
  open FILE, "$dir/$msg" or die "open $dir/$msg: $!";
  while () {
    $events = 1 if /BEGIN:VEVENT/;
    next if /^ATTACH:/;
    # I have to adjust the TimeZone, I don't know why my Exchange's format
    # is not understood by iCal
    s|TZID="\(GMT\+01.00\) Sarajevo/Warsaw/Zagreb"|TZID=Europe/Paris|;
    s|TZID="GMT \+0100 \(Standard\) / GMT +0200 \(Daylight\)"|TZID=Europe/Paris|;
    s|TZID="\(GMT\) Greenwich Mean Time/Dublin/Edinburgh/London"|TZID=Europe/London|;
    # Force UTF8 characters.
    # If there are Latin1 characters, iCal goes in an infinite loop.
    $_ &= "\x7f" x (length $_) unless defined(isUTF8($_));
    # Multi-lines
    $_ = "\n$_" unless s/^ //;
    push @lines, $_ if $events > 0;
    $events = 0 if /END:VEVENT/;
  close FILE;
  my $event = join ('', @lines);
  print $event;
  undef @lines;

print "\nEND:VCALENDAR";
close ICS;

sub isUTF8 {
  my $data = shift;
  return 1 if $data =~ /(
	    | [\xe0-\xef][\x80-\xbf]{2}
	    | [\xf0-\xf7][\x80-\xbf]{3}	) /x;
  return undef if $data =~ /([\x80-\xff])/;
  return 0;

[ Reply to This | # ]
Make iCal subscribable calendar from Exchange data
Authored by: Ptitboul on Sep 05, '08 05:08:58AM
the script is missing an element. You have to replace
  while () {
  while (<FILE>) {

[ Reply to This | # ]