Python and iCal

I hacked together the following script to get a list of upcoming activities from iCal and display them in Geektool (or in a terminal). It uses the CalStoreHelper class by Ali Rantakari and probably fails in millions of ways for the poor sods on Mountain Lion1 and anyone else not using my exact setup. Proceed with caution.

The output looks somewhat like:2

Vandaag
10:45 Some appointment
Morgen
Event that takes all day
Woensdag 5 september
04:00 Get up early
14:30 Some other appointment

In case you’re wondering: ‘vandaag’ and ‘morgen’ mean ‘today’ and ‘tomorrow’. If you’re not Dutch you’ll probably want to change the value of today_name and tomorrow_name, as well as the lines setting the timezone and locale. Have fun!

#! /usr/bin/python
#-*- coding: utf-8 -*-

import locale
from sys import stdout
import dateutil.parser
from CalendarStore import CalCalendarStore
from CalStoreHelper import *
from datetime import *
import pytz

tz = pytz.timezone('Europe/Amsterdam')
locale.setlocale(locale.LC_TIME, "nl_NL")

calendars = ['Names of', 'Calendars you', 'want to show'] 

start_date = datetime.now()
end_date = start_date + timedelta(weeks=2)

today_name = "Vandaag"
tomorrow_name = "Morgen"

c = CalStoreHelper()

events = c.getEvents(calendars, start_date, end_date)

cacheDate = datetime.now(tz)

for e in events:
    edate = dateutil.parser.parse(
        e.startDate().descriptionWithCalendarFormat_timeZone_locale_(None, None, None)
    )
    etitle = e.title()
    if datetime.now(tz).date() > edate.date():
        continue
    if cacheDate.strftime("%d %b")!=edate.strftime("%d %b"):
        if datetime.now(tz).strftime("%d %b")==edate.strftime("%d %b"):
            print "\033[1m" + today_name + "\033[0m"
        elif (datetime.now(tz)+timedelta(days=1)).strftime("%d %b")==edate.strftime("%d %b"):
            print "\033[1m" + tomorrow_name + "\033[0m"
        else:
            print "\033[1m" + edate.strftime("%A %-d %B").capitalize() + "\033[0m"
    stdout.write((edate.strftime("%H:%M") + " ") if (e._.isAllDay == 0) else "")
    print(etitle.encode('utf-8'))
    cacheDate = edate

  1. Update: the script still works in Mountain Lion, but you may need to easy_install pytz first. 

  2. A few notes on formatting: "\033[1m" and "\033[0m" set and unset bold text. In Dutch, months are not capitalized, hence the call to capitalize()