The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniFocus Extras (http://forums.omnigroup.com/forumdisplay.php?f=44)
-   -   Acting on all projects using Applescript (http://forums.omnigroup.com/showthread.php?t=15269)

curt.clifton 2010-03-01 04:18 AM

[QUOTE=RobTrew;74133]

Generally, it seems a good idea not to lose sight of OF's built-in querying when drafting scripts - any flat list that can be automatically queried into existence in the content panel can be readily harvested through applescript ...

(and of course, we can save and restore states if we want to avoid GUI side-effects ...)
[/QUOTE]

My experience is that changing and restoring the GUI states is more work and substantially slower than using recursion.

RobTrew 2010-03-01 05:08 AM

[QUOTE=curt.clifton;74136]My experience is that changing and restoring the GUI states is more work and substantially slower than using recursion.[/QUOTE]

Perhaps it depends on how much state you are aiming to conserve.

Just saving and restoring the filter states is simple to do and runs quite fast:

[CODE]set lstView to GetView()
set lstProjects to ProjectList("all-projects")
RestoreView(lstView)
lstProjects

on GetView()
tell application "OmniFocus"
tell front window
tell sidebar
set strSideID to selected smart group identifier
end tell
tell content
set strGroupID to selected grouping identifier
set strSortID to selected sorting identifier
set strDurnID to selected task duration filter identifier
set strFlagID to selected task flagged filter identifier
set strStateID to selected task state filter identifier
end tell
end tell
{strSideID, strGroupID, strSortID, strDurnID, strFlagID, strStateID}
end tell
end GetView

on RestoreView(lstView)
set {strSideID, strGroupID, strSortID, strDurnID, strFlagID, strStateID} to lstView
tell application "OmniFocus"
tell front window
tell sidebar
set selected smart group identifier to strSideID
end tell
tell content
set selected grouping identifier to strGroupID
set selected sorting identifier to strSortID
set selected task duration filter identifier to strDurnID
set selected task flagged filter identifier to strFlagID
set selected task state filter identifier to strStateID
end tell
end tell
end tell
end RestoreView

on ProjectList(strFilter)
tell application id "com.omnigroup.OmniFocus"
tell front window
set selected view mode identifier to "project"
set focus to {}
tell sidebar
select library
set selected smart group identifier to strFilter
end tell
set lstProject to {}
repeat with oTree in trees of content
set end of lstProject to value of oTree
end repeat
-- set focus to lstProject
lstProject
end tell
end tell
end ProjectList[/CODE]

RobTrew 2010-03-01 08:53 AM

Although creating and then closing a temporary window is even simpler ...

[CODE]set lstProjects to ProjectList("all-projects")

on ProjectList(strFilter)
tell application id "com.omnigroup.OmniFocus"
tell front document
tell (make new document window)
set selected view mode identifier to "project"
set focus to {}
tell sidebar
select library
set selected smart group identifier to strFilter
end tell
set lstProject to {}
repeat with oTree in trees of content
set end of lstProject to value of oTree
end repeat
close
end tell
end tell
end tell
lstProject
end ProjectList[/CODE]

curt.clifton 2010-03-01 11:32 AM

How big is your database? My original recursive script with individual item filtering takes less than a second against my database. The one that opens a new window takes over 7 seconds.

I'm not trying to have a pissing contest here. You're definitely right about not overlooking the built-in filtering capabilities, but neither should we ignore a recursive solution, especially when it's more efficient.

RobTrew 2010-03-01 02:52 PM

[QUOTE=curt.clifton;74152]You're definitely right about not overlooking the built-in filtering capabilities, but neither should we ignore a recursive solution, especially when it's more efficient.[/QUOTE]

Yes, my personal preference is for recursion too - something very elegant and pleasing about it. Here I would probably go for the recursion + where query option.

For a programmer in a hurry, however, the brief non-recursive code might give a good trade-off between programming time and run time. It's certainly quite easy to understand and maintain.

Generally, I think this kind of talmudic debate is quite productive.
It explores the search space and the cost/benefits pretty thoroughly, and one finds things that one might otherwise have overlooked, and which might prove useful later ...

I look forward to the next one :-)

[COLOR="White"]--[/COLOR]

curt.clifton 2010-03-01 03:29 PM

[QUOTE=RobTrew;74158]
I look forward to the next one :-)
[/QUOTE]

Likewise, but first I have to convert a bunch of my scripts to better use where clauses! :-)

RobTrew 2010-06-01 12:02 AM

In case anyone looks to this thread for a solution, a couple of updates come to mind.

My current summary of the faster where-query approach might have the form:

[CODE]tell application "OmniFocus"
set oDoc to default document
set lstProjects to my ProjectList(oDoc)
-- set focus of front document window of oDoc to lstProjects
end tell

on ProjectList(oParent)
using terms from application "OmniFocus"
tell oParent
-- ADJUST THE WHERE QUERIES TO MATCH THE PURPOSE
set lstProjects to projects where (status is active) or (status is on hold)
set lstFolders to folders where hidden is false
end tell
repeat with oFolder in lstFolders
set lstProjects to lstProjects & my ProjectList(oFolder)
end repeat
return lstProjects
end using terms from
end ProjectList[/CODE]

While the non-recursive (but slower) approach based on named filters can be speeded up a little by getting a value list from a reference, to avoid iteration.

[CODE]-- AVAILABLE FILTERS:
-- "all-projects"
-- "remaining-projects"
-- "active-projects"
-- "stalled-projects"
-- "pending-projects"
-- "on-hold-projects"
-- "dropped-projects"
-- "completed-projects"

property pFilter : "all-projects"
property pProject : "project"
property pAny : "any"
property pNone : "none"
property pAll : "all"

set lstProjects to ProjectList(pFilter)

on ProjectList(strFilter)
tell application id "com.omnigroup.OmniFocus"
tell default document
tell (make new document window)
set selected view mode identifier to pProject
set focus to {}
tell content
set selected grouping identifier to pNone
set selected sorting identifier to pNone
set selected task duration filter identifier to pAny
set selected task flagged filter identifier to pAll
set selected task state filter identifier to pAll
end tell
tell sidebar
select library
set selected smart group identifier to strFilter
end tell
-- value list from a reference (avoids iteration)
set lstProject to value of trees of content
close
end tell
end tell
end tell
lstProject
end ProjectList[/CODE]


[COLOR="White"]--[/COLOR]

RobTrew 2010-06-23 05:25 AM

The Applescript library enhancements recently made by Tim Woods in the Sneaky Peek 1.8 builds now hugely simplify this kind of task.

To see a list of projects which lack available actions, for example, you could now write:

[CODE]tell application "OmniFocus"
tell default document
set focus of front document window to ¬
([B]flattened projects where number of available tasks is 0[/B]) as list
end tell
end tell
[/CODE]

(Note that these applescript enhancements will be a feature of ver 1.8, and this script will not work in ver 1.7)

[COLOR="White"]--[/COLOR]

fudster 2010-06-23 07:26 AM

Very cool stuff.

I've actually been holding off on the 1.8 sneaky peek - the biggest reason is actually that I'm concerned about subtle changes and problems in applescript support. I depend on my scripts for my hour-to-hour workflow and if just one or two of them became broken, I'd be hosed until they were fixed, one way or the other. I've done skeakypeeks before (all but the last two) and there weren't many AS problems - but I do recall a couple things breaking that took a day or two to fix.

I haven't been following closely, except a glance every so often to see if it's getting close to GA. I see here that there are probably some new opportunities to simplify some of my scripts - nice, I'll have to set aside some time.

The 1.8 sneaky peek has been going for some time, I expected it to be GA by now. Any idea whether it's getting close?

curt.clifton 2010-06-24 02:15 AM

[QUOTE=fudster;79061]
The 1.8 sneaky peek has been going for some time, I expected it to be GA by now. Any idea whether it's getting close?[/QUOTE]

My gut feeling is that it is getting close. Recent changes seem to be mostly of the final-polish variety. I'd expect OF for iPad to ship first. Per the Omni blog, they're targeting a June 30 submission to Apple for that. I'm just guessing, but I'd expect a push to clean up and ship 1.8 in July.


All times are GMT -8. The time now is 03:56 PM.

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