Skip to content

Instantly share code, notes, and snippets.

@mremond
Forked from matellis/things3-to-of3.applescript
Created September 19, 2018 09:37
Show Gist options
  • Save mremond/0ab75c30b3cb57a9ae76d4a347c9bbf7 to your computer and use it in GitHub Desktop.
Save mremond/0ab75c30b3cb57a9ae76d4a347c9bbf7 to your computer and use it in GitHub Desktop.

Revisions

  1. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -200,14 +200,14 @@ tell application "Things3"

    -- Combine all the folders you want to search here
    -- Options are: Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects, Logbook, Trash
    set theTodos to to dos of list "Inbox" & to dos of list "Today" & to dos of list "Anytime" & to dos of list "Upcoming" & to dos of list "Someday" & to dos of list "Lonely Projects" & to dos of list "Logbook"
    set theTodos to to dos of list "Inbox" & to dos of list "Anytime" & to dos of list "Upcoming" & to dos of list "Someday" & to dos of list "Lonely Projects" & to dos of list "Logbook"

    -- Go through all the tasks in the combined lists
    log "Processing " & (count of theTodos) & " entries"
    repeat with aTodo in theTodos
    -- Get various attributes of Things task
    set theTitle to name of aTodo
    set theNote to notes of aTodo
    set theNote to notes of aTodo
    set theDueDate to due date of aTodo
    set theStartDate to activation date of aTodo -- aka "Defer Date"
    set theFlagStatus to false
  2. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 2 additions and 24 deletions.
    26 changes: 2 additions & 24 deletions things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -205,34 +205,12 @@ tell application "Things3"
    -- Go through all the tasks in the combined lists
    log "Processing " & (count of theTodos) & " entries"
    repeat with aTodo in theTodos

    -- Get title and notes of Things task
    -- Get various attributes of Things task
    set theTitle to name of aTodo
    set theNote to notes of aTodo

    -- ON DUE AND DEFER DATES - PLEASE READ
    -- T3 has a 'Due Date' (deadline) and an 'Activation Date' (next review). These are not directly comparable to OF3 which has a next review date by project and no 'deadline' date
    -- If we map these fields directly then everything you marked to do TODAY in T3 will disappear tomorrow as the 'Defer Date' will be in the past
    -- I didn't use the Due Date much in T3 so I've decided to put Activation Date (T3) into Due Date (OF3) and then flag a task if there was a completion date

    -- This is the straightforward way to convert, I don't like it
    set theNote to notes of aTodo
    set theDueDate to due date of aTodo
    set theStartDate to activation date of aTodo -- aka "Defer Date"
    set theFlagStatus to false
    set theDeadlineDate to missing value
    -- End of simple translation

    -- My alternate translation which I think is more practical even if not directly true
    -- If you want it the other way just comment out these three lines
    set theStartDate to missing value
    set theDueDate to activation date of aTodo
    set theFlagStatus to not (due date of aTodo is missing value)
    if theFlagStatus then ¬
    set theNote to "We flagged this item because it originally had a deadline in Things 3 of " & (due date of aTodo) & return & return & theNote
    set theDeadlineDate to due date of aTodo
    -- End of alternate translation

    -- Other fields
    set theStatus to status of aTodo as string
    set theCompletionDate to completion date of aTodo
    set theCreationDate to creation date of aTodo
  3. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -201,7 +201,6 @@ tell application "Things3"
    -- Combine all the folders you want to search here
    -- Options are: Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects, Logbook, Trash
    set theTodos to to dos of list "Inbox" & to dos of list "Today" & to dos of list "Anytime" & to dos of list "Upcoming" & to dos of list "Someday" & to dos of list "Lonely Projects" & to dos of list "Logbook"
    set theTodos to to do "Review of AirBnb"

    -- Go through all the tasks in the combined lists
    log "Processing " & (count of theTodos) & " entries"
  4. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 129 additions and 143 deletions.
    272 changes: 129 additions & 143 deletions things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -47,123 +47,134 @@ if answer is "How do I reset Omnifocus?" then
    return
    end if
    tell application "Things3"
    if 1 = 2 then
    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    --
    -- Get tags from T3
    set tagList to {}
    repeat with aTag in every tag
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag as string} to end of tagList
    else
    copy {name of parent tag of aTag as string, name of aTag as string} to end of tagList
    end if
    end repeat

    -- Put tags into OF3
    tell application "OmniFocus"
    tell default document
    -- we do this twice, once with first level and then again with second level
    -- this is the only way to preserve order
    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    --
    -- Get tags from T3
    set tagList to {}
    repeat with aTag in every tag
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag as string} to end of tagList
    else
    copy {name of parent tag of aTag as string, name of aTag as string} to end of tagList
    end if
    end repeat

    -- Put tags into OF3
    tell application "OmniFocus"
    tell default document
    -- we do this twice, once with first level and then again with second level
    -- this is the only way to preserve order

    -- first pass - parents only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    -- first pass - parents only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is null then
    if not (tag theChildTag exists) then
    make new tag with properties {name:theChildTag}
    end if
    end if
    end repeat
    if theParentTag is null then
    if not (tag theChildTag exists) then ¬
    make new tag with properties {name:theChildTag}
    end if
    end repeat

    -- second pass - children only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    -- second pass - children only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is not null then
    set parentTag to tag theParentTag
    if not (my isTagInList(name of every tag of parentTag, theChildTag)) then
    set childTag to make new tag with properties {name:theChildTag}
    move childTag to (end of tags of (first tag whose name is theParentTag))
    end if
    if theParentTag is not null then
    set parentTag to tag theParentTag
    if not (my isTagInList(name of every tag of parentTag, theChildTag)) then
    set childTag to make new tag with properties {name:theChildTag}
    move childTag to (end of tags of (first tag whose name is theParentTag))
    end if
    end repeat
    end tell
    end tell -- End of Tag Import
    end if
    end repeat
    end tell
    end tell -- End of Tag Import

    --
    -- Import T3 Areas as Folders into OF3
    --
    -- Get areas from T3
    set folderList to name of every area
    log "Processing " & (count of folderList) & " folders"

    -- Put areas into OF3
    tell application "OmniFocus"
    tell default document
    repeat with aFolder in folderList
    if not (folder aFolder exists) then
    make new folder with properties {name:aFolder}
    end if
    end repeat
    end tell
    end tell -- End of Folder Import
    --
    -- Import Projects into OF3
    --
    set projectList to {{missing value, noProjectTitle, "", "active", "", {}}}
    set completedProjectList to {}
    set AppleScript's text item delimiters to ","
    repeat with aProject in every project
    set areaName to null
    if area of aProject is missing value then
    set areaName to missing value
    else
    set areaName to name of area of aProject as string
    end if
    set projectName to name of aProject as string
    set projectNotes to notes of aProject as string
    -- set tagList to every text item of (tag names of aProject as string)
    set tagList to my gatherTagsOf(aProject)

    --
    -- Import T3 Areas as Folders into OF3
    --
    -- Get areas from T3
    set folderList to name of every area
    log "Processing " & (count of folderList) & " folders"
    set projectCompletionDate to completion date of aProject

    -- Put areas into OF3
    tell application "OmniFocus"
    tell default document
    repeat with aFolder in folderList
    if not (folder aFolder exists) then
    make new folder with properties {name:aFolder}
    end if
    end repeat
    end tell
    end tell -- End of Folder Import
    end if
    if 1 = 2 then
    --
    -- Import Projects into OF3
    --
    set projectList to {{missing value, noProjectTitle, "", "active", "", {}}}
    set completedProjectList to {}
    set AppleScript's text item delimiters to ","
    repeat with aProject in every project
    set areaName to null
    if area of aProject is missing value then
    set areaName to missing value
    else
    set areaName to name of area of aProject as string
    end if
    set projectName to name of aProject as string
    set projectNotes to notes of aProject as string
    -- set tagList to every text item of (tag names of aProject as string)
    set tagList to my gatherTagsOf(aProject)

    set projectCompletionDate to completion date of aProject

    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    set projectStatus to status of aProject as string

    copy {areaName, projectName, projectNotes, projectStatus, projectCompletionDate, tagList} to end of projectList
    end repeat
    log "Processing " & (count of projectList) & " projects"
    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    set projectStatus to status of aProject as string

    tell application "OmniFocus"
    tell default document
    repeat with aProject in projectList
    set theFolderName to first item in aProject
    set theProjectName to second item in aProject
    set theProjectNotes to third item in aProject
    set theProjectStatus to fourth item in aProject
    set theProjectTags to sixth item in aProject
    set theProjectCompletionDate to fifth item in aProject

    if theProjectStatus is "completed" then
    set theProjectStatus to done
    else if theProjectStatus is "canceled" then
    set theProjectStatus to dropped
    else if theProjectStatus is "open" then
    set theProjectStatus to active
    copy {areaName, projectName, projectNotes, projectStatus, projectCompletionDate, tagList} to end of projectList
    end repeat
    log "Processing " & (count of projectList) & " projects"

    tell application "OmniFocus"
    tell default document
    repeat with aProject in projectList
    set theFolderName to first item in aProject
    set theProjectName to second item in aProject
    set theProjectNotes to third item in aProject
    set theProjectStatus to fourth item in aProject
    set theProjectTags to sixth item in aProject
    set theProjectCompletionDate to fifth item in aProject

    if theProjectStatus is "completed" then
    set theProjectStatus to done
    else if theProjectStatus is "canceled" then
    set theProjectStatus to dropped
    else if theProjectStatus is "open" then
    set theProjectStatus to active
    end if

    if theFolderName is missing value then
    -- no area
    if (project theProjectName exists) then
    set theProject to project theProjectName
    else
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    if theFolderName is missing value then
    -- no area
    if (project theProjectName exists) then
    if theProjectStatus is done then
    if not (my isItemInList(completedProjectList, theProject)) then
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    end if
    else
    -- Project inside an area
    tell folder theFolderName
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    -- add tags
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    @@ -172,32 +183,17 @@ tell application "Things3"
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    end if
    else
    -- Project inside an area
    tell folder theFolderName
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    -- add tags
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    if theProjectStatus is done then
    if not (my isItemInList(completedProjectList, theProject)) then
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    end if

    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    -- Write out tags
    my writeTagsTo(theProject, theProjectTags)
    end repeat
    end tell

    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    -- Write out tags
    my writeTagsTo(theProject, theProjectTags)
    end repeat
    end tell
    end if
    end tell

    --
    -- Import T3 To Dos into OF3
    --
    @@ -232,9 +228,8 @@ tell application "Things3"
    set theStartDate to missing value
    set theDueDate to activation date of aTodo
    set theFlagStatus to not (due date of aTodo is missing value)
    if theFlagStatus then
    if theFlagStatus then ¬
    set theNote to "We flagged this item because it originally had a deadline in Things 3 of " & (due date of aTodo) & return & return & theNote
    end if
    set theDeadlineDate to due date of aTodo
    -- End of alternate translation

    @@ -328,9 +323,7 @@ tell application "Things3"
    set completedProject to first item of completedProjectInfo
    set completedProjectDate to second item of completedProjectInfo
    mark complete completedProject
    -- if not (completedProjectDate is missing value) then
    set completion date of completedProject to completedProjectDate
    -- end if
    end repeat
    end tell
    end tell
    @@ -340,7 +333,6 @@ end tell -- Things application
    on isItemInList(theList, theItem)
    set the matchFlag to false
    repeat with anItem from 1 to the count of theList
    -- if id of item anItem of theList is id of theItem then ¬
    if theList contains anItem then ¬
    set the matchFlag to true
    end repeat
    @@ -359,10 +351,6 @@ end isTagInList
    on isInInbox(anItem)
    return ((area of anItem is missing value) and (project of anItem is missing value))
    end isInInbox
    -- is it a project?
    on isProject(anItem)
    return ((project of anItem is missing value) and not (area of anItem is missing value))
    end isProject
    -- gather tags
    on gatherTagsOf(aTodo)
    set allTagNames to {}
    @@ -394,9 +382,7 @@ on writeTagsTo(aTask, tagList)
    set childTag to (first tag of tag theParentTag whose name is theChildTag)
    add childTag to tags of aTask
    end if

    end repeat -- tags

    end tell
    end tell
    end writeTagsTo
  5. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 155 additions and 149 deletions.
    304 changes: 155 additions & 149 deletions things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -47,139 +47,123 @@ if answer is "How do I reset Omnifocus?" then
    return
    end if
    tell application "Things3"
    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    --
    -- Get tags from T3
    set tagList to {}
    repeat with aTag in every tag
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag as string} to end of tagList
    else
    copy {name of parent tag of aTag as string, name of aTag as string} to end of tagList
    end if
    end repeat

    -- Put tags into OF3
    tell application "OmniFocus"
    tell default document
    -- we do this twice, once with first level and then again with second level
    -- this is the only way to preserve order

    -- first pass - parents only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag
    if 1 = 2 then
    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    --
    -- Get tags from T3
    set tagList to {}
    repeat with aTag in every tag
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag as string} to end of tagList
    else
    copy {name of parent tag of aTag as string, name of aTag as string} to end of tagList
    end if
    end repeat

    -- Put tags into OF3
    tell application "OmniFocus"
    tell default document
    -- we do this twice, once with first level and then again with second level
    -- this is the only way to preserve order

    if theParentTag is null then
    if not (tag theChildTag exists) then
    make new tag with properties {name:theChildTag}
    -- first pass - parents only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is null then
    if not (tag theChildTag exists) then
    make new tag with properties {name:theChildTag}
    end if
    end if
    end if
    end repeat

    -- second pass - children only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag
    end repeat

    if theParentTag is not null then
    set parentTag to tag theParentTag
    if not (my isTagInList(name of every tag of parentTag, theChildTag)) then
    set childTag to make new tag with properties {name:theChildTag}
    move childTag to (end of tags of (first tag whose name is theParentTag))
    -- second pass - children only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is not null then
    set parentTag to tag theParentTag
    if not (my isTagInList(name of every tag of parentTag, theChildTag)) then
    set childTag to make new tag with properties {name:theChildTag}
    move childTag to (end of tags of (first tag whose name is theParentTag))
    end if
    end if
    end if
    end repeat
    end tell
    end tell -- End of Tag Import

    --
    -- Import T3 Areas as Folders into OF3
    --
    -- Get areas from T3
    set folderList to name of every area
    log "Processing " & (count of folderList) & " folders"

    -- Put areas into OF3
    tell application "OmniFocus"
    tell default document
    repeat with aFolder in folderList
    if not (folder aFolder exists) then
    make new folder with properties {name:aFolder}
    end if
    end repeat
    end tell
    end tell -- End of Folder Import
    -- Combine all the folders you want to search here
    -- Options are: Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects, Logbook, Trash
    set theTodos to to dos of list "Inbox" & to dos of list "Today" & to dos of list "Anytime" & to dos of list "Upcoming" & to dos of list "Someday" & to dos of list "Lonely Projects" & to dos of list "Logbook"

    --
    -- Import Projects into OF3
    --
    set projectList to {{missing value, noProjectTitle, "", "active", "", {}}}
    set completedProjectList to {}
    set AppleScript's text item delimiters to ","
    repeat with aProject in every project
    set areaName to null
    if area of aProject is missing value then
    set areaName to missing value
    else
    set areaName to name of area of aProject as string
    end if
    set projectName to name of aProject as string
    set projectNotes to notes of aProject as string
    -- set tagList to every text item of (tag names of aProject as string)
    set tagList to my gatherTagsOf(aProject)
    end repeat
    end tell
    end tell -- End of Tag Import

    set projectCompletionDate to completion date of aProject
    --
    -- Import T3 Areas as Folders into OF3
    --
    -- Get areas from T3
    set folderList to name of every area
    log "Processing " & (count of folderList) & " folders"

    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    set projectStatus to status of aProject as string

    copy {areaName, projectName, projectNotes, projectStatus, projectCompletionDate, tagList} to end of projectList
    end repeat
    log "Processing " & (count of projectList) & " projects"

    tell application "OmniFocus"
    tell default document
    repeat with aProject in projectList
    set theFolderName to first item in aProject
    set theProjectName to second item in aProject
    set theProjectNotes to third item in aProject
    set theProjectStatus to fourth item in aProject
    set theProjectTags to sixth item in aProject
    set theProjectCompletionDate to fifth item in aProject

    if theProjectStatus is "completed" then
    set theProjectStatus to done
    else if theProjectStatus is "canceled" then
    set theProjectStatus to dropped
    else if theProjectStatus is "open" then
    set theProjectStatus to active
    end if

    if theFolderName is missing value then
    -- no area
    if (project theProjectName exists) then
    set theProject to project theProjectName
    else
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    -- Put areas into OF3
    tell application "OmniFocus"
    tell default document
    repeat with aFolder in folderList
    if not (folder aFolder exists) then
    make new folder with properties {name:aFolder}
    end if
    end repeat
    end tell
    end tell -- End of Folder Import
    end if
    if 1 = 2 then
    --
    -- Import Projects into OF3
    --
    set projectList to {{missing value, noProjectTitle, "", "active", "", {}}}
    set completedProjectList to {}
    set AppleScript's text item delimiters to ","
    repeat with aProject in every project
    set areaName to null
    if area of aProject is missing value then
    set areaName to missing value
    else
    set areaName to name of area of aProject as string
    end if
    set projectName to name of aProject as string
    set projectNotes to notes of aProject as string
    -- set tagList to every text item of (tag names of aProject as string)
    set tagList to my gatherTagsOf(aProject)

    set projectCompletionDate to completion date of aProject

    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    set projectStatus to status of aProject as string

    copy {areaName, projectName, projectNotes, projectStatus, projectCompletionDate, tagList} to end of projectList
    end repeat
    log "Processing " & (count of projectList) & " projects"

    tell application "OmniFocus"
    tell default document
    repeat with aProject in projectList
    set theFolderName to first item in aProject
    set theProjectName to second item in aProject
    set theProjectNotes to third item in aProject
    set theProjectStatus to fourth item in aProject
    set theProjectTags to sixth item in aProject
    set theProjectCompletionDate to fifth item in aProject

    if theProjectStatus is done then
    if not (my isItemInList(completedProjectList, theProject)) then
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    if theProjectStatus is "completed" then
    set theProjectStatus to done
    else if theProjectStatus is "canceled" then
    set theProjectStatus to dropped
    else if theProjectStatus is "open" then
    set theProjectStatus to active
    end if
    else
    -- Project inside an area
    tell folder theFolderName
    if project theProjectName exists then
    if theFolderName is missing value then
    -- no area
    if (project theProjectName exists) then
    set theProject to project theProjectName
    else
    -- add tags
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    @@ -188,19 +172,41 @@ tell application "Things3"
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    end if

    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    -- Write out tags
    my writeTagsTo(theProject, theProjectTags)
    end repeat
    else
    -- Project inside an area
    tell folder theFolderName
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    -- add tags
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    if theProjectStatus is done then
    if not (my isItemInList(completedProjectList, theProject)) then
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    end if

    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    -- Write out tags
    my writeTagsTo(theProject, theProjectTags)
    end repeat
    end tell
    end tell
    end tell
    end if
    --
    -- Import T3 To Dos into OF3
    --

    -- Combine all the folders you want to search here
    -- Options are: Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects, Logbook, Trash
    set theTodos to to dos of list "Inbox" & to dos of list "Today" & to dos of list "Anytime" & to dos of list "Upcoming" & to dos of list "Someday" & to dos of list "Lonely Projects" & to dos of list "Logbook"
    set theTodos to to do "Review of AirBnb"

    -- Go through all the tasks in the combined lists
    log "Processing " & (count of theTodos) & " entries"
    repeat with aTodo in theTodos
    @@ -292,24 +298,24 @@ tell application "Things3"
    end tell
    end tell
    end if


    -- handle completed
    if theStatus is "completed" then
    mark complete newTask
    set completion date of newTask to theCompletionDate
    else if theStatus is "canceled" then
    mark complete newTask
    set status of newTask to dropped
    set completion date of newTask to theCompletionDate
    else if theStatus is "open" then
    mark incomplete newTask
    set completion date of newTask to missing value
    end if

    -- Process tags
    my writeTagsTo(newTask, allTagNames)
    end if

    -- handle completed
    if theStatus is "completed" then
    mark complete newTask
    set completion date of newTask to theCompletionDate
    else if theStatus is "canceled" then
    mark complete newTask
    set status of newTask to dropped
    set completion date of newTask to theCompletionDate
    else if theStatus is "open" then
    mark incomplete newTask
    set completion date of newTask to missing value
    end if

    -- Process tags
    my writeTagsTo(newTask, allTagNames)

    end if -- not a task
    end tell -- OF application
    end tell -- Document
    @@ -393,4 +399,4 @@ on writeTagsTo(aTask, tagList)

    end tell
    end tell
    end writeTagsTo
    end writeTagsTo
  6. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 24 additions and 14 deletions.
    38 changes: 24 additions & 14 deletions things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -17,30 +17,35 @@
    -- Contact for a task (no OF3 equivalent)
    -- Modification date from Things (it's a read only attribute in OF3)

    -- TODOs
    -- Project tags

    --
    -- Title of project for stuff in things with no project (avoids going into the Inbox)
    --
    property noProjectTitle : "No Project In Things"

    set answer to the button returned of ¬
    (display dialog ¬
    (display alert ¬
    ¬
    "This script will import from Things 3 to Omnifocus 3.
    The script does not yet import sub-tasks, recurrences or project tags.
    "Things 3 to Omnifocus 3 Importer" & return & return & "PLEASE READ BEFORE PROCEEDING" message ¬
    "The script does not yet import sub-tasks or recurrences.
    >> 'Some Day' tasks that are assigned to a project will not be imported. <<
    Omnifocus does not support tag short cuts, cancellation dates or contact info for a task,
    and does not permit the importation of modification date.
    TAKE BACKUPS!
    Empty your trash on Things 3
    Reset your database on OmniFocus 3
    1. TAKE BACKUPS!
    2. Empty your trash on Things 3.
    3. Reset your database on OmniFocus 3 & delete default tags.
    4. Run Clean Up when done on OmniFocus to remove logged tasks.
    5. Setup sync after import has completed.
    Then press 'I Understand' to get going.
    Importation will take a while, about an hour for a 3,000 task database (including logged entries)." buttons {" I Understand ", " Cancel "} default button 2)
    if answer is " Cancel " then return

    Importation will take a while, about 3,000 tasks per hour.
    " buttons {"How do I reset Omnifocus?", "I Understand", " Cancel "} default button 3)
    if answer is " Cancel " then return
    if answer is "How do I reset Omnifocus?" then
    display dialog "Make sure you take backups of your Omnifocus database if you've used it before. Resetting will delete even the backups unless they are copied elsewhere!" with icon stop
    open location "https://support.omnigroup.com/omnifocus-reset-database/"
    return
    end if
    tell application "Things3"
    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    @@ -125,7 +130,9 @@ tell application "Things3"
    end if
    set projectName to name of aProject as string
    set projectNotes to notes of aProject as string
    set tagList to every text item of (tag names of aProject as string)
    -- set tagList to every text item of (tag names of aProject as string)
    set tagList to my gatherTagsOf(aProject)

    set projectCompletionDate to completion date of aProject

    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    @@ -185,6 +192,9 @@ tell application "Things3"
    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    -- Write out tags
    my writeTagsTo(theProject, theProjectTags)
    end repeat
    end tell
    end tell
  7. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 26 additions and 13 deletions.
    39 changes: 26 additions & 13 deletions things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -18,9 +18,29 @@
    -- Modification date from Things (it's a read only attribute in OF3)

    -- TODOs
    -- Intro dialog
    -- Properties for settings
    -- Project tags

    -- Title of project for stuff in things with no project (avoids going into the Inbox)
    property noProjectTitle : "No Project In Things"

    set answer to the button returned of ¬
    (display dialog ¬
    ¬
    "This script will import from Things 3 to Omnifocus 3.
    The script does not yet import sub-tasks, recurrences or project tags.
    >> 'Some Day' tasks that are assigned to a project will not be imported. <<
    Omnifocus does not support tag short cuts, cancellation dates or contact info for a task,
    and does not permit the importation of modification date.
    TAKE BACKUPS!
    Empty your trash on Things 3
    Reset your database on OmniFocus 3
    Then press 'I Understand' to get going.
    Importation will take a while, about an hour for a 3,000 task database (including logged entries)." buttons {" I Understand ", " Cancel "} default button 2)
    if answer is " Cancel " then return

    tell application "Things3"
    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    @@ -69,11 +89,9 @@ tell application "Things3"
    end tell
    end tell -- End of Tag Import


    --
    -- Import T3 Areas as Folders into OF3
    --

    -- Get areas from T3
    set folderList to name of every area
    log "Processing " & (count of folderList) & " folders"
    @@ -95,7 +113,7 @@ tell application "Things3"
    --
    -- Import Projects into OF3
    --
    set projectList to {{missing value, "No Project in Things", "", "active", "", {}}, {missing value, "Today (Imported)", "", "active", "", {}}}
    set projectList to {{missing value, noProjectTitle, "", "active", "", {}}}
    set completedProjectList to {}
    set AppleScript's text item delimiters to ","
    repeat with aProject in every project
    @@ -225,7 +243,7 @@ tell application "Things3"
    set isInbox to true
    else if (project of aTodo) is missing value then
    -- Just an orphaned task, no such thing in OF3 so put in a folder
    set theProjectName to "No Project in Things"
    set theProjectName to noProjectTitle
    else
    -- Regular task inside a project
    set theProjectName to (name of project of aTodo)
    @@ -245,7 +263,7 @@ tell application "Things3"
    -- Create a new task in OmniFocus
    tell application "OmniFocus"
    tell default document
    if not isProject then
    if not isProject then
    -- Create the actual task - does not de-dupe
    -- Do it differently if inbox
    if isInbox then
    @@ -256,11 +274,6 @@ tell application "Things3"
    tell project theProjectName
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus}
    end tell
    else
    tell project "Today (Imported)"
    -- put these in an orphaned project & add project name to the notes
    set newTask to (make new task with properties {name:theTitle, note:"This was originally in project " & theProjectName & return & theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus})
    end tell
    end if
    else
    tell folder theFolderName
    @@ -291,7 +304,7 @@ tell application "Things3"
    end tell -- OF application
    end tell -- Document
    end repeat -- Things list

    -- Mark complete any projects that should be that way
    tell application "OmniFocus"
    tell default document
  8. @matellis matellis renamed this gist Sep 16, 2018. 1 changed file with 2 additions and 46 deletions.
    48 changes: 2 additions & 46 deletions things-to-of.applescript → things3-to-of3.applescript
    Original file line number Diff line number Diff line change
    @@ -21,8 +21,6 @@
    -- Intro dialog
    -- Properties for settings
    -- Project tags
    -- Inbox is losing projects
    -- Deal with projects inside areas -- currently a lot of tasks are getting setup outside
    tell application "Things3"
    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    @@ -131,7 +129,6 @@ tell application "Things3"

    if theProjectStatus is "completed" then
    set theProjectStatus to done
    log "marked as done"
    else if theProjectStatus is "canceled" then
    set theProjectStatus to dropped
    else if theProjectStatus is "open" then
    @@ -223,8 +220,6 @@ tell application "Things3"
    if class of aTodo is project then
    -- Is this task actually a project?
    set isProject to true
    set theFolderName to missing value
    set theProjectName to (name of aTodo)
    else if ((area of aTodo is missing value) and (project of aTodo is missing value)) then
    -- Is this todo in the Inbox? If so, it needs special treatment
    set isInbox to true
    @@ -250,40 +245,7 @@ tell application "Things3"
    -- Create a new task in OmniFocus
    tell application "OmniFocus"
    tell default document

    if isProject then
    if 1 = 2 then
    -- We have to do this differently if project is in an area or at the root
    -- Root level project
    if theFolderName is missing value then
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    else
    -- Project inside an area
    set theFolder to folder theFolderName
    tell theFolder
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    if theStatus is "complete" then
    copy theProject to end of completedProjectList
    end if

    -- TODO: Add project tags here
    end if
    else

    if not isProject then
    -- Create the actual task - does not de-dupe
    -- Do it differently if inbox
    if isInbox then
    @@ -313,16 +275,13 @@ tell application "Things3"
    if theStatus is "completed" then
    mark complete newTask
    set completion date of newTask to theCompletionDate
    log "marked as done"
    else if theStatus is "canceled" then
    mark complete newTask
    set status of newTask to dropped
    set completion date of newTask to theCompletionDate
    log "marked as canceled"
    else if theStatus is "open" then
    mark incomplete newTask
    set completion date of newTask to missing value
    log "marked as active"
    end if

    -- Process tags
    @@ -332,8 +291,7 @@ tell application "Things3"
    end tell -- OF application
    end tell -- Document
    end repeat -- Things list



    -- Mark complete any projects that should be that way
    tell application "OmniFocus"
    tell default document
    @@ -347,7 +305,6 @@ tell application "Things3"
    end repeat
    end tell
    end tell
    log (count of completedProjectList)
    end tell -- Things application

    -- Clumsy way of seeing if an item is in the Inbox as Things doesn't expose a "list" property
    @@ -371,7 +328,6 @@ on isTagInList(theList, theItem)
    end isTagInList
    -- less clumsy inbox hack
    on isInInbox(anItem)
    log (get properties of anItem)
    return ((area of anItem is missing value) and (project of anItem is missing value))
    end isInInbox
    -- is it a project?
  9. @matellis matellis revised this gist Sep 16, 2018. 1 changed file with 149 additions and 126 deletions.
    275 changes: 149 additions & 126 deletions things-to-of.applescript
    Original file line number Diff line number Diff line change
    @@ -9,21 +9,24 @@
    -- Empty your Things Trash first.
    --
    -- Does not support:
    -- Scheduled tasks
    -- Tags belonging to a project
    -- Recurring tasks
    -- Sub-tasks
    -- Someday tasks (can't get them from T3)
    -- Someday tasks (can't get them from T3 unless they are not in a project)
    -- Tag short cuts (not an OF3 feature)
    -- Cancellation date (no OF3 equivalent)
    -- Contact for a task (no OF3 equivalent)
    -- Modification date from Things (it's a read only attribute in OF3)
    -- Does not import projects with no tasks (can't get them from T3)

    -- TODOs
    -- Intro dialog
    -- Properties for settings
    -- Project tags
    -- Inbox is losing projects
    -- Deal with projects inside areas -- currently a lot of tasks are getting setup outside
    tell application "Things3"

    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    --

    -- Get tags from T3
    set tagList to {}
    repeat with aTag in every tag
    @@ -33,7 +36,6 @@ tell application "Things3"
    copy {name of parent tag of aTag as string, name of aTag as string} to end of tagList
    end if
    end repeat
    log "Processing " & (count of tagList) & " tags"

    -- Put tags into OF3
    tell application "OmniFocus"
    @@ -48,7 +50,6 @@ tell application "Things3"

    if theParentTag is null then
    if not (tag theChildTag exists) then
    log "Creating parent tag " & theChildTag
    make new tag with properties {name:theChildTag}
    end if
    end if
    @@ -63,7 +64,6 @@ tell application "Things3"
    set parentTag to tag theParentTag
    if not (my isTagInList(name of every tag of parentTag, theChildTag)) then
    set childTag to make new tag with properties {name:theChildTag}
    log "Move child tag " & theChildTag & " to parenttag " & theParentTag
    move childTag to (end of tags of (first tag whose name is theParentTag))
    end if
    end if
    @@ -90,35 +90,32 @@ tell application "Things3"
    end repeat
    end tell
    end tell -- End of Folder Import


    -- Combine all the folders you want to search here
    -- Options are: Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects, Logbook, Trash
    set theTodos to to dos of list "Inbox" & to dos of list "Today" & to dos of list "Anytime" & to dos of list "Upcoming" & to dos of list "Someday" & to dos of list "Lonely Projects" & to dos of list "Logbook"
    -- set theTodos to to dos of list "Logbook"

    --
    -- Import Projects into OF3
    --
    set projectList to {{null, "No Project in Things", "", "active", "", {}}, {null, "Today (Imported)", "", "active", "", {}}}
    set projectList to {{missing value, "No Project in Things", "", "active", "", {}}, {missing value, "Today (Imported)", "", "active", "", {}}}
    set completedProjectList to {}
    set AppleScript's text item delimiters to ","
    repeat with aTodo in theTodos
    if class of aTodo is project then
    set areaName to null
    if not (area of aTodo is missing value) then
    set areaName to name of area of aTodo as string
    end if
    set projectName to name of aTodo as string
    set projectNotes to notes of aTodo as string
    set tagList to every text item of (tag names of aTodo as string)
    set projectCompletionDate to null

    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    set projectStatus to status of aTodo as string
    log "T3 projectStatus " & projectStatus

    copy {areaName, projectName, projectNotes, projectStatus, projectCompletionDate, tagList} to end of projectList
    repeat with aProject in every project
    set areaName to null
    if area of aProject is missing value then
    set areaName to missing value
    else
    set areaName to name of area of aProject as string
    end if
    set projectName to name of aProject as string
    set projectNotes to notes of aProject as string
    set tagList to every text item of (tag names of aProject as string)
    set projectCompletionDate to completion date of aProject

    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    set projectStatus to status of aProject as string

    copy {areaName, projectName, projectNotes, projectStatus, projectCompletionDate, tagList} to end of projectList
    end repeat
    log "Processing " & (count of projectList) & " projects"

    @@ -129,8 +126,9 @@ tell application "Things3"
    set theProjectName to second item in aProject
    set theProjectNotes to third item in aProject
    set theProjectStatus to fourth item in aProject
    set theProjectTags to sixth item in aProject
    set theProjectCompletionDate to fifth item in aProject

    log "projectStatus----: " & theProjectStatus
    if theProjectStatus is "completed" then
    set theProjectStatus to done
    log "marked as done"
    @@ -140,41 +138,33 @@ tell application "Things3"
    set theProjectStatus to active
    end if

    log theProjectStatus

    set theProjectCompletionDate to fifth item in aProject
    set theProjectTags to sixth item in aProject

    if theFolderName is null then
    if theFolderName is missing value then
    -- no area
    if (project theProjectName exists) then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    if theProjectStatus is done then
    if not (completedProjectList contains theProject) then
    copy theProject to end of completedProjectList
    if not (my isItemInList(completedProjectList, theProject)) then
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    -- Todo: Add completed date
    log "mark complete " & name of theProject
    end if
    else
    -- Project inside an area
    tell folder theFolderName
    if not (project theProjectName exists) then
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    -- add tags
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    if theProjectStatus is done then
    if not (completedProjectList contains theProject) then
    copy theProject to end of completedProjectList
    if not (my isItemInList(completedProjectList, theProject)) then
    copy {theProject, theProjectCompletionDate} to end of completedProjectList
    end if
    -- Todo: Add completed date
    log "mark complete " & name of theProject
    end if

    end tell
    @@ -183,7 +173,6 @@ tell application "Things3"
    end repeat
    end tell
    end tell

    --
    -- Import T3 To Dos into OF3
    --
    @@ -224,156 +213,153 @@ tell application "Things3"
    set theCreationDate to creation date of aTodo

    -- Get project & area names
    set theFolderName to ""
    set theFolderName to missing value
    set theProjectNote to ""
    set theProjectName to ""
    set processItemFlag to true
    set isInbox to false
    set isProject to false

    log (get class of aTodo)

    if class of aTodo is project then
    -- Is this task actually a project?
    set isProject to true
    set theFolderName to ""
    set theFolderName to missing value
    set theProjectName to (name of aTodo)
    log "--> " & theProjectName
    else if ((area of aTodo is missing value) and (project of aTodo is missing value)) then
    -- Is this todo in the Inbox? If so, it needs special treatment
    set isInbox to true
    log "..inbox"
    else if (project of aTodo) is missing value then
    -- Just an orphaned task, no such thing in OF3 so put in a folder
    set theProjectName to "No Project in Things"
    log "..no project"
    else
    -- Regular task inside a project
    set theProjectName to (name of project of aTodo)
    set theProjectNote to (notes of project of aTodo)

    -- With a folder
    if not (area of project of aTodo) is missing value then
    if area of project of aTodo is missing value then
    set theFolderName to missing value
    else
    set theFolderName to (name of area of project of aTodo)
    end if
    log "..task"
    -- log "Area: " & area of project of aTodo as string
    log "Project: " & name of project of aTodo as string
    end if

    -- Gather tags
    set allTagNames to {}
    repeat with aTag in every tag of aTodo
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag} to end of allTagNames
    else
    copy {name of parent tag of aTag, name of aTag} to end of allTagNames
    end if
    end repeat
    set allTagNames to my gatherTagsOf(aTodo)

    -- Create a new task in OmniFocus
    tell application "OmniFocus"
    tell default document

    if isProject then
    -- We have to do this differently if project is in an area or at the root
    -- Root level project
    if theFolderName = "" then
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    else
    -- Project inside an area
    set theFolder to folder theFolderName
    tell theFolder
    if 1 = 2 then
    -- We have to do this differently if project is in an area or at the root
    -- Root level project
    if theFolderName is missing value then
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    if theStatus is "complete" then
    copy theProject to end of completedProjectList
    else
    -- Project inside an area
    set theFolder to folder theFolderName
    tell theFolder
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    if theStatus is "complete" then
    copy theProject to end of completedProjectList
    end if

    -- TODO: Add project tags here
    end if

    -- TODO: Add project tags here

    else

    -- Create the actual task - does not de-dupe
    -- Do it differently if inbox
    if isInbox then
    set newTask to make new inbox task with properties {name:theTitle, note:theNote, creation date:theCreationDate}
    set newTask to make new inbox task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus}
    else
    if project theProjectName exists then
    tell project theProjectName
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus}
    end tell
    if theFolderName is missing value then
    if project theProjectName exists then
    tell project theProjectName
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus}
    end tell
    else
    tell project "Today (Imported)"
    -- put these in an orphaned project & add project name to the notes
    set newTask to (make new task with properties {name:theTitle, note:"This was originally in project " & theProjectName & return & theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus})
    end tell
    end if
    else
    tell project "Today (Imported)"
    -- put these in an orphaned project & add project name to the notes
    set newTask to (make new task with properties {name:theTitle, note:"This was originally in project " & theProjectName & return & theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus})
    tell folder theFolderName
    tell project theProjectName
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus}
    end tell
    end tell
    end if
    end if

    -- handle completed
    if theStatus is "completed" then
    mark complete newTask
    set completion date of newTask to theCompletionDate
    end if

    -- Process tags
    -- Fiddly, because they're hierarchal
    repeat with aTag in allTagNames

    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is null then
    -- No Parent tag
    add tag theChildTag to tags of newTask
    else
    -- Has a parent tag
    set parentTag to tag theParentTag
    set childTag to (first tag of parentTag whose name is theChildTag)
    add childTag to tags of newTask
    -- handle completed
    if theStatus is "completed" then
    mark complete newTask
    set completion date of newTask to theCompletionDate
    log "marked as done"
    else if theStatus is "canceled" then
    mark complete newTask
    set status of newTask to dropped
    set completion date of newTask to theCompletionDate
    log "marked as canceled"
    else if theStatus is "open" then
    mark incomplete newTask
    set completion date of newTask to missing value
    log "marked as active"
    end if

    end repeat -- tags
    -- Process tags
    my writeTagsTo(newTask, allTagNames)
    end if
    end if -- not a task
    end tell -- OF application
    end tell -- Document
    end repeat -- Things list


    -- Mark complete any projects that should be that way
    tell application "OmniFocus"
    tell default document
    repeat with completedProject in completedProjectList
    repeat with completedProjectInfo in completedProjectList
    set completedProject to first item of completedProjectInfo
    set completedProjectDate to second item of completedProjectInfo
    mark complete completedProject
    -- to do add Completed Date
    -- if not (completedProjectDate is missing value) then
    set completion date of completedProject to completedProjectDate
    -- end if
    end repeat
    end tell
    end tell
    log (count of completedProjectList)
    end tell -- Things application

    -- Clumsy way of seeing if an item is in the Inbox as Things doesn't expose a "list" property
    on isiteminlist(theList, theItem)
    on isItemInList(theList, theItem)
    set the matchFlag to false
    repeat with anItem from 1 to the count of theList
    if id of item anItem of theList is id of theItem then ¬
    -- if id of item anItem of theList is id of theItem then ¬
    if theList contains anItem then ¬
    set the matchFlag to true
    end repeat
    return the matchFlag
    end isiteminlist
    end isItemInList
    -- Another hack for heirarchal tags to say "does tag exist inside this other tag?"
    on isTagInList(theList, theItem)
    set the matchFlag to false
    @@ -391,4 +377,41 @@ end isInInbox
    -- is it a project?
    on isProject(anItem)
    return ((project of anItem is missing value) and not (area of anItem is missing value))
    end isProject
    end isProject
    -- gather tags
    on gatherTagsOf(aTodo)
    set allTagNames to {}
    tell application "Things3"
    repeat with aTag in every tag of aTodo
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag} to end of allTagNames
    else
    copy {name of parent tag of aTag, name of aTag} to end of allTagNames
    end if
    end repeat
    end tell
    return allTagNames
    end gatherTagsOf
    -- write tags
    on writeTagsTo(aTask, tagList)
    tell application "OmniFocus"
    tell default document
    repeat with aTag in tagList

    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is null then
    -- No Parent tag
    add tag theChildTag to tags of aTask
    else
    -- Has a parent tag
    set childTag to (first tag of tag theParentTag whose name is theChildTag)
    add childTag to tags of aTask
    end if

    end repeat -- tags

    end tell
    end tell
    end writeTagsTo
  10. @matellis matellis revised this gist Sep 14, 2018. 1 changed file with 215 additions and 56 deletions.
    271 changes: 215 additions & 56 deletions things-to-of.applescript
    Original file line number Diff line number Diff line change
    @@ -8,27 +8,34 @@
    -- Added: OF3 & Things 3 compatibility; task order; areas/folders; tags
    -- Empty your Things Trash first.
    --
    -- Does not yet support:
    -- Does not support:
    -- Scheduled tasks
    -- Someday tasks
    -- Tags belonging to a project
    -- Sub-tasks
    -- Someday tasks (can't get them from T3)
    -- Tag short cuts (not an OF3 feature)
    -- Cancellation date (no OF3 equivalent)
    -- Status of a task (no OF3 equivalent)
    -- Contact for a task (no OF3 equivalent)
    -- Modification date from Things (it's a read only attribute in OF3)

    -- Does not import projects with no tasks (can't get them from T3)
    tell application "Things3"
    -- Setup hierarchal tags, in correct order and without duplicates

    --
    -- Import T3 hierarchal tags into OF3 in correct order and without duplicates
    --

    -- Get tags from T3
    set tagList to {}
    repeat with aTag in every tag
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag} to end of tagList
    copy {null, name of aTag as string} to end of tagList
    else
    copy {name of parent tag of aTag, name of aTag} to end of tagList
    copy {name of parent tag of aTag as string, name of aTag as string} to end of tagList
    end if
    end repeat
    log "Processing " & (count of tagList) & " tags"

    -- Put tags into OF3
    tell application "OmniFocus"
    tell default document
    -- we do this twice, once with first level and then again with second level
    @@ -41,6 +48,7 @@ tell application "Things3"

    if theParentTag is null then
    if not (tag theChildTag exists) then
    log "Creating parent tag " & theChildTag
    make new tag with properties {name:theChildTag}
    end if
    end if
    @@ -53,7 +61,6 @@ tell application "Things3"

    if theParentTag is not null then
    set parentTag to tag theParentTag

    if not (my isTagInList(name of every tag of parentTag, theChildTag)) then
    set childTag to make new tag with properties {name:theChildTag}
    log "Move child tag " & theChildTag & " to parenttag " & theParentTag
    @@ -62,28 +69,126 @@ tell application "Things3"
    end if
    end repeat
    end tell
    end tell
    end tell -- End of Tag Import

    -- Setup T3 Sections as Folders in OF3
    set theFolders to name of every area

    --
    -- Import T3 Areas as Folders into OF3
    --

    -- Get areas from T3
    set folderList to name of every area
    log "Processing " & (count of folderList) & " folders"

    -- Put areas into OF3
    tell application "OmniFocus"
    tell default document
    repeat with aFolder in theFolders
    repeat with aFolder in folderList
    if not (folder aFolder exists) then
    make new folder with properties {name:aFolder}
    end if
    end repeat
    end tell
    end tell
    end tell -- End of Folder Import

    -- Used to see if an item is in the inbox or not
    set theInboxList to to dos of list "Inbox"

    -- Combine all the folders you want to search here
    -- Options are Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects
    set theTodos to to dos of list "Inbox" & to dos of list "Anytime" & to dos of list "Someday"
    -- Options are: Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects, Logbook, Trash
    set theTodos to to dos of list "Inbox" & to dos of list "Today" & to dos of list "Anytime" & to dos of list "Upcoming" & to dos of list "Someday" & to dos of list "Lonely Projects" & to dos of list "Logbook"
    -- set theTodos to to dos of list "Logbook"
    --
    -- Import Projects into OF3
    --
    set projectList to {{null, "No Project in Things", "", "active", "", {}}, {null, "Today (Imported)", "", "active", "", {}}}
    set completedProjectList to {}
    set AppleScript's text item delimiters to ","
    repeat with aTodo in theTodos
    if class of aTodo is project then
    set areaName to null
    if not (area of aTodo is missing value) then
    set areaName to name of area of aTodo as string
    end if
    set projectName to name of aTodo as string
    set projectNotes to notes of aTodo as string
    set tagList to every text item of (tag names of aTodo as string)
    set projectCompletionDate to null

    -- status: active/‌on hold/‌done/‌dropped. vs open completed canceled
    set projectStatus to status of aTodo as string
    log "T3 projectStatus " & projectStatus

    copy {areaName, projectName, projectNotes, projectStatus, projectCompletionDate, tagList} to end of projectList
    end if
    end repeat
    log "Processing " & (count of projectList) & " projects"

    tell application "OmniFocus"
    tell default document
    repeat with aProject in projectList
    set theFolderName to first item in aProject
    set theProjectName to second item in aProject
    set theProjectNotes to third item in aProject
    set theProjectStatus to fourth item in aProject

    log "projectStatus----: " & theProjectStatus
    if theProjectStatus is "completed" then
    set theProjectStatus to done
    log "marked as done"
    else if theProjectStatus is "canceled" then
    set theProjectStatus to dropped
    else if theProjectStatus is "open" then
    set theProjectStatus to active
    end if

    log theProjectStatus

    set theProjectCompletionDate to fifth item in aProject
    set theProjectTags to sixth item in aProject

    if theFolderName is null then
    -- no area
    if (project theProjectName exists) then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    if theProjectStatus is done then
    if not (completedProjectList contains theProject) then
    copy theProject to end of completedProjectList
    end if
    -- Todo: Add completed date
    log "mark complete " & name of theProject
    end if
    else
    -- Project inside an area
    tell folder theFolderName
    if not (project theProjectName exists) then
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNotes}
    end if

    if theProjectStatus is done then
    if not (completedProjectList contains theProject) then
    copy theProject to end of completedProjectList
    end if
    -- Todo: Add completed date
    log "mark complete " & name of theProject
    end if

    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if
    end repeat
    end tell
    end tell

    --
    -- Import T3 To Dos into OF3
    --
    -- Go through all the tasks in the combined lists
    log "Processing " & (count of theTodos) & " entries"
    repeat with aTodo in theTodos

    -- Get title and notes of Things task
    @@ -113,6 +218,8 @@ tell application "Things3"
    set theDeadlineDate to due date of aTodo
    -- End of alternate translation

    -- Other fields
    set theStatus to status of aTodo as string
    set theCompletionDate to completion date of aTodo
    set theCreationDate to creation date of aTodo

    @@ -121,28 +228,41 @@ tell application "Things3"
    set theProjectNote to ""
    set theProjectName to ""
    set processItemFlag to true
    set isInbox to false
    set isProject to false

    if my isItemInList(theInboxList, aTodo) then
    log (get class of aTodo)

    if class of aTodo is project then
    -- Is this task actually a project?
    set isProject to true
    set theFolderName to ""
    set theProjectName to (name of aTodo)
    log "--> " & theProjectName
    else if ((area of aTodo is missing value) and (project of aTodo is missing value)) then
    -- Is this todo in the Inbox? If so, it needs special treatment
    set theProjectName to "Inbox"
    else if (project of aTodo) is missing value and not (area of aTodo) is missing value then
    -- Is this task actually a project? Projects seem to turn up as tasks for some reason, we infer this when a task has no project but it does have an area
    set processItemFlag to false
    set theFolderName to (name of area of aTodo)
    set isInbox to true
    log "..inbox"
    else if (project of aTodo) is missing value then
    -- Just an orphaned task
    -- Just an orphaned task, no such thing in OF3 so put in a folder
    set theProjectName to "No Project in Things"
    log "..no project"
    else
    -- Regular task inside a project
    set theProjectName to (name of project of aTodo)
    set theProjectNote to (notes of project of aTodo)

    -- With a folder
    if not (area of project of aTodo) is missing value then
    set theFolderName to (name of area of project of aTodo)
    end if
    log "..task"
    -- log "Area: " & area of project of aTodo as string
    log "Project: " & name of project of aTodo as string
    end if

    -- get all tags from todo item
    -- Gather tags
    set allTagNames to {}
    -- copy (name of tags of aTodo) to allTagNames
    repeat with aTag in every tag of aTodo
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag} to end of allTagNames
    @@ -151,51 +271,69 @@ tell application "Things3"
    end if
    end repeat


    -- Create a new task in OmniFocus
    tell application "OmniFocus"
    tell default document
    if processItemFlag then
    -- Set (or create new) project
    -- Do nothing if this is an inbox task as they don't have projects
    if not (theProjectName is "Inbox") then
    -- We have to do this differently if an area exists
    if theFolderName = "" then

    if isProject then
    -- We have to do this differently if project is in an area or at the root
    -- Root level project
    if theFolderName = "" then
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    else
    -- Project inside an area
    set theFolder to folder theFolderName
    tell theFolder
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if

    else
    -- if we want this to be within an area for some reason we have to do it within a tell block for the area
    set theFolder to folder theFolderName
    tell theFolder
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if
    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if

    if theStatus is "complete" then
    copy theProject to end of completedProjectList
    end if

    -- TODO: Add project tags here

    else

    -- Create the actual task - does not de-dupe
    -- Do it differently if inbox
    if theProjectName is "Inbox" then
    if isInbox then
    set newTask to make new inbox task with properties {name:theTitle, note:theNote, creation date:theCreationDate}
    else
    tell theProject
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, completion date:theCompletionDate, flagged:theFlagStatus}
    end tell
    if project theProjectName exists then
    tell project theProjectName
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus}
    end tell
    else
    tell project "Today (Imported)"
    -- put these in an orphaned project & add project name to the notes
    set newTask to (make new task with properties {name:theTitle, note:"This was originally in project " & theProjectName & return & theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, flagged:theFlagStatus})
    end tell
    end if
    end if

    -- handle completed
    if theStatus is "completed" then
    mark complete newTask
    set completion date of newTask to theCompletionDate
    end if

    -- Process tags
    -- Fiddly, because they're hierarchal
    repeat with aTag in allTagNames

    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    @@ -208,22 +346,34 @@ tell application "Things3"
    set childTag to (first tag of parentTag whose name is theChildTag)
    add childTag to tags of newTask
    end if

    end repeat -- tags
    end if -- not a task
    end tell -- document
    end tell -- OF application
    end tell -- OF application
    end tell -- Document
    end repeat -- Things list

    -- Mark complete any projects that should be that way
    tell application "OmniFocus"
    tell default document
    repeat with completedProject in completedProjectList
    mark complete completedProject
    -- to do add Completed Date
    end repeat
    end tell
    end tell
    log (count of completedProjectList)
    end tell -- Things application

    -- Clumsy way of seeing if an item is in the Inbox as Things doesn't expose a "list" property
    on isItemInList(theList, theItem)
    on isiteminlist(theList, theItem)
    set the matchFlag to false
    repeat with anItem from 1 to the count of theList
    if id of item anItem of theList is id of theItem then ¬
    set the matchFlag to true
    end repeat
    return the matchFlag
    end isItemInList
    end isiteminlist
    -- Another hack for heirarchal tags to say "does tag exist inside this other tag?"
    on isTagInList(theList, theItem)
    set the matchFlag to false
    @@ -233,3 +383,12 @@ on isTagInList(theList, theItem)
    end repeat
    return the matchFlag
    end isTagInList
    -- less clumsy inbox hack
    on isInInbox(anItem)
    log (get properties of anItem)
    return ((area of anItem is missing value) and (project of anItem is missing value))
    end isInInbox
    -- is it a project?
    on isProject(anItem)
    return ((project of anItem is missing value) and not (area of anItem is missing value))
    end isProject
  11. @matellis matellis revised this gist Sep 10, 2018. 1 changed file with 87 additions and 24 deletions.
    111 changes: 87 additions & 24 deletions things-to-of.applescript
    Original file line number Diff line number Diff line change
    @@ -12,34 +12,76 @@
    -- Scheduled tasks
    -- Someday tasks
    -- Tags belonging to a project
    -- Tag hierarchy (not an OF3 feature)
    -- Tag short cuts (not an OF3 feature)
    -- Cancellation date (no OF3 equivalent)
    -- Status of a task (no OF3 equivalent)
    -- Contact for a task (no OF3 equivalent)
    -- Modification date from Things (it's a read only attribute in OF3)

    tell application "Things3"
    -- Setup hierarchal tags, in correct order and without duplicates
    set tagList to {}
    repeat with aTag in every tag
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag} to end of tagList
    else
    copy {name of parent tag of aTag, name of aTag} to end of tagList
    end if
    end repeat

    tell application "OmniFocus"
    tell default document
    -- we do this twice, once with first level and then again with second level
    -- this is the only way to preserve order

    -- first pass - parents only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is null then
    if not (tag theChildTag exists) then
    make new tag with properties {name:theChildTag}
    end if
    end if
    end repeat

    -- second pass - children only
    repeat with aTag in tagList
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is not null then
    set parentTag to tag theParentTag

    if not (my isTagInList(name of every tag of parentTag, theChildTag)) then
    set childTag to make new tag with properties {name:theChildTag}
    log "Move child tag " & theChildTag & " to parenttag " & theParentTag
    move childTag to (end of tags of (first tag whose name is theParentTag))
    end if
    end if
    end repeat
    end tell
    end tell

    -- Setup T3 Sections as Folders in OF3
    set theFolders to name of every area
    tell application "OmniFocus"
    tell default document
    repeat with aFolder in theFolders
    if not (folder aFolder exists) then
    set newFolder to make new folder with properties {name:aFolder}
    make new folder with properties {name:aFolder}
    end if
    end repeat
    end tell
    end tell

    -- TODO: Should probably do the same with tags here

    -- Used to see if an item is in the inbox or not
    set theInboxList to to dos of list "Inbox"

    -- Combine all the folders you want to search here
    -- Options are Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects
    set theTodos to to dos of list "Inbox" & to dos of list "Anytime"
    set theTodos to to dos of list "Inbox" & to dos of list "Anytime" & to dos of list "Someday"

    -- Go through all the tasks in the combined lists
    repeat with aTodo in theTodos
    @@ -83,11 +125,10 @@ tell application "Things3"
    if my isItemInList(theInboxList, aTodo) then
    -- Is this todo in the Inbox? If so, it needs special treatment
    set theProjectName to "Inbox"

    else if (project of aTodo) is missing value and not (area of aTodo) is missing value then
    -- Is this task actually a project? Projects seem to turn up as tasks for some reason, we infer this when a task has no project but it does have an area
    set processItemFlag to false

    set theFolderName to (name of area of aTodo)
    else if (project of aTodo) is missing value then
    -- Just an orphaned task
    set theProjectName to "No Project in Things"
    @@ -101,12 +142,20 @@ tell application "Things3"

    -- get all tags from todo item
    set allTagNames to {}
    copy (name of tags of aTodo) to allTagNames
    -- copy (name of tags of aTodo) to allTagNames
    repeat with aTag in every tag of aTodo
    if (parent tag of aTag) is missing value then
    copy {null, name of aTag} to end of allTagNames
    else
    copy {name of parent tag of aTag, name of aTag} to end of allTagNames
    end if
    end repeat


    -- Create a new task in OmniFocus
    tell application "OmniFocus"
    if processItemFlag then
    tell default document
    tell default document
    if processItemFlag then
    -- Set (or create new) project
    -- Do nothing if this is an inbox task as they don't have projects
    if not (theProjectName is "Inbox") then
    @@ -115,6 +164,7 @@ tell application "Things3"
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if

    @@ -125,7 +175,7 @@ tell application "Things3"
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    log "Creating project '" & theFolderName & "\\" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    end tell
    @@ -143,20 +193,24 @@ tell application "Things3"
    end tell
    end if

    -- Add tags
    repeat with theTag in allTagNames
    set theTag to theTag as string
    if not (theTag = "") then
    if not (tag theTag exists) then
    log "Creating new tag '" & theTag & "'"
    make new tag with properties {name:theTag}
    end if
    log "Adding tag '" & theTag & "' to " & theTitle
    add tag theTag to tags of newTask
    -- Process tags
    -- Fiddly, because they're hierarchal
    repeat with aTag in allTagNames
    set theParentTag to first item of aTag
    set theChildTag to second item of aTag

    if theParentTag is null then
    -- No Parent tag
    add tag theChildTag to tags of newTask
    else
    -- Has a parent tag
    set parentTag to tag theParentTag
    set childTag to (first tag of parentTag whose name is theChildTag)
    add childTag to tags of newTask
    end if
    end repeat -- tags
    end tell -- document
    end if -- not a task
    end repeat -- tags
    end if -- not a task
    end tell -- document
    end tell -- OF application
    end repeat -- Things list
    end tell -- Things application
    @@ -170,3 +224,12 @@ on isItemInList(theList, theItem)
    end repeat
    return the matchFlag
    end isItemInList
    -- Another hack for heirarchal tags to say "does tag exist inside this other tag?"
    on isTagInList(theList, theItem)
    set the matchFlag to false
    repeat with anItem from 1 to the count of theList
    if item anItem of theList is theItem then ¬
    set the matchFlag to true
    end repeat
    return the matchFlag
    end isTagInList
  12. @matellis matellis revised this gist Sep 10, 2018. 1 changed file with 141 additions and 68 deletions.
    209 changes: 141 additions & 68 deletions things-to-of.applescript
    Original file line number Diff line number Diff line change
    @@ -4,96 +4,169 @@
    --------------------------------------------------
    --------------------------------------------------
    --
    -- Script taken from: http://forums.omnigroup.com/showthread.php?t=14846&page=2
    -- Added: creation date, due date, start date functionality
    -- Script taken from: http://forums.omnigroup.com/showthread.php?t=14846&page=2 && https://gist.github.com/cdzombak/11265615
    -- Added: OF3 & Things 3 compatibility; task order; areas/folders; tags
    -- Empty your Things Trash first.
    -- Note that this won't move over scheduled recurring tasks.
    --
    -- Does not yet support:
    -- Scheduled tasks
    -- Someday tasks
    -- Tags belonging to a project
    -- Tag hierarchy (not an OF3 feature)
    -- Tag short cuts (not an OF3 feature)
    -- Cancellation date (no OF3 equivalent)
    -- Status of a task (no OF3 equivalent)
    -- Contact for a task (no OF3 equivalent)
    -- Modification date from Things (it's a read only attribute in OF3)

    tell application "Things3"
    -- Setup T3 Sections as Folders in OF3
    set theFolders to name of every area
    tell application "OmniFocus"
    tell default document
    repeat with aFolder in theFolders
    if not (folder aFolder exists) then
    set newFolder to make new folder with properties {name:aFolder}
    end if
    end repeat
    end tell
    end tell

    -- TODO: Should probably do the same with tags here

    -- Used to see if an item is in the inbox or not
    set theInboxList to to dos of list "Inbox"

    -- Combine all the folders you want to search here
    -- Options are Inbox, Today, Anytime, Upcoming, Someday, Lonely Projects
    set theTodos to to dos of list "Inbox" & to dos of list "Anytime"

    -- Loop through ToDos in Things. Do Next, Scheduled, Someday, Inbox.
    -- Note that Someday'd Projects don't get included.
    -- After doing the above lists, move Someday projects to Next and change this to "of project "project name"".
    repeat with aToDo in to dos of list "Upcoming"
    -- Go through all the tasks in the combined lists
    repeat with aTodo in theTodos

    -- Get title and notes of Things task
    set theTitle to name of aToDo
    set theNote to notes of aToDo
    set theCreationDate to creation date of aToDo
    set theDueDate to due date of aToDo
    set theStartDate to activation date of aToDo
    set theTitle to name of aTodo
    set theNote to notes of aTodo

    -- get dates
    if (creation date of aToDo) is not missing value then
    set theCreationDate to creation date of aToDo
    else
    set theCreationDate to today
    end if
    -- ON DUE AND DEFER DATES - PLEASE READ
    -- T3 has a 'Due Date' (deadline) and an 'Activation Date' (next review). These are not directly comparable to OF3 which has a next review date by project and no 'deadline' date
    -- If we map these fields directly then everything you marked to do TODAY in T3 will disappear tomorrow as the 'Defer Date' will be in the past
    -- I didn't use the Due Date much in T3 so I've decided to put Activation Date (T3) into Due Date (OF3) and then flag a task if there was a completion date

    if (due date of aToDo) is not missing value then
    set theDueDate to due date of aToDo
    end if
    -- This is the straightforward way to convert, I don't like it
    set theDueDate to due date of aTodo
    set theStartDate to activation date of aTodo -- aka "Defer Date"
    set theFlagStatus to false
    set theDeadlineDate to missing value
    -- End of simple translation

    if (activation date of aToDo) is not missing value then
    set theStartDate to activation date of aToDo
    -- My alternate translation which I think is more practical even if not directly true
    -- If you want it the other way just comment out these three lines
    set theStartDate to missing value
    set theDueDate to activation date of aTodo
    set theFlagStatus to not (due date of aTodo is missing value)
    if theFlagStatus then
    set theNote to "We flagged this item because it originally had a deadline in Things 3 of " & (due date of aTodo) & return & return & theNote
    end if
    set theDeadlineDate to due date of aTodo
    -- End of alternate translation

    set theCompletionDate to completion date of aTodo
    set theCreationDate to creation date of aTodo

    -- Get project & area names
    set theFolderName to ""
    set theProjectNote to ""
    set theProjectName to ""
    set processItemFlag to true

    -- Get project name
    if (project of aToDo) is not missing value then
    set theProjectName to (name of project of aToDo)
    if my isItemInList(theInboxList, aTodo) then
    -- Is this todo in the Inbox? If so, it needs special treatment
    set theProjectName to "Inbox"

    else if (project of aTodo) is missing value and not (area of aTodo) is missing value then
    -- Is this task actually a project? Projects seem to turn up as tasks for some reason, we infer this when a task has no project but it does have an area
    set processItemFlag to false

    else if (project of aTodo) is missing value then
    -- Just an orphaned task
    set theProjectName to "No Project in Things"
    else
    set theProjectName to "No Project In Things"
    set theProjectName to (name of project of aTodo)
    set theProjectNote to (notes of project of aTodo)
    if not (area of project of aTodo) is missing value then
    set theFolderName to (name of area of project of aTodo)
    end if
    end if

    -- Get Contexts from tags
    -- get all tags from one ToDo item...
    -- get all tags from 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
    copy (name of tags of aTodo) to allTagNames

    -- Create a new task in OmniFocus
    tell application "OmniFocus"

    tell default document

    repeat with theTag in allTagNames
    set theTag to theTag as string
    if not (theTag = "") then
    if not (tag theTag exists) then
    log "Created new tag '" & theTag & "'"
    make new tag with properties {name:theTag}
    if processItemFlag then
    tell default document
    -- Set (or create new) project
    -- Do nothing if this is an inbox task as they don't have projects
    if not (theProjectName is "Inbox") then
    -- We have to do this differently if an area exists
    if theFolderName = "" then
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if

    else
    -- if we want this to be within an area for some reason we have to do it within a tell block for the area
    set theFolder to folder theFolderName
    tell theFolder
    if project theProjectName exists then
    set theProject to project theProjectName
    else
    log "Creating project '" & theProjectName & "'"
    set theProject to make new project with properties {name:theProjectName, note:theProjectNote}
    end if
    end tell
    move theProject to (end of sections of (first folder whose name is theFolderName))
    end if
    end if
    end repeat

    -- 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

    set testTag to tag "schedule"
    -- Create new task
    tell theProject
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate}

    if (theStartDate is not missing value) then set the defer date of newTask to theStartDate

    if (theDueDate is not missing value) then set the due date of newTask to theDueDate
    -- Create the actual task - does not de-dupe
    -- Do it differently if inbox
    if theProjectName is "Inbox" then
    set newTask to make new inbox task with properties {name:theTitle, note:theNote, creation date:theCreationDate}
    else
    tell theProject
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate, due date:theDueDate, defer date:theStartDate, completion date:theCompletionDate, flagged:theFlagStatus}
    end tell
    end if

    -- Add tags
    repeat with theTag in allTagNames
    -- set theRealTag to tag theTag
    -- log "theRealTag:" & (theRealTag as string)
    -- set the tag of newTask to tag theTag
    end repeat

    end tell

    end tell -- document
    set theTag to theTag as string
    if not (theTag = "") then
    if not (tag theTag exists) then
    log "Creating new tag '" & theTag & "'"
    make new tag with properties {name:theTag}
    end if
    log "Adding tag '" & theTag & "' to " & theTitle
    add tag theTag to tags of newTask
    end if
    end repeat -- tags
    end tell -- document
    end if -- not a task
    end tell -- OF application
    end repeat -- Main loop
    end repeat -- Things list
    end tell -- Things application

    -- Clumsy way of seeing if an item is in the Inbox as Things doesn't expose a "list" property
    on isItemInList(theList, theItem)
    set the matchFlag to false
    repeat with anItem from 1 to the count of theList
    if id of item anItem of theList is id of theItem then ¬
    set the matchFlag to true
    end repeat
    return the matchFlag
    end isItemInList
  13. @matellis matellis revised this gist Sep 9, 2018. 1 changed file with 19 additions and 31 deletions.
    50 changes: 19 additions & 31 deletions things-to-of.applescript
    Original file line number Diff line number Diff line change
    @@ -9,12 +9,12 @@
    -- Empty your Things Trash first.
    -- Note that this won't move over scheduled recurring tasks.

    tell application "Things"
    tell application "Things3"

    -- Loop through ToDos in Things. Do Next, Scheduled, Someday, Inbox.
    -- Note that Someday'd Projects don't get included.
    -- After doing the above lists, move Someday projects to Next and change this to "of project "project name"".
    repeat with aToDo in to dos of list "Next"
    repeat with aToDo in to dos of list "Upcoming"

    -- Get title and notes of Things task
    set theTitle to name of aToDo
    @@ -42,7 +42,7 @@ tell application "Things"
    if (project of aToDo) is not missing value then
    set theProjectName to (name of project of aToDo)
    else
    set theProjectName to "NoProjInThings"
    set theProjectName to "No Project In Things"
    end if

    -- Get Contexts from tags
    @@ -53,20 +53,21 @@ tell application "Things"
    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
    repeat with theTag in allTagNames
    set theTag to theTag as string
    if not (theTag = "") then
    if not (tag theTag exists) then
    log "Created new tag '" & theTag & "'"
    make new tag with properties {name:theTag}
    end if
    end if
    end repeat

    -- Set (or create new) project
    if project theProjectName exists then
    @@ -75,37 +76,24 @@ tell application "Things"
    set theProject to make new project with properties {name:theProjectName}
    end if

    set testTag to tag "schedule"
    -- Create new task
    tell theProject
    set newTask to make new task with properties {name:theTitle, note:theNote, context:theContext, creation date:theCreationDate}
    set newTask to make new task with properties {name:theTitle, note:theNote, creation date:theCreationDate}

    if (theStartDate is not missing value) then set the defer date of newTask to theStartDate

    if (theDueDate is not missing value) then set the due date of newTask to theDueDate

    repeat with theTag in allTagNames
    -- set theRealTag to tag theTag
    -- log "theRealTag:" & (theRealTag as string)
    -- set the tag of newTask to tag theTag
    end repeat

    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
  14. @cdzombak cdzombak renamed this gist Apr 25, 2014. 1 changed file with 8 additions and 30 deletions.
    38 changes: 8 additions & 30 deletions gistfile1.applescript → things-to-of.applescript
    Original file line number Diff line number Diff line change
    @@ -5,13 +5,15 @@
    --------------------------------------------------
    --
    -- Script taken from: http://forums.omnigroup.com/showthread.php?t=14846&page=2
    --

    -- Added: creation date, due date, start date functionality
    -- Empty your Things Trash first.
    -- Note that this won't move over scheduled recurring tasks.

    tell application "Things"

    -- Loop through ToDos in Things
    -- Loop through ToDos in Things. Do Next, Scheduled, Someday, Inbox.
    -- Note that Someday'd Projects don't get included.
    -- After doing the above lists, move Someday projects to Next and change this to "of project "project name"".
    repeat with aToDo in to dos of list "Next"

    -- Get title and notes of Things task
    @@ -77,7 +79,7 @@ tell application "Things"
    tell theProject
    set newTask to make new task with properties {name:theTitle, note:theNote, context:theContext, creation date:theCreationDate}

    if (theStartDate is not missing value) then set the start date of newTask to theStartDate
    if (theStartDate is not missing value) then set the defer date of newTask to theStartDate

    if (theDueDate is not missing value) then set the due date of newTask to theDueDate

    @@ -97,7 +99,7 @@ end tell -- Things application
    --------------------------------------------------
    on FindContextName(tagNames)
    -- Example usage
    --FindContextName("@Mac", "1/2hr", "High") -- FYI, my tags are context, duration and priority
    -- FindContextName("@Mac", "1/2hr", "High") -- FYI, my tags are context, duration and priority

    repeat with aTagName in tagNames
    if aTagName starts with "@" then
    @@ -106,28 +108,4 @@ on FindContextName(tagNames)
    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()
    end FindContextName
  15. @hvolkmer hvolkmer revised this gist Nov 5, 2012. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion gistfile1.applescript
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,9 @@
    -- Import tasks from Things to OmniFocus
    --------------------------------------------------
    --------------------------------------------------
    --
    -- Script taken from: http://forums.omnigroup.com/showthread.php?t=14846&page=2
    --

    -- Added: creation date, due date, start date functionality

    @@ -127,4 +130,4 @@ on ReplaceText(find, replace, subject)

    return subject

    end ReplaceText -- End replaceText()
    end ReplaceText -- End replaceText()
  16. @hvolkmer hvolkmer renamed this gist Nov 5, 2012. 1 changed file with 29 additions and 2 deletions.
    31 changes: 29 additions & 2 deletions gistfile1.txt → gistfile1.applescript
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,9 @@
    -- Import tasks from Things to OmniFocus
    --------------------------------------------------
    --------------------------------------------------

    -- Added: creation date, due date, start date functionality

    tell application "Things"

    -- Loop through ToDos in Things
    @@ -11,6 +14,24 @@ tell application "Things"
    -- Get title and notes of Things task
    set theTitle to name of aToDo
    set theNote to notes of aToDo
    set theCreationDate to creation date of aToDo
    set theDueDate to due date of aToDo
    set theStartDate to activation date of aToDo

    -- get dates
    if (creation date of aToDo) is not missing value then
    set theCreationDate to creation date of aToDo
    else
    set theCreationDate to today
    end if

    if (due date of aToDo) is not missing value then
    set theDueDate to due date of aToDo
    end if

    if (activation date of aToDo) is not missing value then
    set theStartDate to activation date of aToDo
    end if

    -- Get project name
    if (project of aToDo) is not missing value then
    @@ -51,7 +72,13 @@ tell application "Things"

    -- Create new task
    tell theProject
    set newTask to make new task with properties {name:theTitle, note:theNote, containing project:theProject, context:theContext}
    set newTask to make new task with properties {name:theTitle, note:theNote, context:theContext, creation date:theCreationDate}

    if (theStartDate is not missing value) then set the start date of newTask to theStartDate

    if (theDueDate is not missing value) then set the due date of newTask to theDueDate


    end tell

    end tell -- document
    @@ -100,4 +127,4 @@ on ReplaceText(find, replace, subject)

    return subject

    end ReplaceText -- End replaceText()
    end ReplaceText -- End replaceText()
  17. @aderyabin aderyabin created this gist Dec 12, 2011.
    103 changes: 103 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,103 @@
    --------------------------------------------------
    --------------------------------------------------
    -- 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()