Groupwise Calendar to Google Calendar Exporter

by Miguel de Icaza

I wrote a small tool that exports my Groupwise Calendar to Google Calendar.

This tool only runs on Windows as it is using the Groupwise COM APIs to fetch the calendar data. I would love to have this work on Linux if someone knows how to get to these from Unix.

You will need the Google Calendar assemblies (Google.GData.AccessControl, Google.GData.Calendar, Google.GData.Extenions) and the Groupwise Assemblies (GroupwiseTypeLibrary, GroupWiseCommander) and a text file that contains your passwords (called `passwords').

´╗┐using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Google.GData.Calendar;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.Accounts;
using System.Threading;
using System.IO;

namespace CalendarExporter
    class Program
	const string google_email = "[email protected]";
	const string groupwise_login = "YOURNAME";
        static void Main(string[] args)
            var f = File.OpenRead("passwords");
            var reader = new StreamReader(f);
            var google_passowrd = reader.ReadLine();
            var groupwise_password = reader.ReadLine();

            new Thread(delegate() {
                Thread.Sleep(1000 * 120);
                Console.Error.WriteLine("Timing out");

            ClientLoginRequest login = new ClientLoginRequest();
            login.AccountType = "GOOGLE";
            login.Email = google_email;
            login.Password = google_password;
            login.Service = "cl";
            login.Source = "YOURNAMECo-CalendarPush-1";

            var token = login.Login();

            CalendarService cs = new CalendarService("YOURNAMECo-CalendarPush-1");

            CalendarQuery cq = new CalendarQuery();
            cq.Uri = new Uri("");
            CalendarFeed resultFeed = cs.Query(cq);
            CalendarEntry gw_at_google = null;
            foreach (CalendarEntry entry in resultFeed.Entries) {
                if (entry.Title.Text == "Groupwise Calendar") {
            gw_at_google = new CalendarEntry();
            gw_at_google.Title.Text = "Groupwise Calendar";
            gw_at_google.Summary.Text = "This is the syncrhonized calendar at Novell's Groupwise server";
            gw_at_google.TimeZone = "America/New_York";
            gw_at_google.Hidden = false;
            gw_at_google.Color = "#2952a3";
            gw_at_google.Location = new Where("", "", "Boston");
            gw_at_google.Selected = true;
            Uri postUri = new Uri("");
            CalendarEntry cal = (CalendarEntry)cs.Insert(postUri, gw_at_google);

            string calurl = cal.EditUri.Content;
            int p = calurl.LastIndexOf ('/');
            string code = calurl.Substring (p);

            Uri edit_uri = new Uri ("" + code + "/private/full");
            GroupwareTypeLibrary.GWSession2Class gsc = null;
                gsc = new GroupwareTypeLibrary.GWSession2Class();
                Console.WriteLine("Did not regsvr the file c:\novell\groupwise\gwcma1.dll and is this program x86-only?");
            var account = gsc.Login(groupwise_login, "", groupwise_password, null, null);
            var path_to_host = account.PathToHost;

            //alendar calendar = new iCalendar();

            int count = 0, skipped =0;
            foreach (GroupwareTypeLibrary.Message m in account.Calendar.Messages)
                if (!m.ClassName.StartsWith ("GW.MESSAGE.APPOINTMENT"))

                GroupwareTypeLibrary.Appointment2 app = (GroupwareTypeLibrary.Appointment2) m;

                // Ignore appointments that are older than 15 days.
                if (app.EndDate < DateTime.Now - TimeSpan.FromDays(7)) {

                var ee = new EventEntry();
                ee.Title.Text = app.Subject.PlainText;
                ee.Content.Content = app.BodyText.PlainText;
                ee.Locations.Add (new Where () { ValueString = app.Place });
                ee.Times.Add(new When(app.StartDate, app.EndDate));
                ee.EventVisibility = app.Private ?
                    EventEntry.Visibility.PRIVATE : EventEntry.Visibility.PUBLIC;

                cs.Insert (edit_uri, ee);

You will also need the Login.cs which is some sample code that I found on the tubes for doing Google Account authentication.

Posted on 02 Dec 2008