(Disclaimer: I'm tired, this is incomplete - please feel free to add to it!)
Here is somewhat of a two-way sync between Entourage and OmniFocus. It works by exporting all your Ent. tasks to OmniFocus, with the Ent. task linked as an attachment in the OF note.
If it finds that an Ent. task is already linked to some OF task, it tries to keep that pair of tasks in sync based on modification dates (this is the incomplete part, it checks but doesn't yet update - see code)
There is also code to try and sync the OF task id property to the Ent. task GUID property, however OF doesn't properly let the id be set (bug has been filed), hence we check for links instead. IDs would be quicker.
I put it to the community to please add to this, and to OmniFocus that if you want to add a proper Entourage <-> OmniFocus sync, it's all yours! (Free upgrades, maybe?)
Hope someone finds it useful! Thanks to all who've inadvertantly helped me so greatly with their code snippets from this forum!
Cheers,
David.
Here is somewhat of a two-way sync between Entourage and OmniFocus. It works by exporting all your Ent. tasks to OmniFocus, with the Ent. task linked as an attachment in the OF note.
If it finds that an Ent. task is already linked to some OF task, it tries to keep that pair of tasks in sync based on modification dates (this is the incomplete part, it checks but doesn't yet update - see code)
There is also code to try and sync the OF task id property to the Ent. task GUID property, however OF doesn't properly let the id be set (bug has been filed), hence we check for links instead. IDs would be quicker.
I put it to the community to please add to this, and to OmniFocus that if you want to add a proper Entourage <-> OmniFocus sync, it's all yours! (Free upgrades, maybe?)
Hope someone finds it useful! Thanks to all who've inadvertantly helped me so greatly with their code snippets from this forum!
Cheers,
David.
Code:
-- The following script is a (rough) two-way sync between Entourage and OmniFocus -- It exports all Entourage tasks to OmniFocus, by either creating OF tasks and linking the Ent. task as an attachment, -- or (if it finds a task already linked) by updating whichever task has most recently changed. -- -- Essentially, this is a one-way Entourage-To-Omnifocus export, with subsequent two-way syncs. -- -- Run it on a timed schedule from Entourage to ensure OmniFocus is always up to date. -- -- NOTE: You will have to ensure your Entourage Project names match your OF Projects, -- and your Entourage Categories match your OF Contexts, or everything will get dumped to -- whatever's set in OF's preferences as default. -- -- (c) 2009 David J. Szego - All rights waived but a little credit would be nice. Maybe eternal free upgrades to OmniFocus desktop/iPhone if they end up using this code! on run set valETaskID to null set valOFTaskID to null tell application "Microsoft Entourage" -- Get all tasks if (count of tasks) is greater than 0 then set lstAllTasks to every task -- if there are no tasks then quit if lstAllTasks is {} then return end if -- Go through all the tasks, get info, and export repeat with oTheTask in lstAllTasks -- Get the task's information set lstETaskInfo to every item of my getETaskInfo(oTheTask) --DEBUG: display dialog "Name: " & item 1 of lstETaskInfo & return & "Note: " & item 2 of lstETaskInfo & return & "ID: " & item 3 of lstETaskInfo & return & "Flag: " & item 5 of lstETaskInfo & return & "Project: " & item 6 of lstETaskInfo & return & "Context: " & item 7 of lstETaskInfo & return & "Due: " & item 8 of lstETaskInfo & return & "Start: " & item 9 of lstETaskInfo & return & "Completed: " & item10 of lstETaskInfo & return & "Last Updated: " & item 11 of lstETaskInfo -- Check if the task exists in OmniFocus set valETaskID to item 3 of lstETaskInfo set dateETaskMod to item 11 of lstETaskInfo set valOFTaskIDAndMod to my doesTaskExist(valETaskID) if valOFTaskIDAndMod is not null then -- If it exists, see which is newer set valOFTaskID to item 2 of valOFTaskIDAndMod set dateOFTaskMod to item 2 of valOFTaskIDAndMod -- If Entourage task is newer, update OF -- DEBUG: display dialog dateOFTaskMod & " (OF) is newer than " & dateETaskMod & " (E)" if dateOFTaskMod is greater than dateETaskMod then -- DEBUG: display dialog (dateOFTaskMod as string) & " (OF) is newer than " & (dateETaskMod as string) & " (E)" -- display dialog "OF is newer than E" my updateOFTask(valOFTaskID, lstETaskInfo) else -- if OF task is newer, update Entourage -- my updateETask(valETaskID, lstOFTaskInfo) end if else -- If it doesn't exist in OmniFocus, make it my makeOFTask(lstETaskInfo) end if end repeat end if end tell end run --------- on getETaskInfo(oTheTask) tell application "Microsoft Entourage" set strETaskName to name of oTheTask --set theSender to display name of sender of oTheTask set strENote to content of oTheTask set strEGUID to GUID of oTheTask as string set strEID to ID of oTheTask set boolIsCompleted to completed of oTheTask set strLastUpdate to modification date of oTheTask set valEPriority to priority of oTheTask set boolIsFlagged to false if valEPriority is high or valEPriority is highest then set boolIsFlagged to true -- Set the project and category to the last in each list (hey, it works) set strECategory to null set lstCategoryList to category of oTheTask repeat with strCategory in lstCategoryList set strECategory to name of strCategory end repeat set theProjectList to project list of oTheTask set strEProjectName to "" repeat with theProject in theProjectList if the name of theProject is not "" then set strEProjectName to name of theProject end if end repeat -- If task has a date, set it if has due date of oTheTask is true then set strDueDate to due date of oTheTask else set strDueDate to "" end if if has start date of oTheTask is true then set strStartDate to start date of oTheTask else set strStartDate to "" end if end tell set lstETaskInfo to {strETaskName, strENote, strEID, strEGUID, boolIsFlagged, strEProjectName, strECategory, strDueDate, strStartDate, boolIsCompleted, strLastUpdate} return lstETaskInfo end getETaskInfo --------- on makeOFTask(lstTaskInfo) set strETaskName to item 1 of lstTaskInfo set strENote to item 2 of lstTaskInfo set strEID to item 3 of lstTaskInfo set strEGUID to item 4 of lstTaskInfo set boolIsFlagged to item 5 of lstTaskInfo set strEProjectName to item 6 of lstTaskInfo set strECategory to item 7 of lstTaskInfo set dateETaskDueDate to item 8 of lstTaskInfo set dateETaskStartDate to item 9 of lstTaskInfo set boolIsCompleted to item 10 of lstTaskInfo set dateETaskModDate to item 11 of lstTaskInfo tell application "OmniFocus" tell default document if (strEProjectName = "") or (strEProjectName is null) then -- Let OmniFocus's preferences dictate the default list for single items set strOFProject to null else try -- Let OF default if it can't be set set strOFProject to project strEProjectName as string end try end if --DEBUG: display dialog "Making: Name: " & item 1 of lstTaskInfo & return & "Note: " & item 2 of lstTaskInfo & return & "ID: " & item 3 of lstTaskInfo & return & "Flag: " & item 5 of lstTaskInfo & return & "Project: " & item 6 of lstTaskInfo & return & "Context: " & item 7 of lstTaskInfo & return & "Due: " & item 8 of lstTaskInfo & return & "Start: " & item 9 of lstTaskInfo & return & "Last Updated: " & item 11 of lstTaskInfo -- Make the new task, and sync the id to Entourage's GUID (for later versions of OmniFocus where this isn't trampled) set oNewOFTask to make new inbox task with properties {name:strETaskName, note:strENote, completed:boolIsCompleted, id:strEGUID} -- Set the Context if (strECategory is not null) and (strECategory is not "") then try -- Let OmniFocus store it in the Inbox if there is no matching context name -- This will eventually need to walk trees for matching contexts, or parse / create etc. set context of oNewOFTask to context strECategory end try end if -- Set the Project if strOFProject is not null then set containing project of oNewOFTask to strOFProject end if -- Set the dates if dateETaskStartDate is not null and dateETaskStartDate is not "" then set start date of oNewOFTask to dateETaskStartDate end if if dateETaskDueDate is not null and dateETaskDueDate is not "" then set due date of oNewOFTask to dateETaskDueDate end if -- Sync the mod dates -- (note, this doesn't work... Talk to Michaela! -- set modification date of oNewOFTask to dateETaskModDate -- Attach the original Entourage item to the OF Task set theCommand to "mdfind com_microsoft_entourage_recordID==" & strEID try set strETaskFileName to the first item of paragraphs of (do shell script theCommand) if strETaskFileName is not null then tell the note of oNewOFTask make new file attachment with properties {file name:strETaskFileName, embedded:false} end tell end if end try compact end tell end tell end makeOFTask ---------------- on updateOFTask(valOFTaskID, lstTaskInfo) set strOFTaskName to item 1 of lstTaskInfo set strOFNote to item 2 of lstTaskInfo set strOFID to item 3 of lstTaskInfo set strEGUID to item 4 of lstTaskInfo set boolIsFlagged to item 5 of lstTaskInfo set strOFProjectName to item 6 of lstTaskInfo set strOFContext to item 7 of lstTaskInfo set dateDueDate to item 8 of lstTaskInfo set boolIsCompleted to item 9 of lstTaskInfo set dateStartDate to item 10 of lstTaskInfo --DEBUG: display dialog "Updating OF Task " & valOFTaskID & ": " & item 1 of lstTaskInfo & return & "Note: " & item 2 of lstTaskInfo & return & "ID: " & item 3 of lstTaskInfo & return & "Flag: " & item 4 of lstTaskInfo & return & "Project: " & item 5 of lstTaskInfo & return & "Context: " & item 6 of lstTaskInfo & return & "Due: " & item 7 of lstTaskInfo & return & "Start: " & item 8 of lstTaskInfo & return & "Completed: " & item 9 of lstTaskInfo tell application "OmniFocus" -- Find the task with ID valOFTaskID and change it's properties end tell end updateOFTask ----------------- on updateETask(valETaskID, lstTaskInfo) set strETaskName to item 1 of lstTaskInfo set strENote to item 2 of lstTaskInfo set strEID to item 3 of lstTaskInfo set strEGUID to item 4 of lstTaskInfo set boolIsFlagged to item 5 of lstTaskInfo set strEProjectName to item 6 of lstTaskInfo set strECategory to item 7 of lstTaskInfo set dateDueDate to item 8 of lstTaskInfo set boolIsCompleted to item 9 of lstTaskInfo set dateStartDate to item 10 of lstTaskInfo --DEBUG: display dialog "Updating OF Task " & valTaskOFID & ": " & item 1 of lstTaskInfo & return & "Note: " & item 2 of lstTaskInfo & return & "ID: " & item 3 of lstTaskInfo & return & "Flag: " & item 4 of lstTaskInfo & return & "Project: " & item 5 of lstTaskInfo & return & "Context: " & item 6 of lstTaskInfo & return & "Due: " & item 7 of lstTaskInfo & return & "Start: " & item 8 of lstTaskInfo & return & "Completed: " & item 9 of lstTaskInfo tell application "Microsoft Entourage" -- Find the task with ID valETaskID and change it's properties end tell end updateETask ----------------- on doesTaskExist(valTaskEID) set strETaskFileName to null set boolTaskFound to false set strOFTaskID to null set boolIsFileAttached to false set dateOFTaskMod to null -- Get the path of the Entourage task for attachment set theCommand to "mdfind com_microsoft_entourage_recordID==" & valTaskEID try set strETaskFileName to the first item of paragraphs of (do shell script theCommand) end try --DEBUG: display dialog "Looking for filename: " & return & strETaskFilename -- Walk the OF content tree to see if there are any OF tasks which have this Entourage task attached tell application "OmniFocus" --tell front document tell default document tell (first document window whose index is 1) -- Get the whole library set oEveryItem to descendant tree of content -- Walk the tree repeat with oCurrentItem in oEveryItem --try set oCurrentItemValue to value of oCurrentItem set clTreeClass to class of oCurrentItemValue --DEBUG: display dialog "Class of item: " & clTreeClass & " / " & class of oCurrentItem & " / " & name of oCurrentItem & return if (clTreeClass is task) or (clTreeClass is inbox task) then -- If we've got a task, then check for matching file attachments --DEBUG: display dialog "Found a task! : " & name of oCurrentItemValue set boolIsFileAttached to my findInOFFileAttachments(oCurrentItemValue, strETaskFileName) --DEBUG: display dialog "file attached to " & name of oCurrentItemValue & ": " & boolIsFileAttached if boolIsFileAttached is true then -- If Entourage task is attached, set the OF task ID for returning set strOFTaskID to id of oCurrentItemValue set dateOFTaskMod to modification date of oCurrentItemValue --DEBUG: display dialog "Task: " & name of oCurrentItem & return & " exists as task id: " & strOFTaskID end if end if --end try end repeat end tell end tell end tell if strOFTaskID is null then return null else return {strOFTaskID, dateOFTaskMod} end if end doesTaskExist ---------------- on findInOFFileAttachments(oOFTask, strETaskFileName) set boolTaskFound to false set strOFTaskID to null set lstOFFileAttachments to null using terms from application "OmniFocus" --try tell the note of oOFTask -- Get a list of the name of every file attachment to try and find the Entourage task set lstOFFileAttachments to file name of every file attachment end tell -- DEBUG: display dialog "Looking for files in " & name of oOFTask repeat with strOFFileName in lstOFFileAttachments -- DEBUG: display dialog "Files: " & strFileAttachment -- Convert the OF attachment filename to a Unix path set strOFFileName to POSIX path of strOFFileName --DEBUG: display dialog "Found a note with file: " & return & strOFFileName & return & return & "but looking for " & return & return & strETaskFileName & return & return & "in task" & return & name of oOFTask -- Compare it to what we're looking for form Entourage if strOFFileName is equal to strETaskFileName then set boolTaskFound to true -- DEBUG: display dialog "Found it!" return true end if end repeat --end try end using terms from return boolTaskFound end findInOFFileAttachments ------------ -- Allows script to be quit cleanly as when scheduled shutdown or logout occurs. on quit continue quit end quit