Kasperian Moving Parts

kinda like Batman, but with a wife and 3 kids

Syncing Exchange Calendar 1-way Into Korganizer/Kontact

| 10 Comments

I’ve alluded to this before, but never really posted properly about it. Warning: this is very geeky…

My current employer uses Exchange as its mail/contact/calendaring solution. I have no say in the matter, so hush. =;) But this poses some challenges to those of us insisting on using Free Software at work (like me). Evolution has a connector for this, but I much-prefer KDE solutions, so I stick with Kontact and Korganizer, and of course KPilot to sync my calendars with my palm. To further complicate things, nobody in KDE PIM has the time/resources to make Kontact play nicely with Exchange as a calendar back end.

So, what I must have is the ability to keep my private and work calendars separate. Read: I do not want to be keeping my personal information on the corporate Exchange server. I also have a Palm (Treo 650 currently) PDA and I sync all of my calendar data with it and Korganizer’s “std.ics” iCalendar file. Because of the fact that I insist on keeping my work and private data separate, I cannot use the otherwise possibly useful VersaMail Exchange plugin that synchronizes Mail/Calendar/Contact data for you. Also, KPilot operates best when it’s synchronizing the Palm calendars with a single iCal file, so creating a separate file for korganizer to show me with my Exchange calendar is less than useful.

My approach, then is to write a wrapper process that can retrieve my Exchange calendar, tag each calendar item with a category that I only use for Exchange, and then 1-way sync my exchange calendar into Korganizer’s std.ics. Oh–I also use KMail to access my Exchange mail account via IMAP, and because the current lack of built-in calendaring cooperation between KDE PIM (note: hire me to fix this!! =;) ), whenever I get a meeting request, I click the URL and open the appointment in Firefox (using Outlook Web Access). Not perfect, but certainly very functional and stable and I don’t have to bring up Outlook or Windows for any of it, which makes me very happy.

My first stab at this (which has worked very well for 6+ months now) was to use OWASync (Outlook Web Access Sync) which was written by Graham Cobb. This is a TCL/Starkit-based solution. And again, this has worked well for quite a while now, but has recently stopped working for some unknown reason.

So since OWASync has been having troubles retrieving my calendar lately (and I really do not like TCL), I started looking for another Exchange retriever, and I found a really, really nice Ruby implementation here. It’s based on the RExchange project, and provides a nice and very easy to understand front-end script. I’ve never touched Ruby before this, but I’ve been playing with this script (adding some missing fields like appointment status, location, and description) and I am hooked! Ruby is very cool. And the thing I like best about this approach over the TCL/Starkit one is that I can easily modify and test this Ruby stuff and feel confident that I know what I’m doing.

So to put it all together, I have a shell script that I have crontabbed to run every 10 minutes. This shell script calls my modified Ruby script which pulls down my Exchange calendar (VERY quickly) and creates a single file which has all of my calendar items in it. As it creates the file of events, I have it adding on my custom “Exchange-only” category (CATEGORIES:WorkXChange) to each event. I do this so that my shell script can clean up all previously 1-way-synced Exchange items from my korganizer iCal file, and so that I can also associate a color with this category in both korganizer and my Treo so that I can easily see which items in my calendar are work-related. If the calendar retrieval was successful, my shell script then saves off a copy of my korganizer’s std.ics file, removes all events which have “WorkXChange” in it, and then adds in all of my just-download Exchange events. It also reports on how many events were there before and after the changes so that I can easily tell if something is going wrong. And it does some sanity-checking before overlaying korganizer’s std.ics file to make sure that it hasn’t been changed since it grabbed a copy of it. Korganizer will recognize that its file has changed and reload the calendar automatically. And KPilot will remove the previous Exchange events and add the new ones for me as well.

Perhaps not quite as seamless as one might like, but until I (or some other fearless KDE-PIMster) find the time to start getting Kontact to play nicely with Exchange’s calendaring stuff, it most certainly does the trick. HTH!! =:)

UPDATE : I’ve discovered another really cool ruby library called simply enough iCalendar. It does a very nice job of dealing with iCalendar files. So I’ve completely re-done the merging as I have posted it above and now use 1 shell script that calls 2 ruby scripts

  • rexport.rb which does the exchange OWA calendar retrieval and iCalendar output
  • calmerge.rb which uses the iCalendar ruby library and harvests old X-PILOTIDs from korganizer’s file, then removes the last-synced Exchange events, then merges in the just-downloaded events.

Much more better. But I’ll leave the old, crufty shell/perl method as it is above too… =;)

UPDATE Part Deux : I wanted to add ATTENDEE and ORGANIZER retrieving to my Exchange download/merge process. I hacked it easily enough into rexport.rb and rexchange/appointment.rb, so my Exchange calendar download process works correctly. However, I couldn’t for the life of me get the Ruby iCalendar library to deal with the multiple-occurences-per-VEVENT ATTENDEE tag correctly. So I did what I should have done to begin with (although learning Ruby was REALLY cool) and wrote a simple C++ program that uses KDE PIM’s libkcal library to handle the calendar merging for me. And it works MUCH better and MUCH faster now. You can find mergecalendars.cc in kpilot’s tests directory, in which you’ll also find the CMakeLists.txt for it. You’ll also need to have kdepim and kdepim-dev installed on your machine to build mergecalendars.cc.

So, hopefully this is the last update to this post, and hopefully this will come in nice and handy for someone else who wants to be able to view their Exchange calendar in kontact. Granted, I’ve twisted this to a larger scale than most people would need to because of how I wanted to keep my private data out of the Exchange server, and I want to sync it all reliably with my Treo 650 via KPilot. Here’s a tarball of the whole thing (make sure you right-click and choose save-as). I’d love to hear from anyone who is looking to do what I’ve done here and please let me know if this does or does not help you in your travels, oh weary Exchange sojourner.

UPDATE Part Trois : Here’s the latest skinny, thanks to Exchange 2007, grr…

Author: Jason 'vanRijn' Kasper

My name is Jason ‘vanRijn’ Kasper. I am the ring leader of the amazing Kasper family. I am unashamedly a Christian Nerd. These are our stories….

10 Comments

  1. Great solution, I can’t get it to work though. Looks like our exchange environment uses form based authentication

    https://myserver.com/exchweb/bin/auth/owalogon.asp?url=https://myserver.com/exchange/&reason=0

    Is there a way to get this to work or is it impossible with form based authentication?

    Thanks

  2. Hi Joe! Yes, absolutely! My previous employer used FBA and this method worked perfectly. I do think that there’s a trick in getting the URL right…. I think you might have to set your environment variables like this:

    export _CUSER=USERNAME
    export _CPASS=PASSWORD
    export _COWAURL=https://WEBSERVER/Exchange/USERNAME

    I think the trick is putting the username at the end of the OWA URL?

  3. Thanks for the response,

    No Luck

    From a browser the url is- https://mycompany.com/exchange/
    it then redirects to- https://mycompany.com/exchweb/bin/auth/owalogon.asp?url=https://mycompany.com/exchange/&reason=0

    I have tried every combination of username and url – no luck. I’m using Ruby 1.8.6 on Mac OSX

    Thanks

    Below are some extracts from the errors
    ruby 1.8.6 (2007-06-07 patchlevel 36) [universal-darwin9.0]
    ./rexchange.rb:19: warning: global variable `$log’ not initialized
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:571: warning: using default DH parameters.
    Exception `REXML::ParseException’ at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/parsers/baseparser.rb:320 – Missing end tag for ‘META’ (got “HEAD”)
    Line:
    Position:
    Last 80 unconsumed characters:
    The page cannot beborder=0 cellspacing=10>
    Exception `REXML::ParseException’ at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rexml/parsers/baseparser.rb:375 – Missing end tag for ‘META’ (got “HEAD”)
    Line:
    Position:
    Last 80 unconsumed characters:
    The page cannot beborder=0 cellspacing=10>

  4. Hi,
    Can you please publish the complete working archive of the ruby program ? (with the libraries and so on).

    Thanks a lot for your help.
    Regards.

  5. I did. It’s listed above as “the tarball.”

  6. Pingback: KPilot Hackery of Sorts (or How To Sync Your Work’s Exchange Calendar To Your Palm, Part III) | moving parts of the kasper clan

  7. I get a message telling me that the method “calendar” is undefined (from a line in folder.rb). After poking around for a bit, I got an inkling that the Rexchange guys haven’t updated for Exchange 2007 and that Rexchange in its current state is asking for something via webdav that simply isn’t there anymore… :-/ Is this the case? Or did something go awry in my setup?

    -Adam

  8. @Adam Keck: =:D LOL. Yeah, I had to go back to OWASync. I’ll add a note to this post to look there instead. =:)

  9. Pingback: Exchange 2003 ICS v1.0 – LMB^Box

Leave a Reply

Required fields are marked *.