[Pythonmac-SIG] Scripting iCal :: getting the events of the day?

has hengist.podd at virgin.net
Wed Jul 7 14:26:56 CEST 2004


Paul Berkowitz wrote:

>One of my main goals with doing so is to extract all the events that 
>happen to occur on any given day.
>
>It's not so ornate as all that. iCal stores its events in separate 
>calendars, so you have to search per calendar. It implements 'whose 
>clauses' for quick searching. Here's how to do it in pure 
>AppleScript, which doesn't really belong on this list. You should 
>join the AppleScript-Users mailing list, on Apple's website.

I think a better list for Python users who wish to learn application 
scripting would be Dartmouth's MACSCRPT list, which is language 
agnostic and more programmer-friendly than AS Users:

<http://listserv.dartmouth.edu/scripts/wa.exe?A0=macscrpt&D=1&H=0&O=D&T=1>


>set today to (current date) --or date "8/1/2004"
>set time of today to 0 -- midnight, if not
>set tomorrow to today + (1 * days)
>tell application "iCal"
>     set dayEvents to {}
>     repeat with c in (every calendar)
>         set end of dayEvents to (every event of c whose start date „ 
>today and start date < tomorrow)
>     end repeat
>end tell
>return dayEvents

Here's the equivalent Python:

#######

from datetime import date, datetime, timedelta
from appscript import *

today = datetime.fromordinal(date.today().toordinal()) # [1]
tomorrow = today + timedelta(1)

events = []
for cal in app('iCal.app').calendars.get():
     events.extend(
         cal.events.filter(
                 (its.start_date >= today).AND(its.start_date < tomorrow)
                 ).get()
         )

print events

#######

which will return something like this:

     [app(u'/Applications/iCal.app').calendars[2].events[4], 
app(u'/Applications/iCal.app').calendars[2].events[5], 
app(u'/Applications/iCal.app').calendars[6].events[7]]

...

Now, you _should_ be able to do away with the 'for' loop and just use 
the following reference instead:

events = app('iCal.app').calendars.events.filter(
         (its.start_date >= today).AND(its.start_date < tomorrow)
         ).get()


This _ought_ to return a list like:

--> [[], [app(u'/Applications/iCal.app').calendars[2].events[4], 
app(u'/Applications/iCal.app').calendars[2].events[5]], [], [], [], 
[app(u'/Applications/iCal.app').calendars[6].events[7]], []]

which could then be flattened using:

     reduce(lambda e,v: e+v, events)


However, in OS 10.2 [and maybe 10.3; I'm not sure if it's been fixed 
yet] this reference is partly broken and instead returns this mess:

--> [k.missing_value, 
[app(u'/Applications/iCal.app').calendars[2].events[4], 
app(u'/Applications/iCal.app').calendars[2].events[5]], 
k.missing_value, k.missing_value, k.missing_value, 
app(u'/Applications/iCal.app').calendars[6].events[7], 
k.missing_value]


which you'll need to pass through the following to clean it up:

     events = [type(e) == list and e or e != k.missing_value and [e] 
or [] for e in events]

...

Kind of annoying, but Mac application scripting has always been 
riddled with bugs, flaws and inconsistencies. While you can learn the 
essential principles in an hour, it takes rather longer to develop 
the deep voodoo skills required to bend the less well-implemented 
application scripting models to your will. Which totally bites, but 
I'm sure y'all know where Radar is...;)

When it does work, however, it's an absolutely wonderful technology. 
e.g. InDesign's scripting model is a thing of beauty (one of its 
engineers was on the original team that developed the technology), 
and I'm sure Paul can tell you lots of stories about Entourage and 
other great scriptable apps. It's just unfortunate that Apple's own 
iApps are not yet amongst this list, but their engineers are working 
on it so fingers crossed they'll get there eventually.

HTH

has

[1] The next version of appscript can pack date and time objects 
directly, simplifying this line to 'today = date.today()'
-- 
http://freespace.virgin.net/hamish.sanderson/


More information about the Pythonmac-SIG mailing list