You may know that Safari Bookmarks, Address Book entries, and iCal calendars are not single-file based, i.e., that an individual iCal event, A/B entry, or Safari Bookmark is not a single file; it’s in a database file. Safari’s Bookmarks (and similarly Camino’s) are stored in a single plist file (~/Library/Safari/Bookmarks.plist), Address Book uses a data file and two index files (~/Library/Application Support/AddressBook/AddressBook.data, ABPerson.skIndexInverted, and ABSubscribedPerson.skIndexInverted, where sk stands for Search Kit), and finally, iCal maintains a directory for each Calendar (~/Library/Application Support/iCal/Sources/.calendar, where UUID identifies the user and calendar).
This means that iCal has to use Spotlight (mdfind) to find stuff and when you have made a change to iCal there’s a timing issue with the metadata record. After iCal’s mdimporter has run again, the metadata, apparently including the uuids of events has changed. Then when you use an old UUID, it leads you to the wrong record, hence the need for a new search in the refreshed metadata database. mdutil can be used to turn the spotlight mdimport for an app on and off, so you might have to play with that or figure out how to use mdfind to locate your events directly.
You can see these metadata files like so:
set IC to do shell script "ls ~/Library/Caches/Metadata/iCal/"
-- Long hex-coded file names, one for each calendar.
-- Assuming you have at least one uuid:
set C to paragraph 1 of IC
set aCal to do shell script "ls ~/Library/Caches/Metadata/iCal/" & C
-- a string of files ending in "-.icalevent"
To find a calendar cache for an event, try playing with this:
-- Find the calendar cache for the event containing the name (of my dentist, e.g.) after today
set D to paragraph -1 of (do shell script "mdfind 'kMDItemTitle == \"Dr. Penwell\" && kMDItemDueDate > $time.today'") as Unicode text
-- Get the value of Date and Time for this event (not combined to keep it clearer but recall they can be)
set DT to paragraph -1 of (do shell script "mdls -name kMDItemDueDate " & D)
-- Prepare a notification (in AppleScript rather than the shell)
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "kMDItemDueDate = " as Unicode text
set Apt to text item 2 of DT
set AppleScript's text item delimiters to "/"
set tDay to (reverse of (words 1 thru 3 of Apt)) as text
set AppleScript's text item delimiters to ":"
set tTime to (words 4 thru -3 of Apt) as text
set AppleScript's text item delimiters to tid
set msg to "See Dentist on " & tDay & " at " & tTime
--> "See Dentist on 17/04/2007 at 11:45"
You can do the same sort of thing with Address Book metadata:
set tName to text returned of (display dialog "Enter a known Address Book entry as it appears there" default answer "Cadabra Abra" with title "Look Up Phone Numbers") as Unicode text
-- defaults to the well-known genie and the entry in my Address Book that I use for testing. ;-)
try -- combined form for one call, errors for 0 or more than 1 value
set dataAB to (do shell script "P=`mdfind 'kMDItemContentType == com.apple.addressbook.person && kMDItemDisplayName == \"" & tName & "\"'`;mdls -name kMDItemPhoneNumbers \"$P\"")
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "kMDItemPhoneNumbers ="
set PN to text item 2 of dataAB
set AppleScript's text item delimiters to tid
set PhNums to text 3 thru -2 of PN
display dialog PhNums
on error -- Either no such name found or too many found if the name appears more than once.
display dialog "Sorry, no such name appears." & return & return & "Did you enter it as it is in your Address Book.app?" & return & return & "Normally: Last_Name First_Name" with icon 0
end try
HTH
Adam