UPDATE:
I managed to upload the script by changing the extension to .doc. Here you can download the OmniFocusToThings script, but you need to rename it to .applescript or copy it into the apple script editor.
UPDATE: there is a new version of this script from robotii, see comments for the link.
I decided to give cultured code things another try after Jyri reported he is pretty happy with things. I tried a couple month ago, at this time I liked the simple interface but it had not the features I was looking for. Things got better but I still missing a good mail app integration. Omnifocus for example allows you to select what ever text, you press a hot key and vola you have a new task in the inbox.
Anyhow my biggest problem was to migrate my hounders of task from omni focus to things, so I glued two apple scripts together and improved them up until I had what I was looking for. Thanks to Karels MailToThings script and Robinfrancistrew OF2TaskpaperMail script.
Consider the script alpha, and make sure you update omni focus and things before you try it! Please give me feedback and fix the bugs! 🙂
How to:
1.) Copy the text into a new script document (script editor)
2.) open things and omni focus
3.) switch into a project view of omni focus and select all task you want to import into things.
4.) Start the script and get a beer, the script is super slow since i need ti use key events to communicate with things.
5.) Clean up the import. The script tries to import all OF meta data as tags, this might be a little messy since also due date etc are used as tags. Feel free to change it in a way it makes sense to you.
-- -------------------------------------
-- the general run method
-- -------------------------------------
on run
display dialog "Should we start? Make sure you have all task in Omni Focus marked you want to import into Thing" buttons {"OK", "Cancel"} default button 1
tell application "OmniFocus"
tell default document
if number of document window is 0 then
make new document window with properties {bounds:{0, 0, 1000, 500}}
end if
end tell
tell document window 1 of front document
set lstTrees to selected trees of content
if (count of lstTrees) = 0 then
try
display dialog "Nothing selected in the right-hand panel." & return & return & "Select material to export, and try again." & return
end try
else
-- Generate a TaskPaper string of the selected content
set blnContext to (selected view mode identifier is not equal to "project")
set lngIndent to 0
my ExportTrees(lstTrees, lngIndent, blnContext)
end if
end tell
end tell
end run
-- -------------------------------------
-- Walks the omni focus tree
-- -------------------------------------
on ExportTrees(lstTrees, lngIndent, blnContextView)
-- if the tree is a task give full detail
-- else just name and any note
-- set strTP to ""
using terms from application "OmniFocus"
repeat with oTree in lstTrees
-- intialize task string
set strTP to ""
set notes to ""
set tags to ""
set oValue to value of oTree
try
set strName to name of oValue
on error
set strName to "Inbox"
end try
if length of strName > 0 then
set strName to my Esc(strName)
end if
if strName ≠ "Inbox" then
set strNote to note of oValue
if length of strNote > 0 then
set strNote to my Esc(strNote)
end if
end if
set clValue to class of oValue
if (clValue is not equal to task) and (clValue is not equal to inbox task) then
-- Project or Folder
if clValue is not equal to folder then
if clValue is not equal to project then
--Inbox (No details)
set strTP to strTP & "Inbox:" & return
else
-- Project (Name and possibly note)
if length of strName > 0 then
set strTP to strTP & strName & ":" & return
if length of strNote > 0 then
set notes to strNote & return
end if
end if
end if
else
-- Folder (Just name - no note)
set strTP to strTP & strName & ":" & return
end if
else -- Task (with details from specified columns)
-- set recFields to {fldName:name of oValue, fldNote:note of oValue, fldDone:completed of oValue, fldContext:strContext, fldStartDate:start date of oValue, flddueDate:due date of oValue, fldDoneDate:completion date of oValue, fldDuration:estimated minutes of oValue, fldFlagged:flagged of oValue}
-- write first line of task, followed by tags
set lstLines to paragraphs of strName
set strTP to strTP & item 1 of lstLines
-- Add any tags
set oContext to context of oValue
if oContext is not equal to missing value then
set tags to " @" & name of oContext & ","
end if
set dteStart to start date of oValue
if dteStart is not equal to missing value then
set tags to tags & " @start(" & my DateString(dteStart) & ")" & ","
end if
set dteDue to due date of oValue
if dteDue is not equal to missing value then
set tags to tags & " @due(" & my DateString(dteDue) & ")" & ","
end if
set lngDurn to estimated minutes of oValue
if lngDurn is not equal to missing value then
set tags to tags & " @mins(" & (lngDurn as string) & ")" & ","
end if
if flagged of oValue then
set tags to tags & " @flag" & ","
end if
if completed of oValue then
set tags to tags & " @done" & ","
end if
-- project if we know
set aProject to containing project of oValue
if aProject is not equal to missing value then
set tags to tags & " @" & name of aProject & ","
end if
set strTP to strTP & return
-- write any remaining lines of task as note text
if length of lstLines > 1 then
repeat with strLine in rest of lstLines
set strLine to my RTrim(strLine)
if length of strLine > 0 then
-- change any trailling : to :-, to avoid misinterpretation as a header
if last character of strLine ≠ ":" then
set notes to notes & strLine & return
else
set notes to notes & strLine & "-" & return
end if
end if
end repeat
end if
-- append any attached note text
set lstLines to paragraphs of strNote
repeat with strLine in lstLines
set strLine to my RTrim(strLine)
if length of strLine > 0 then
-- change any trailling : to :-
if last character of strLine ≠ ":" then
set notes to notes & strLine & return
else
set notes to notes & strLine & "-" & return
end if
end if
end repeat
end if
-- if the current node has sub-trees then recurse
set lstSubTrees to trees of oTree
if (count of lstSubTrees) > 0 then
if (clValue ≠ project) and (clValue ≠ item) then
set lngNewIndent to lngIndent + 1
else
set lngNewIndent to lngIndent
end if
set strTP to strTP & ExportTrees(lstSubTrees, lngNewIndent, blnContextView)
end if
-- my log_event(my Esc(strTP))
my createThingTask(my Esc(strTP), my Esc(notes), tags)
end repeat
end using terms from
end ExportTrees
-- -------------------------------------
-- trims a text
-- -------------------------------------
on RTrim(someText)
local someText
repeat until someText does not end with return
if length of someText > 1 then
set someText to text 1 thru -2 of someText
else
set someText to ""
end if
end repeat
return someText
end RTrim
-- -------------------------------------
-- converts dates into a string
-- -------------------------------------
on DateString(dte)
-- yyyy-mm-dd hh:mm
set strDate to ""
if dte is not equal to missing value then
set lngMonth to month of dte as integer
set strMonth to lngMonth as string
if lngMonth < 10 then set strMonth to "0" & strMonth
set lngDay to day of dte as integer
set strDay to lngDay as string
if lngDay 0) or (lngmins > 0) then
set strHrs to lngHrs as string
if lngHrs < 10 then set strHrs to "0" & strHrs
set strMins to lngmins as string
if lngmins 1 then
set strNew to item 1 of lstParts
repeat with n from 2 to lngParts
set strNew to strNew & replace & item n of lstParts
end repeat
set text item delimiters to strOldDelim
return strNew
else
set text item delimiters to strOldDelim
return str
end if
end EscAmpersand
-- -------------------------------------
-- A simple logging mechanism
-- -------------------------------------
on log_event(theMessage)
set theLine to (do shell script ¬
"date +'%Y-%m-%d %H:%M:%S'" as string) ¬
& " " & theMessage
do shell script "echo " & "\"" & theLine & "\"" & ¬
" >> /import-events.log"
end log_event
-- -------------------------------------
-- import the task into things, we have to use key events
-- and the clipboard since things do not have apple script support yet
-- -------------------------------------
on createThingTask(subject, notes, tags)
activate application "Things"
-- jump to inbox
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \"0\" using {option down, command down}"
my doWithTimeout(uiScript, timeoutSeconds)
-- create new task
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \"n\" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
-- set subject
set the clipboard to subject
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \"v\" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
-- jump to tags
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \" \""
my doWithTimeout(uiScript, timeoutSeconds)
set the clipboard to tags
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \"v\" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
-- jump to notes
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \" \""
my doWithTimeout(uiScript, timeoutSeconds)
set the clipboard to notes
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \"v\" using command down"
my doWithTimeout(uiScript, timeoutSeconds)
delay 1
set timeoutSeconds to 1.0
set uiScript to "keystroke \" \""
my doWithTimeout(uiScript, timeoutSeconds)
end createThingTask
-- -------------------------------------
-- DO SOMETHING WITH A TIMEOUT
-- -------------------------------------
on doWithTimeout(uiScript, timeoutSeconds)
set endDate to (current date) + timeoutSeconds
repeat
try
run script "tell application \"System Events\"
" & uiScript & "
end tell"
exit repeat
on error errorMessage
if ((current date) > endDate) then
error "Can not " & uiScript
end if
end try
end repeat
end doWithTimeout
23 comments
Comments feed for this article
October 3, 2008 at 12:45 pm
Jason
Can you repost this as straight plaintext (or link to the text).
I can’t cut-and-paste from Safari to Script Editor. There are all kinds
of special character errors (e.g., quote marks).
Thanks for writing this!
October 12, 2008 at 3:38 pm
Katie
Hi. I’d love to use this, but when I put it in Script Editor, it keeps giving me syntax errors (it didn’t like the dashes at the beginning of the first comment, and then it didn’t like the quotation marks). Help?
October 12, 2008 at 11:08 pm
joa23
Hi Katie,
I just sent you the script file.
@All, please just let me know and I will send you the file or tell me how to post test files on wordpress. 😮
October 22, 2008 at 10:08 am
mark Hibdon
Can you please email me the script? Thanks so much in advance for putting one together.
October 22, 2008 at 10:17 am
joa23
Hi Christophe,
I even used it with OF 1.5 snapshot.
November 12, 2008 at 1:02 pm
Ryan
Christophe,
Thanks for putting this together. Can you email me or post the script file?
Thanks,
Ryan
November 19, 2008 at 12:41 am
Renault
Hi, can you send me your script? Thanks
November 20, 2008 at 12:12 pm
jon a.
can you e-mail me the script? Thanks!
November 26, 2008 at 12:02 pm
PaulKrone
Would you please e-mail me the script? Thanks!
December 10, 2008 at 1:09 am
Jose L Sebastian L
Hi, can you send me your script?
I have the same problems with syntax
Thanks
December 15, 2008 at 5:45 am
Olivier D.
Would you email me the script, please ?
Thanx for your work.
December 24, 2008 at 3:50 pm
Jon S
I’d love a copy too (I get the quote and — errors when run). Can you email me it? Thanks!
January 6, 2009 at 4:04 pm
Anders
Hi,
Could you also e-mail me your script. It seems really useful.
Thanks from Denmark
Anders
January 8, 2009 at 2:03 pm
robotii
Could you email me a copy of the script. I knocked up my own version, but yours seems more feature complete. I would like to merge the due date support I have in my version to yours, if that’s ok. I will send you back a copy once its done (and post it on my blog – with a link back to this post of course)
January 9, 2009 at 6:17 am
fridoruth
Hi, thanks for posting this. Please email me the current version of your script. Thanks a million.
January 10, 2009 at 3:33 pm
travisll
Can you send me a copy please?
January 10, 2009 at 4:45 pm
Gary
OK, looks like I would like a copy too. I tried to edit the script, but lost my way in DateString where lstParts is referenced but not set (and also apparently referred to as lngParts in the “repeat”).
Thank you very much for this. I have a lot of info in OmniFocus, but it looks like Things will work better with the projects I need to track.
January 12, 2009 at 8:49 am
Jim
Hello,
I’d like to try your script – could you email it to me? Thanks for your efforts!
January 15, 2009 at 12:06 pm
Robotii » Blog Archive » Migrate Omnifocus to Things Applescript
[…] This is the original page here. […]
January 15, 2009 at 12:10 pm
robotii
I updated the script to add due dates to it. Please feel free to update it and use as you please. It can be found at http://www.robotii.co.uk/archives/2009/01/15/migrate-omnifocus-to-things-applescript/
June 1, 2009 at 5:31 am
Emily H
I’d be interested to know what features of Things made you think of ditching Omnifocus… I’ve been a big fan of Omnifocus for a year or so now, but to be honest I hadn’t compared it to anything else. I’ve recently found out a little more about some functionality Things offers that Omnifocus doesn’t, like the This Week filter and Ongoing projects. This is making me consider Things, but if Things still doesn’t integrate with Mail.app like you describe with the shortcut -which I think must be the keystone to Omnifocus’s success in helping me GTD- then I don’t think I could consider making the switch. Since you’ve tried both extensively now (i’m presuming) I’d be well interested in a blog where you compare the two.
Cheers!
June 2, 2009 at 10:34 am
joa23
I like it since it has less feature. 🙂
Latest version has apple script support so things like email integration should be available soon, but I think I just saw this such an apple script.
August 27, 2012 at 4:37 am
arjanzuidhof
OK, this is an old topic, hopefully you can (still) help out: for a client of mine I tried to run the updated script (comment Jan 15, 2009) on Mac OS X Mountain Lion and recent versions of OF/Things. After fixing a couple things related to mime-type of the page I got stuck on variable definitions. E.g. strNote yielded an error. Is there a short instruction to make it work correctly?
Any help would be really appreciated!