The Omni Group
These forums are now read-only. Please visit our new forums to participate in discussion. A new account will be required to post in the new forums. For more info on the switch, see this post. Thank you!

Go Back   The Omni Group Forums > OmniFocus > OmniFocus Extras
FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
Things to OF importer Thread Tools Search this Thread Display Modes
Hi All,
1st post here. And 1st apple script late last night... It would be awesome if someone said "Hey, your reinventing the wheel here. Just follow this link."

I was able to get my data out of Things and into a tab delimited txt file. I then used the trial version of oo3 to convert the txt to an OmniOutliner file. The resulting txt file looks like this:
"projectName" \t "nextAction" \t "@Context" \t "duration eg. 5min or 1h" \t "priority eg. High, Low" \t "hugeChunkOfNotesWith\n'sRemovedToKeepOOHappy" \n (or \r I forget which) repeat...

Here are the issues I am working through:
-The resulting OmniOutliner file looks like the txt file (of course) but with many columns (and no outlining?). Is there a preferred way to format a txt file so that OO opens it and sees an outline and not just a 2d string array?

-OF brings everything in flat and doesn't recognize the project attribute (also flat-ish in OO hmmm, pg. 50 in the OO manual talks about out-denting... is there something here I am missing?)

-My durations go straight to metadata instead of the duration field (this could be my naming convention: 5min, 15min, 30min, 1h, 2h, 1d. What naming conventions are supported/recognized?)

-The notes show up but with a "Metadata: " string prepended to them. Any way to write directly to the notes object?

-I guess "Metadata: Priority: High" is fine. What do you use to set H M L priorities in your OF setup?

I know there is a lot here. Thanks for taking time to read it all. My script code is (will be) pasted below. It began life here: http://culturedcode.com/things/wiki/..._(AppleScript). BTW they have one that does OF to Things http://culturedcode.com/things/wiki/...Omni_To_Things. I'll check that out for ideas.

---On a silly XP machine at work, I'll post the script code later---

Last edited by A to the B; 2009-12-23 at 08:23 AM.. Reason: one of the hyperlinks did not like th ")" symbol
 
Quote:
Originally Posted by A to the B View Post
Hi All,
1st post here. And 1st apple script late last night... It would be awesome if someone said "Hey, your reinventing the wheel here. Just follow this link."
Welcome! Now why would you want someone else's script when you could have the satisfaction of building your own? :)
Quote:

Here are the issues I am working through:
-The resulting OmniOutliner file looks like the txt file (of course) but with many columns (and no outlining?). Is there a preferred way to format a txt file so that OO opens it and sees an outline and not just a 2d string array?
I don't know how you could structure a text file to tell OmniOutliner to build an indented outline from it. I would probably just convert the Applescript you're using to make the text file to build the structure in OmniOutliner directly. When you have a chance to post your code, I'll have a look at it and see what I can suggest. Others with more substantial Applescript chops may chime in as well.

Quote:
-OF brings everything in flat and doesn't recognize the project attribute (also flat-ish in OO hmmm, pg. 50 in the OO manual talks about out-denting... is there something here I am missing?)
Yeah, you can select a row (or rows) in OO and indent it with cmd-] or the Reorganize->Indent command. That will establish an outline structure, and OF will honor that structure during import.

Quote:
-My durations go straight to metadata instead of the duration field (this could be my naming convention: 5min, 15min, 30min, 1h, 2h, 1d. What naming conventions are supported/recognized?)
The underlying problem seems to be that the importer is broken -- I'm not able to get it to understand start/due dates or durations. I've filed a report.
Quote:
-The notes show up but with a "Metadata: " string prepended to them. Any way to write directly to the notes object?
Yes, if you use an Applescript to do it. Given that the importer seems to have some troubles with dates and durations, if you were already going to the trouble of making an script that wrote an OmniOutliner file to be imported and cared about dates and durations, one might as well just tell OmniFocus to build the rows directly. Too busy trying to convert this to a previously solved problem to take a step back and think of that before!
Quote:
-I guess "Metadata: Priority: High" is fine. What do you use to set H M L priorities in your OF setup?
I don't. I'm not a believer in putting on priority labels. I'll flag things and use start and due dates to manage the list as needed. One thing I've suggested in the past for people who want such a thing is repurposing the Duration field as a priority field. Make 1-5m your highest priority group, 6-15m your next priority group, etc. following the steps in the duration filter. Set the duration filter to 5 min and you'll only see your highest priority items. Set it to 15 minutes and you see the top two groups. Also sort by duration and you can have various shadings in each group.
 
Quote:
Originally Posted by A to the B View Post
---On a silly XP machine at work, I'll post the script code later---
Later...

Code:
on ReplaceText(find, replace, subject)
	set prevTIDs to text item delimiters of AppleScript
	set text item delimiters of AppleScript to find
	set subject to text items of subject
	
	set text item delimiters of AppleScript to replace
	set subject to "" & subject
	set text item delimiters of AppleScript to prevTIDs
	
	return subject
end ReplaceText

--get replaceText("Windows", "the Mac OS", "I love Windows and I will always love Windows and I have always loved Windows.")


tell application "Things"
	-- Include date in the filename.  
	-- Filename will be ThingsToday.2009June5.txt
	set {year:y, month:m, day:d} to (current date)
	set fileName to "ThingsNext." & y & m & d & ".txt"
	
	-- Set the path.  You should replace 'username' with your actual 
	-- username, and change the path as you please 
	set pathName to "Macintosh HD:Users:Alan:Desktop:" & fileName
	
	set fullReport to ""
	
	-- To number the lines in the output
	set itemCount to 0
	
	repeat with aToDo in to dos of list "Next"
		set itemCount to itemCount + 1
		
		-- Create an empty list for tags and notes and well everything...
		set allTags to {}
		
		-- Get project name
		if (project of aToDo) is not missing value then
			set todoDataRow to (name of project of aToDo) & ": " & (name of aToDo) & tab
		else
			set todoDataRow to "no project" & ": " & (name of aToDo) & tab
		end if
		
		-- Get item name
		--set todoDataRow to todoDataRow & (name of aToDo) & tab
		
		-- Get all tags on the todo item
		set todoTags to tags of aToDo
		repeat with aTag in todoTags
			copy (name of aTag) to the end of allTags
		end repeat
		
		-- Get all tags on the project, if there is one
		if (project of aToDo) is not missing value then
			set projTags to tags of (project of aToDo)
			repeat with aTag in projTags
				copy (name of aTag) to the end of allTags
			end repeat
		end if
		
		-- Get all tags on the area, if there is one  --not needed for my application but you may need this
		--		if (area of aToDo) is not missing value then
		--			set areaTags to tags of (area of aToDo)
		--			repeat with aTag in areaTags
		--				copy (name of aTag) to the end of allTags
		--			end repeat
		--		end if
		
		-- Get all notes on the todo, if there is one
		if (notes of aToDo) is not missing value then
			repeat with x from ((count allTags) + 1) to 4
				copy "" to the end of allTags
			end repeat
			
			-- Replace line feeds
			set aString to ""
			copy (notes of aToDo) to aString
			copy my ReplaceText("\n", "--- CR GUID ---", aString) to aString
			copy aString to the end of allTags
		end if
		
		-- Combine the tags (and notes) into a tab-delimited list
		if allTags is not missing value then
			set AppleScript's text item delimiters to {"\t"}
			set todoDataRow to todoDataRow & ¬
				(allTags as text)
		end if
		
		set fullReport to fullReport & (todoDataRow & return as string)
	end repeat
	
	-- Get the count of inbox items
	set inboxItems to count of (to dos of list "Inbox")
	
	-- Compile the contexts and notes of the output for this run
	-- Include full date and time, and counts of items in Today and Inbox
	(*	set fullReport to (((the current date) as string) & ¬
		(tab as string) & ¬
		(tab as string) & ¬
		(itemCount as string) & " items in Today, " & ¬
		(inboxItems as string) & " items in Inbox" & ¬
		return as string) & fullReport & return as string
	*)
	-- Open and write to the ouput file
	set outputFile to open for access (pathName as string) with write permission
	write (fullReport & return as string) to outputFile starting at eof
	close access outputFile
end tell
It is pretty much a hack of some otherwise nice code written by someone else. I plan to clean up the mess I made :D and alter it to write straight to OF. I am still ramping up on apple script and the syntax...

Script question: Performance wise which is better?

A)
Tell app things to give me a big struct, all at once;
Then tell app OF to parse it and create OF rows all at once;

or B)
For (thisItem in allThingsItems)
{
Tell Things to copy anItem to thisItem;
Tell OF to set thisItem to someNewItem;
}

or C)
is this stuff doable/easier in xcode?

Thanks,
Ab
 
Thanks for the response! Hopefully I'll have some time over the break to roll up my sleeves and dive into the OF API. I agree writting straight to OF and skipping the txt is ideal.
 
there seems to be a syntax error in this line:

-- To number the lines in the output
set itemCount to 0

repeat with aToDo in to dos of list "Next"
set itemCount to itemCount + 1


Error is "Expected expression but found "to"
 
Below is code to export tasks from Things into OmniFocus. The importer grabs everything in "Next" and moves it over. It does NOT get items in "Someday" or "Scheduled" (it would be an easy change for you to make if you need it). It preserves projects and contexts (tags that look like "@_____").

This is my first real script. I hope you find it helpful.

Enjoy.
Ab

Code:
--------------------------------------------------
--------------------------------------------------
-- Import tasks from Things to OmniFocus
--------------------------------------------------
--------------------------------------------------
tell application "Things"
	
	-- Loop through ToDos	in Things
	repeat with aToDo in to dos of list "Next"
		
		-- Get title and notes of Things task
		set theTitle to name of aToDo
		set theNote to notes of aToDo
		
		-- Get project name
		if (project of aToDo) is not missing value then
			set theProjectName to (name of project of aToDo)
		else
			set theProjectName to "NoProjInThings"
		end if
		
		-- Get Contexts from tags
		-- get all tags from one ToDo item...
		set allTagNames to {}
		copy (name of tags of aToDo) to allTagNames
		-- ...and from the project...
		if (project of aToDo) is not missing value then
			copy (name of tags of project of aToDo) to the end of allTagNames
		end if
		-- ...now extract contexts from tags
		copy my FindContextName(allTagNames) to theContextName
		
		-- Create a new task in OmniFocus
		tell application "OmniFocus"
			
			tell default document
				
				-- Set (or create new) task context
				if context theContextName exists then
					set theContext to context theContextName
				else
					set theContext to make new context with properties {name:theContextName}
				end if
				
				-- Set (or create new) project
				if project theProjectName exists then
					set theProject to project theProjectName
				else
					set theProject to make new project with properties {name:theProjectName}
				end if
				
				-- Create new task
				tell theProject
					set newTask to make new task with properties {name:theTitle, note:theNote, containing project:theProject, context:theContext}
				end tell
				
			end tell -- document
		end tell -- OF application
	end repeat -- Main loop
end tell -- Things application


--------------------------------------------------
--------------------------------------------------
-- Get context from array of Things tags
--------------------------------------------------
--------------------------------------------------
on FindContextName(tagNames)
	-- Example usage
	--FindContextName("@Mac", "1/2hr", "High") -- FYI, my tags are context, duration and priority
	
	repeat with aTagName in tagNames
		if aTagName starts with "@" then
			return aTagName
		end if
	end repeat
	return ""
	
end FindContextName -- End FindContextName


--------------------------------------------------
--------------------------------------------------
-- Remove the CRs from a string,
-- not used in this script,
-- carry over from prior implementation
--------------------------------------------------
--------------------------------------------------
on ReplaceText(find, replace, subject)
	-- Example usage
	-- ReplaceText("Windows", "the Mac OS", "I love Windows and I will always love Windows and I have always loved Windows.")
	
	set prevTIDs to text item delimiters of AppleScript
	set text item delimiters of AppleScript to find
	set subject to text items of subject
	
	set text item delimiters of AppleScript to replace
	set subject to "" & subject
	set text item delimiters of AppleScript to prevTIDs
	
	return subject
	
end ReplaceText -- End replaceText()
 
Where do the actions go once the get into OF? Inbox?

Does it import the projects as well?

Darren

Last edited by darrenburgess; 2010-01-01 at 04:37 AM..
 
Quote:
Originally Posted by darrenburgess View Post
Where do the actions go once the get into OF? Inbox?

Does it import the projects as well?

Darren
Projects are imported. Nonproject actions go to the inbox.
 
Thanks A to the B for the script. I've made a small change so that Areas get import and changed into normal projects rather than all areas getting put into a single project.

Code:
--------------------------------------------------
--------------------------------------------------
-- Import tasks from Things to OmniFocus
--------------------------------------------------
--------------------------------------------------
tell application "Things"
	
	-- Loop through ToDos	in Things
	repeat with aToDo in to dos of list "Next"
		
		-- Get title and notes of Things task
		set theTitle to name of aToDo
		set theNote to notes of aToDo
		
		-- Get project name
		if (project of aToDo) is not missing value then
			set theProjectName to (name of project of aToDo)
		else if (area of aToDo) is not missing value then
			set theProjectName to (name of area of aToDo)
		else
			set theProjectName to "NoProjInThings"
		end if
		
		-- Get Contexts from tags
		-- get all tags from one ToDo item...
		set allTagNames to {}
		copy (name of tags of aToDo) to allTagNames
		-- ...and from the project...
		if (project of aToDo) is not missing value then
			copy (name of tags of project of aToDo) to the end of allTagNames
		end if
		-- ...now extract contexts from tags
		copy my FindContextName(allTagNames) to theContextName
		
		-- Create a new task in OmniFocus
		tell application "OmniFocus"
			
			tell default document
				
				-- Set (or create new) task context
				if context theContextName exists then
					set theContext to context theContextName
				else
					set theContext to make new context with properties {name:theContextName}
				end if
				
				-- Set (or create new) project
				if project theProjectName exists then
					set theProject to project theProjectName
				else
					set theProject to make new project with properties {name:theProjectName}
				end if
				
				-- Create new task
				tell theProject
					set newTask to make new task with properties {name:theTitle, note:theNote, containing project:theProject, context:theContext}
				end tell
				
			end tell -- document
		end tell -- OF application
	end repeat -- Main loop
end tell -- Things application


--------------------------------------------------
--------------------------------------------------
-- Get context from array of Things tags
--------------------------------------------------
--------------------------------------------------
on FindContextName(tagNames)
	-- Example usage
	--FindContextName("@Mac", "1/2hr", "High") -- FYI, my tags are context, duration and priority
	
	repeat with aTagName in tagNames
		if aTagName starts with "@" then
			return aTagName
		end if
	end repeat
	return ""
	
end FindContextName -- End FindContextName


--------------------------------------------------
--------------------------------------------------
-- Remove the CRs from a string,
-- not used in this script,
-- carry over from prior implementation
--------------------------------------------------
--------------------------------------------------
on ReplaceText(find, replace, subject)
	-- Example usage
	-- ReplaceText("Windows", "the Mac OS", "I love Windows and I will always love Windows and I have always loved Windows.")
	
	set prevTIDs to text item delimiters of AppleScript
	set text item delimiters of AppleScript to find
	set subject to text items of subject
	
	set text item delimiters of AppleScript to replace
	set subject to "" & subject
	set text item delimiters of AppleScript to prevTIDs
	
	return subject
	
end ReplaceText -- End replaceText()
 
I am ready to come back to Omni Focus from Things.

Please tell me how to use this script.
I don't have a clue.

Thank you in advance for any instructions you can provide.

Kim
 
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
I Really Messed Things Up [Support Ninjas helped fix things, tho. :-)] jpkeppel OmniFocus 1 for Mac 2 2011-05-10 10:26 AM
AS - importer for xmind - in progress johnjj OmniFocus Extras 20 2010-08-25 10:28 PM
AS - importer for MLO (mylifeorganized) johnjj OmniFocus Extras 7 2009-12-24 08:24 AM
Birthday Importer JoaoPinheiro OmniFocus Extras 3 2008-11-13 10:30 AM
Life Balance Importer sprugman OmniFocus Extras 11 2008-01-08 08:04 PM


All times are GMT -8. The time now is 09:11 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.