The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniPlan Extras (http://forums.omnigroup.com/forumdisplay.php?f=45)
-   -   OmniPlan to TaskPaper AppleScript (http://forums.omnigroup.com/showthread.php?t=23410)

psidnell 2012-02-05 09:34 AM

OmniPlan to TaskPaper AppleScript
 
My needs are simple, so it may be a little rough around the edges:

[CODE]
-- ver 0.3 2012-02-06 Exports an OmniPlan project to a TaskPaper project
--
-- Based on Rob Trew's OmniPlan to OmniFocus script
--
-- All activities (or those selected) in OmniPlan GUI transferred (with their descendants)
-- into a new date-stamped project in new TaskPaper file.
-- #####
-- Posted: http://forums.omnigroup.com/showthread.php?t=23410
-- #####
-- 2012-02-05: added resources as TP Tags
-- 2012-02-06: fixed bug with date formatting
-- 2012-02-06: Combined two scripts into one (still a lot of similar looking code)
-- #####
-- TODO integrate with OP as an export type - possible?
-- Can params be passed in to configure output?

-- Main entry point
on run
-- Choose One:
--createStructure()
createDateList()
end run

-- Create a TP document resembling the OmniPlan project structure
on createStructure()
set {docName, lstTasks} to readPlanStructure()
if length of lstTasks > 0 then
createTPStructure(docName, lstTasks)
else
display dialog "No tasks found"
end if
end createStructure

-- Create a TP document with leaf tasks organised by day
on createDateList()
set {docName, lstTasks} to readPlanDateList()
if length of lstTasks > 0 then
createTPDateList(docName, lstTasks)
else
display dialog "No tasks found"
end if
end createDateList

-- ########## OMNIPLAN CODE

-- Get a nested list of the selected OmniPlan activities
on readPlanStructure()
tell application "OmniPlan"

tell document 1 of it
tell project of it
set projectTitle to title of it
end tell
end tell

tell front window
if (count of selected tasks) > 0 then
set lstOPTasks to selected tasks
else
set lstOPTasks to (every child task)
end if
if (count of lstOPTasks) > 0 then
return {projectTitle, my tasksToStructureList(lstOPTasks)}
else
return {projectTitle, {}}
end if
end tell
end tell
end readPlanStructure

-- Get a flat list of leaf tasks
on readPlanDateList()
tell application "OmniPlan"

tell document 1 of it
tell project of it
set projectTitle to title of it
end tell
end tell

tell front window
if (count of selected tasks) > 0 then
set lstOPTasks to selected tasks
else
set lstOPTasks to (every child task)
end if
set leaves to {}
if (count of lstOPTasks) > 0 then
leaves = my tasksToDateList(lstOPTasks, leaves)
leaves = my sort(leaves)
return {projectTitle, leaves}
else
return {projectTitle, {}}
end if
end tell
end tell
end readPlanDateList

-- Translate OmniPlan activities to a nested list of activities
on tasksToStructureList(lstOPTasks)
using terms from application "OmniPlan"
set lstTasks to {}
repeat with oTask in lstOPTasks
tell oTask

set lstChiln to child tasks

if (lstChiln is not missing value) and (length of lstChiln) > 0 then
set end of lstTasks to my buildTaskData(oTask, my tasksToStructureList(lstChiln))
else
set end of lstTasks to my buildTaskData(oTask, {})
end if

end tell
end repeat
return lstTasks
end using terms from
end tasksToStructureList

-- Translate OmniPlan leaf activities to a list of activities
on tasksToDateList(lstOPTasks, leaves)
using terms from application "OmniPlan"
set lstTasks to {}
repeat with oTask in lstOPTasks
tell oTask

set lstChiln to child tasks

if (lstChiln is not missing value) and (length of lstChiln) > 0 then
my tasksToDateList(lstChiln, leaves)
else
-- Going to sort by first element
--set end of leaves to {ending date, name, {}, starting date, note, duration / 60, remaining effort, resrces}
set end of leaves to my buildTaskData(oTask, {})
end if

end tell
end repeat
return leaves
end using terms from
end tasksToDateList

-- Extract the task data
on buildTaskData(oTask, children)
using terms from application "OmniPlan"
tell oTask

set resrces to {}
repeat with asgn in every assignment of it
set end of resrces to name of resource of asgn
end repeat

return {ending date, name, children, starting date, note, duration / 60, remaining effort, resrces}
end tell
end using terms from
end buildTaskData

-- ########## TASKPAPER CODE

-- Place nested list of activities in a new TP file and project
on createTPStructure(docName, lstActivities)
if length of lstActivities > 0 then
tell application "TaskPaper"
make new document
tell front document
set projName to docName & " " & my tpDate(my SysDate())
set tpProject to make new project with properties {name:projName}
my fillInTPStructure(tpProject, lstActivities)
end tell
end tell
end if
end createTPStructure

-- Place flat list of activities in a new TP file and project
on createTPDateList(docName, lstActivities)
if length of lstActivities > 0 then
tell application "TaskPaper"
make new document
tell front document
set projName to docName & " " & my tpDate(my SysDate())
set tpProject to make new project with properties {name:projName}
my fillInTPDateList(tpProject, lstActivities)
end tell
end tell
end if
end createTPDateList

-- Descent the activity structure and fill in the TP tasks
on fillInTPStructure(parent, lstActivities)
using terms from application "TaskPaper"
tell parent

repeat with oAct in lstActivities
set {dteDue, strName, lstChiln, dteStart, strNote, dur, remEffrt, resources} to oAct

if length of lstChiln > 0 then
-- Assume that if the task has children then we want it to be a TP Project
set tpSubProject to make new project with properties {name:strName}
else
-- Otherwise assume it's a task
set tpSubProject to make new task with properties {name:strName}

my fillInTPElement(tpSubProject, oAct)

end if

my fillInTPNote(tpSubProject, strNote)

if length of lstChiln > 0 then
my fillInTPStructure(tpSubProject, lstChiln)
end if

end repeat

end tell
end using terms from
end fillInTPStructure

-- Walk the list of TP activities and place them in day projects
on fillInTPDateList(parent, lstActivities)
using terms from application "TaskPaper"
tell parent

set prevDate to ""
repeat with oAct in lstActivities
set {dteDue, strName, lstChiln, dteStart, strNote, dur, remEffrt, resources} to oAct
set thisDate to my tpDate(dteDue)

if prevDate is not thisDate then
set dateProj to make new project with properties {name:thisDate}
set prevDate to thisDate
end if

tell dateProj
set tpSubProject to make new task with properties {name:strName}
end tell

my fillInTPElement(tpSubProject, oAct)

my fillInTPNote(tpSubProject, strNote)

end repeat

end tell
end using terms from
end fillInTPDateList

on fillInTPElement(tpSubProject, oAct)
using terms from application "TaskPaper"
set {dteDue, strName, lstChiln, dteStart, strNote, dur, remEffrt, resources} to oAct

-- Infer some TP tags from the dates, (beware - milestones have zero duration)
tell tpSubProject
-- Standard todo/due tags
if (remEffrt > 0) then
make tag with properties {name:"todo"}
make tag with properties {name:"due", value:my tpDate(dteDue)}
else if (dur > 0) then
make tag with properties {name:"done", value:my tpDate(dteDue)}
end if

-- Inventing milestone tag
if (dur is 0) then
make tag with properties {name:"milestone", value:my tpDate(dteDue)}
end if

-- Add resources as tags
repeat with resource in resources
make tag with properties {name:resource}
end repeat
end tell
end using terms from
end fillInTPElement

-- Add any note text
on fillInTPNote(tpSubProject, strNote)
using terms from application "TaskPaper"
if (strNote is not missing value) and (strNote is not "") then
tell tpSubProject
set splitLines to my splitText(strNote, ASCII character 10)
repeat with oneLine in splitLines
make new note with properties {name:oneLine}
end repeat
end tell
end if
end using terms from
end fillInTPNote

-- ########## UTIL

-- Return a TaskPaper formatted date
on tpDate(appleDate)
return "" & year of appleDate & "-" & tpMonth(appleDate) & "-" & padZero(day of appleDate)
end tpDate

-- Turn a month name into it's integer equivalent
on tpMonth(appleDate)
-- TODO good grief, must be a better way
set monthStr to "" & month of appleDate
if monthStr is "January" then
return 1
else if monthStr is "February" then
return 2
else if monthStr is "March" then
return 3
else if monthStr is "April" then
return 4
else if monthStr is "May" then
return 5
else if monthStr is "June" then
return 6
else if monthStr is "July" then
return 7
else if monthStr is "August" then
return 8
else if monthStr is "September" then
return 9
else if monthStr is "October" then
return 10
else if monthStr is "November" then
return 11
end if
return 12
end tpMonth

-- Take an integer and return it as a string with leading zero if < 10, for TaskPaper dates
on padZero(n)
if n < 10 then
return "0" & n
else
return "" & n
end if
end padZero

-- return the current datetime
on SysDate()
current date
end SysDate

-- Split a string
on splitText(someText, delimiter)
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set output to text items of someText
set AppleScript's text item delimiters to prevTIDs
return output
end splitText

-- Sort by the first element
on sort(myList)
repeat with i from 1 to (count of myList) - 1
repeat with j from i + 1 to count of myList
if item 1 of item j of myList < item 1 of item i of myList then
set temp to item i of myList
set item i of myList to item j of myList
set item j of myList to temp
end if
log myList
end repeat
end repeat

return myList
end sort
[/CODE]

This is my first attempt at AppleScript, so apologies if there are any laugh out loud gaffes in there...

Updated: 2012-02-06


All times are GMT -8. The time now is 02:19 AM.

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