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
try
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
else
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
else
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
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
try
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
else
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
else
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