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

10.6: Display a summary of iCal events in Terminal Apps
Many people and companies use shared calendars to keep track of the time spent on projects. I wrote a Python script (free, open source) called icalreport to display monthly summaries of iCal events, including Microsoft Exchange calendars.

It has several command-line options to customize the output to fit your needs.

[robg adds: This worked as described in my testing. Just in case the original site ever vanishes, I've reproduced the code in the remainder of this hint, but check the link first for the newest version.]

#!/usr/bin/python
 
# Nicolas Seriot
# 2009-09-28
# http://github.com/nst/iCalReport
 
import sys
import datetime
import re
from optparse import OptionParser, OptionGroup
from Foundation import NSProcessInfo
 
class CalReport(object):
    
    def __init__(self, cal_name, field='title'):
    
        if field not in ['location', 'title']:
            raise Exception('Not a suitable field: %s' % field)
    
        self.cal_name = cal_name
        self.field = field
        
        self.store = CalCalendarStore.defaultCalendarStore()
        
        predicate = NSPredicate.predicateWithFormat_("title == \"%s\"" % self.cal_name)
        
        self.calendars = self.store.calendars().filteredArrayUsingPredicate_(predicate)
 
        if len(self.calendars) != 1:
            print "Error: %d calendars with title %s" % (len(self.calendars), self.cal_name)
            sys.exit(1)
 
    def print_digest(self, start_date, stop_date):
    
        predicate = CalCalendarStore.eventPredicateWithStartDate_endDate_calendars_(start_date, stop_date, self.calendars)
        
        events = self.store.eventsWithPredicate_(predicate)
                
        projects = {}
        
        for e in events:
            name = e.location() if self.field == 'location' else e.title()
            
            if not name in projects:
                projects[name] = 0.0
            
            projects[name] += e.endDate().timeIntervalSinceDate_(e.startDate())
        
        total = 0.0
        
        print "-" * 30
        print "From", start_date, "to", stop_date - datetime.timedelta(days=1)
        print "-" * 30
        
        for (p, s) in projects.iteritems():
            if not p:
                p = ''
 
            print p.ljust(20, ' '), "%0.2f" % (s / 3600.0)
            total += s
        
        print "-" * 30
        print "Total".ljust(20, ' '), "%0.2f" % (total / 3600.0)
        print "-" * 30
 
if __name__ == '__main__':
 
    os_version = NSProcessInfo.processInfo().operatingSystemVersionString()
    os_version = re.compile("Version (\d+\.\d+)\.\d+ .*").match(os_version).groups()[0]
    
    if float(os_version) < 10.6:
        print "icalreport needs Mac OS X 10.6 or later"
        sys.exit(1)
        
    from CalendarStore import *
 
    now = datetime.datetime.now()
 
    parser = OptionParser()
 
    parser.add_option("-c", help="Name of the calendar (mandatory)", dest="cal_name", metavar="NAME",)
    parser.add_option("-m", action="store", type="int", dest="month_start", metavar="MONTH",
                      help="Number of the month for which to report (default: current)")
    parser.add_option("-u", action="store", type="int", dest="month_stop", metavar="MONTH",
                      help="Number of the month until which to report (default: month_start)")
    parser.add_option("-l", action="store_true", dest="use_location",
                      help="Look for projects in events locations (default: titles)")
 
    group = OptionGroup(parser, "Purpose", "Report the time spent on projects by reading iCal events.")
    parser.add_option_group(group)
                      
    group = OptionGroup(parser, "Example", "&#36; icalreport -c MyHours -m 9 -u 10 -l")
    parser.add_option_group(group)
    
    (options, args) = parser.parse_args()
    
    if not parser.values.cal_name:
        parser.print_help()
        sys.exit(1)
    
    if parser.values.month_start:
        month_start = options.month_start
    else:
        month_start = now.month
    
    month_stop = month_start
    
    if parser.values.month_stop:
        month_stop = parser.values.month_stop
    else:
        month_stop = month_start
    
    month_stop = (month_stop) % 12 + 1
 
    year_shift = 1 if (month_stop <= month_start) else 0
            
    start_date = datetime.date(year=now.year, month=month_start, day=1)
    stop_date = datetime.date(year=now.year+year_shift, month=month_stop, day=1)
    
    field = 'location' if parser.values.use_location else 'title'
    
    ct = CalReport(cal_name=parser.values.cal_name, field=field)
    ct.print_digest(start_date, stop_date)
    •    
  • Currently 2.56 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (9 votes cast)
 
[6,221 views]  

10.6: Display a summary of iCal events in Terminal | 4 comments | Create New Account
Click here to return to the '10.6: Display a summary of iCal events in Terminal' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
10.6: Display a summary of iCal events in Terminal
Authored by: russkey on Oct 21, '09 08:40:19AM
why not use icalBuddy i find that it is very nicely flexible.

[ Reply to This | # ]
10.6: Display a summary of iCal events in Terminal
Authored by: MurphyM on Oct 21, '09 09:15:49PM
Related : View and create Google Calendar events in Terminal with gcalcli

[ Reply to This | # ]
10.6: Display a summary of iCal events in Terminal
Authored by: Helge33 on Oct 22, '09 01:59:29AM

Interesting example to get useful data from iCal, Mail or Addressbook. Its a pity that this is 10.6 only (I am not able to asses why). I think since 10.4 there was always several SQL database hidden in OSX which hold all the info from iCal, Mail and Addressbook.

Thus with some scripting and SQL queries it should be possible to get useful queries like "all e-mails from that person in Addressbook within the last year" and "all ical events where Person X was invited" etc.



[ Reply to This | # ]
10.6: Display a summary of iCal events in Terminal
Authored by: loren_ryter on Oct 25, '09 09:35:47PM

while I'm not sure about this particular hint, icalbuddy works nicely (see above) and should work on Leopard also (though also not 100% of that -- but it relies on calendar store which is a leopard + technology).



[ Reply to This | # ]