🕷 zenspider.com

by ryan davis

Looking for the Ruby Quickref?

Applescript: Nuke Ancient Events - make iSync faster/happier

Published 2006-06-22 @ 00:21

Tagged thoughts, toys, applescript

I’ve been using iCal and iSync since they came out (sometimes to my dismay). This script seems to do a good job purging crap and making slooow bluetooth syncs a lot zippier.

As the code says: Be smart. Make backups. I won’t be held responsible for shit. You’ve been warned.

Otherwise, I’d like to know what you think.

    Nuke Ancient Events - by Ryan Davis (ryand-applescript@zenspider.com)
    *** Be smart. Make backups. I won't be held responsible for shit. You've been warned. ***

    Does a two-pass purge on your iCal Calendars:
    First, it deletes all events older than days_ago days (edit the value as you see fit--I use 90). iCal supposedly does this, but seems to get confused or stuck with certain types of events (specifically, recurring events of particular types or states).
    Second, it goes through the remaining events and deletes any excluded dates older than days_ago days. Excluded dates are events where a repeating calendar item was moved or deleted for a particular entry (e.g., You have a weekly meeting, but moved last week's meeting to Tuesday or flat out cancelled it). Excluded dates in particular seem to sit around for a long long time. I've seen upwards of 50 in some of my older entries.
    Hopefully, by purging these entries, syncing to .mac and your peripherals speed up once the changes propagate. I did have some cases where my phone argued with iCal and the exclusions came back, but running this a few times and syncing everything should generally make things happier.
    NOTE: you must set be_destructive to true for this to have any effect.

-- tweak these how you see fit
set days_ago to 90
set be_destructive to false

-- don't bother changing these
set today to current date
set recent to today - (days_ago * 86400)
set oldsep to AppleScript's text item delimiters
set AppleScript's text item delimiters to {";"}

tell application "iCal"
    set old to 0
    set not_until to 0
    repeat with aCalendar in (every calendar whose writable is true)
        repeat with anEvent in (every event of aCalendar whose start date < recent and end date < recent and recurrence is not "")
            set r to recurrence of anEvent
                set untilstr to third text item of r
                if untilstr starts with "UNTIL" then
                    -- damn applescript is dumb...
                    set newdatestr to do shell script "/usr/local/bin/ruby -rtime -e 'if ARGV.first =~ /UNTIL=(\\w+)/; then puts Time.parse($1).strftime(\"%B %d, %Y\"); else puts Time.now; end' " & untilstr
                    set d to my date newdatestr
                    if d < recent then
                        if summary of anEvent does not start with "BAD:" then
                            set newsummary to "BAD: " & summary of anEvent
                            set summary of anEvent to newsummary
                        end if
                        set old to old + 1
                    end if
                    set not_until to not_until + 1
                end if
            on error
                -- do nothing
            end try
        end repeat
        if be_destructive then
            delete (every event of aCalendar whose summary starts with "BAD:")
        end if
    end repeat
    display dialog "Deleted " & old & " events. Couldn't delete " & not_until & " events because they haven't finished yet or were otherwise borked."
    set errors to {}
    set deletes to 0
    set keeps to 0
    repeat with aCalendar in (every calendar whose writable is true)
        repeat with anEvent in every event in aCalendar
            set thedates to excluded dates of anEvent
            set theprops to properties of anEvent
            if thedates is not {} then
                set newdates to {}
                repeat with aDate in thedates
                    if recent < aDate then
                        copy aDate to the end of newdates
                        set keeps to keeps + 1
                        set deletes to deletes + 1
                    end if
                end repeat
                if be_destructive and (count of newdates) is not (count of thedates) then
                    set excluded dates of anEvent to newdates
                end if
            end if
        end repeat
    end repeat
    display dialog "Deleted " & deletes & " excluded dates. Kept " & keeps & " dates."
end tell

set AppleScript's text item delimiters to oldsep