Importing OmniFocus Projects

Simply copy the following script(s) into a new "Script Editor" document and press run.
Feel free to customize them for your use cases.

Note: We do not take responsibility for any data loss incurred by running these scripts.
Make sure to back up your data (e.g. by copying the directories mentioned here to a different location) before running these scripts.

Importing the Complete Project Hierarchy

-- Copyright (c) 2017 timingapp.com / Daniel Alm. All rights reserved.
-- This script is licensed only to extend the functionality of Timing. Redistribution and any other uses are not allowed without prior permission from us.

-- Set this to false if you'd also like to include e.g. completed projects.
property activeProjectsOnly : true

set alertResult to display alert "Please back up your data!" message "Before proceeding, please make sure to back up your Timing database.\n\nSee https://timingapp.com/help/faq#data on which folders you need to back up." buttons {"Cancel", "I Have A Backup"}
if button returned of alertResult is "Cancel" then
	error number -128
end if

on getOrCreateProject(projectName, parentProject)
	if projectName = "" then
		return missing value
	end if
	
	tell application "TimingHelper"
		if parentProject is missing value then
			set results to (projects whose name is projectName)
			if results = {} then
				return (create project name projectName)
			else
				return (first item of results)
			end if
		else
			set results to (projects of parentProject whose name is projectName)
			if results = {} then
				return (create project name projectName parent project parentProject)
			else
				return (first item of results)
			end if
		end if
	end tell
end getOrCreateProject

on importFolders(omniFocusFolders, timingParentProject)
	repeat with omniFocusFolder in omniFocusFolders
		set shouldAddFolder to false
		tell application "OmniFocus"
			set folderName to name of omniFocusFolder
			set childSections to sections of omniFocusFolder
			set childFolders to folders of omniFocusFolder
			
			if activeProjectsOnly then
				repeat with subProject in flattened projects of omniFocusFolder
					if status of subProject is active then
						set shouldAddFolder to true
						exit repeat
					end if
				end repeat
			else
				set shouldAddFolder to true
			end if
		end tell
		
		if shouldAddFolder then
			set timingProject to getOrCreateProject(folderName, timingParentProject)
			importProjects(childSections, timingProject)
			importFolders(childFolders, timingProject)
		end if
	end repeat
end importFolders

on importProjects(omniFocusProjects, timingParentProject)
	repeat with omniFocusProject in omniFocusProjects
		set shouldAddProject to false
		tell application "OmniFocus"
			set projectName to name of omniFocusProject
			if activeProjectsOnly then
				if class of omniFocusProject is folder then
					repeat with subProject in flattened projects of omniFocusProject
						if status of subProject is active then
							set shouldAddProject to true
							exit repeat
						end if
					end repeat
				else
					set shouldAddProject to ((status of omniFocusProject) is active)
				end if
			else
				set shouldAddProject to true
			end if
		end tell
		if shouldAddProject then
			getOrCreateProject(projectName, timingParentProject)
		end if
	end repeat
end importProjects

tell application "OmniFocus"
	set rootSections to sections of front document
	set rootFolders to folders of front document
end tell

importProjects(rootSections, missing value)
importFolders(rootFolders, missing value)

Importing All Selected Projects And Folders (Without Hierarchy)

-- Copyright (c) 2017 timingapp.com / Daniel Alm. All rights reserved.
-- This script is licensed only to extend the functionality of Timing. Redistribution and any other uses are not allowed without prior permission from us.

set alertResult to display alert "Please back up your data!" message "Before proceeding, please make sure to back up your Timing database.\n\nSee https://timingapp.com/help/faq#data on which folders you need to back up." buttons {"Cancel", "I Have A Backup"}
if button returned of alertResult is "Cancel" then
	error number -128
end if

on getOrCreateProject(projectName, parentProject)
	if projectName = "" then
		return missing value
	end if
	
	tell application "TimingHelper"
		if parentProject is missing value then
			set results to (projects whose name is projectName)
			if results = {} then
				return (create project name projectName)
			else
				return (first item of results)
			end if
		else
			set results to (projects of parentProject whose name is projectName)
			if results = {} then
				return (create project name projectName parent project parentProject)
			else
				return (first item of results)
			end if
		end if
	end tell
end getOrCreateProject

set projectNames to {}
tell application "OmniFocus"
	set theDoc to front document
	set allTreeProperties to properties of value of every selected tree of sidebar of front document window of theDoc
	repeat with treeProperties in allTreeProperties
		copy name of treeProperties to the end of projectNames
	end repeat
end tell

repeat with projectName in projectNames
	getOrCreateProject(projectName, missing value)
end repeat