(* This code belongs to Ryan Cuthbertson. Licence: You may use fragments or ideas from here in your own scripts. If the size of the fragment used in your script is appreciable (eg. the download subroutine) you must make acknowledgement of its source in your code, and if the script is to be distributed, in your read me/documentation or other appropriate place. If this sounds too restrictive, contact me for special permission. If you wish to modify this code and use it for your own purpose, you may, provided you acknowledge this as the original version and do not publicly redistribute your version without permission. Only the original unmodified version with all its other files (eg. the Read me) can be redistributed. Thank you! Tested for iCal 1.5.5 (Panther) and 2.0.3 (Tiger) Known probs: Don't think it works right on repeating events. Not that it should... Recurring todos, ugh! Version History: 1.0 Initial release *) property randomIdentifier : 68894652 -- ^ This is used by the "areYouMe" method which this script will attempt to call on the event's open file alarm file. The "areYouMe" method will return the random number which will be checked for equality by the main method. --Else I could make this script an application and use (path to me as text). --tell application "iCal" to activate tell application "iCal" to set calList to every calendar repeat with thisCal in calList tell application "iCal" to set convertMePosList to uid of (every event in thisCal whose open file alarms is not {} and start date is less than or equal to (current date) + 20 * minutes) -- convertMePosList must be a list of UIDs rather than iCal events because after an event is deleted, the list points to different events. repeat with thisEventUID in convertMePosList tell application "iCal" set thisEvent to item 1 of (every event in thisCal whose uid is thisEventUID) set attachedFiles to filepath of every open file alarm in thisEvent end tell repeat with attachedFile in attachedFiles set attachedFile to text 17 thru end of attachedFile set attachedFile to my decode_text(attachedFile) set areYouMeResult to "" --for now try set attachedFile to (POSIX file attachedFile) as alias -- may fail if the file has been moved and because iCal is stupid for not updating the path by using the alias system. set hopefullyMe to load script attachedFile set areYouMeResult to areYouMe() of hopefullyMe on error --it seems the attached file is not me. No further action in this iteration. end try if areYouMeResult is equal to my randomIdentifier then --thisEvent is an event requiring conversion. tell application "iCal" -- Make a new To Do item set newTodoProps to {} set todoSummary to summary of thisEvent if todoSummary starts with "start " or todoSummary starts with "begin " then set todoSummary to text 7 thru end of todoSummary end if set newTodoProps to newTodoProps & {summary:todoSummary} set todoURL to (url of thisEvent) as string set newTodoProps to newTodoProps & {url:todoURL} set newTodoProps to newTodoProps & {description:(description of thisEvent)} -- Only works on Tiger :-( Don't tell Jonathon. --get dueDate set dueLine to "" --for now repeat with thisPara in (every paragraph in (description of thisEvent as text)) if thisPara starts with "due" then set dueLine to thisPara as text end repeat if dueLine is not "" then try --dates start with a number if first character of word 2 of dueLine is in "1234567890" then set dueDateText to text from word 2 to last word of dueLine else -- eg. "due on 31/3/06" set dueDateText to text from word 3 to last word of dueLine end if tell me to set dueDate to date dueDateText -- telling iCal doesn't work (?!) set newTodoProps to newTodoProps & {due date:dueDate} on error display dialog "Couldn't work out the due date" buttons {"Cancel", "Set to none"} default button 2 with icon caution end try else --do nothing, they didn't put a due date. end if make new todo at end of thisCal with properties newTodoProps set myTodo to properties of the result -- log (myTodo) delete thisEvent --display dialog "a todo was converted" exit repeat --we don't need to check the other attachedFiles for thisEvent. end tell else --It's not me that's attached. Must be some other script with a similar mechanism. Ignore and continue. end if end repeat end repeat end repeat to areYouMe() return randomIdentifier end areYouMe --Thanks to Apple for supplying the following code (which would not be necessary if iCal was better). -- this sub-routine is used to decode text strings on decode_text(this_text) set flag_A to false set flag_B to false set temp_char to "" set the character_list to {} repeat with this_char in this_text set this_char to the contents of this_char if this_char is "%" then set flag_A to true else if flag_A is true then set the temp_char to this_char set flag_A to false set flag_B to true else if flag_B is true then set the end of the character_list to my decode_chars(("%" & temp_char & this_char) as string) set the temp_char to "" set flag_A to false set flag_B to false else set the end of the character_list to this_char end if end repeat return the character_list as string end decode_text -- this sub-routine is used to decode a three-character hex string on decode_chars(these_chars) copy these_chars to {indentifying_char, multiplier_char, remainder_char} set the hex_list to "123456789ABCDEF" if the multiplier_char is in "ABCDEF" then set the multiplier_amt to the offset of the multiplier_char in the hex_list else set the multiplier_amt to the multiplier_char as integer end if if the remainder_char is in "ABCDEF" then set the remainder_amt to the offset of the remainder_char in the hex_list else set the remainder_amt to the remainder_char as integer end if set the ASCII_num to (multiplier_amt * 16) + remainder_amt return (ASCII character ASCII_num) end decode_chars