Populate GCal Using Google Calendar API

Today I present a Python script using the Google Calendar API to read events from my text-based desktop calendar and push them to the cloud for global access.

I was busy last week with the Revit API and The Building Coder, after returning from my vacation and lots of nice places and activities in Ticino, Mont Blanc, and the French Jura.

Now I finally got to look at something not related to the Revit API, or to any other CAD modelling, for a change:

My Text Based Calendar

I use a simple text file to manage my personal and profession calendar events.

Here is a typical series of entries, for the Autodesk cloud accelerator in Prague next month:

2015-09-13 accelerator@prague begin
2015-09-13 12:35-13:55 zrh-prg # lx1486, confirmation... trip record locator...
2015-09-13 19:00 dinner # Brasileiro Slovanský dům, Na Příkopě 22
2015-09-14 prague
2015-09-15 prague
2015-09-16 prague
2015-09-17 prague
2015-09-18 accelerator@prague end
2015-09-18 14:45-16:05 prg-zrh # lx1487

I prefer text files for storing and managing data, and avoid commercial proprietary formats and software whenever possible.

This solution has proved optimal for me ever since I started using it in February 2003.

I can tell you the exact date I started using it, because all my appointments since then are and remain stored in this one single file, currently still just 165 KB is size:

$ ls -o /j/doc/db/calendar.txt
-rw-rw-rw-  1 jta  164870 Aug 18 22:02 /j/doc/db/calendar.txt

This is obviously extremely handy for editing, searching and archiving.

It also obviously does not provide a very useful visual overview over a week or month.

That is where tools come in handy.

Ever since then, I have also been using pcal to visualise the calendar file contents.

The Pcal PostScript Calendar Program

Pcal is a calendar-generation program that produces nice-looking PostScript output.

It is often used to generate monthly-format calendars, one month per page, with optional embedded text and images to mark special events.

I actually use the HTML output option and a yearly format instead, producing this view in the browser:

Pcal HTML output

This works perfectly fine on the desktop, or wherever I can access the generated HTML output.

Now and then, though, it would be handy to have global access to this data, e.g. to share with friends and colleagues or on the road with no access to this file.

One solution is to feed this data into a Google calendar.

The Google Calendar API

Accordingly, I set up a Google Calendar (GCal) and read about the CalDAV, the Calendaring Extensions to WebDAV, how to synchronise desktop calendars with Google calendar and the Google Calendar CalDAV API Developer's Guide.

As it turns out, I did not need to know much about the underlying technology, because all I need is provided by the Google Calendar API tutorials and samples.

I opted for a solution using Python and headed straight to the Python Quickstart.

I ran into a few hiccups getting it started, which I pretty quickly resolved by consulting StackOverflow, defining the Python search path, installing httplib2, and a couple of reinstallations of the various components using pip:

export PYTHONPATH="/Library/Python/2.7/site-packages:$PYTHONPATH"

After a bit longer than the five minutes promised in the quickstart guide – but not toooo much longer – the quickstart.py sample was up and running.

In order to set up the credentials, the Google libraries open up a web page, ask you to identify yourself, and cache the result locally on your system, e.g., in the file ~/.credentials/calendar-quickstart.json.

Adding an Event to the Google Calendar

Following the lines of the Google calendar API Python quickstart example, the following function adds a new event to my calendar:

def add_event():
  """Add an event using the Google Calendar API.

  Creates a Google Calendar API service object
  and creates a new event on the user's calendar.
  """
  credentials = get_credentials()
  http = credentials.authorize(httplib2.Http())
  service = discovery.build('calendar', 'v3', http=http)

  body = {
    u'status': u'confirmed',
    u'kind': u'calendar#event',
    u'start': {u'dateTime': u'2015-08-19T10:00:00+02:00'},
    u'end': {u'dateTime': u'2015-08-19T10:50:00+02:00'},
    u'summary': u'jeremy test event summary',
    u'organizer': {u'self': True, u'displayName': u'Jeremy Tammik', u'email': u'jeremytammik@gmail.com'},
    u'creator': {u'self': True, u'displayName': u'Jeremy Tammik', u'email': u'jeremytammik@gmail.com'}
  }
  service.events().insert( calendarId='primary', body=body).execute()

The new entry appears immediately in my online calendar like this:

New Google calendar entry

Now I just need to parse my entire calendar file and add all or a selected set of the events defined there.

A later step might be to read back the calendar events from the online calendar, determine what has been modified or added, and update my holy calendar master text file.

I hope this is of use and interest to you as well.