The Omni Group Forums

The Omni Group Forums (
-   OmniFocus Extras (
-   -   Script: custom OmniFocus action lists on the desktop, using Geektool (

RobTrew 2010-12-16 06:09 AM

Script: custom OmniFocus action lists on the desktop, using Geektool
1 Attachment(s)

OVERVIEW[INDENT]It can be useful to glance at a key action list on the desktop, without having to fire up OmniFocus and choose a perspective. (A [I]due now[/I] list perhaps, or [I]due soon[/I], or a context list, or simply the inbox, as a spur to getting it clear).

This post splits off from [URL=""]another thread[/URL] which began by discussing ways of displaying a desktop banner of the current action, and drifted off topic towards Geektool.

I posted a couple of rather rudimentary scripts to that thread (for getting particular - unformatted and unwrapped - OF lists into a Geektool window), but here is a much more general script which enables you to attach a range of customized list specifiers to one or more Geektool 'windows' (shell geeklets) at the same time.
[INDENT]Displays one or more custom action lists (or project lists) on your desktop, even when OmniFocus isn't running, using [URL=""]GeekTool[/URL].

The lists can be wrapped to fit the geeklet window, shifted to upper case, or generally modified by piping them through shell commands.[/INDENT]
LIST DEFINITIONS[INDENT]Some simple queries are pre-defined by the script,[INDENT]in inbox
due soon
due now
next action
in context <Context Name>[INDENT]in context "Phone"
in context "Library"[/INDENT]selected actions

[[I]selected actions[/I] does, of course, require OmniFocus to be running - it lists the actions currently selected in the OF GUI][/INDENT]and these can all be modified, for example to adjust sort order,
[INDENT]in inbox order by dateAdded
in inbox order by dateAdded DESC
in inbox order by dateDue, dateAdded
due now order by effectivedateDue
next action order by effectiveDateDue
in context "Library" order by[/INDENT][/INDENT][INDENT]
and/or further restrict contents.
[INDENT]next action and flagged=1
next action and flagged=0 order by effectiveDateDue[/INDENT][/INDENT][INDENT]Their format can be adjusted by piping them through further shell commands, like fold and tr.[INDENT]Wrapping with 'fold'
[INDENT]inbox order by dateDue, dateAdded | fold -s -w 50
in context "Phone" | fold -s -w 30[/INDENT][/INDENT][/INDENT][INDENT][INDENT]Shifting to upper case with 'tr'
[INDENT]due now order by effectiveDateDue | tr "[:lower:]" "[:upper:]" | fold -s -w 40
active selections order by name | tr "[:lower:]" "[:upper:]" | fold -s -w 40[/INDENT]
(or anything else which can be achieved by piping to another shell command).[/INDENT][/INDENT][INDENT]More sophisticated queries can be devised in Sqlite SQL.[INDENT]Project / Projects is a pre-defined alias,
and a set of relative date expressions can be used in the SQL clauses.[INDENT]yesterday, today, now, soon
<jan> ... <dec> (Interpreted as references to midnight at the start of the first day of the next (or current) month of that name).

today +1w, now +2d etc.[/INDENT][/INDENT][INDENT][/INDENT][/INDENT]
PRECEDING THE LIST WITH A HEADER[INDENT]The default list header is [I]$Q ($N) & return[/I] where $Q is a variable representing the query, and $N is the number of matches.
In addition, a custom header can now be specified for a List/Geeklet by following the query with the switch [B]--header=[/B] followed by an unquoted string, optionally including $Q or $N
e.g. [LIST][*][I]Due Soon --header=$Q [$N matches]: | fold -s -w 40[/I][*][I]task where flagged=1 order by projectinfo, dateDue --header=Flagged ($N)[B]\n[/B] | fold -s -w 40[/I][*]or simply (to display no header at all) [I]Active Selections --header= | fold -s -w 40[/I][/LIST]
Note that additional blank lines in (or at the end of) the header can be specified as [B]\n[/B]
[/INDENT]INSTALLATION[LIST=1][*]Choose a home for this script (if you put it in the OmniFocus script directory it will appear in the OF script menu, and can be installed on the OF toolbar). (~/Library/Scripts/Applications/Omnifocus )[*]Install Geektool [url][/url][*]Drag one or more shell windows from the GeekTool preference pane onto your desktop, select each of your shell windows in turn, and use the properties dialog to assign it: [LIST][*]A name (at the top of the properties dialog - it says "optional" but this script needs each of your Geeklets to have a name).[*]The colours and font that you want (not urgent, these can be changed later),[*]A time out period of 5 seconds, and refresh interval of 10+ seconds. (lists that won't change rapidly can obviously be refreshed less frequently).

(Note that there is no need to assign a command - that will be done automatically by this script.)[/LIST][*]Launch this script.[/LIST]
USAGE[LIST=1][*]Run this script,[*]choose a shell geeklet from the list that appears,[*]and respond the prompt by typing the name of a simple or modified query.[/LIST][INDENT]It may be helpful to begin your experimentation by simply accepting the default query which is offered.
If an error message appears in your geeklet, run this script again and carefully check the spelling and syntax of your list description.[/INDENT]

RobTrew 2010-12-18 05:17 AM

I have updated the code above to ver 0.3 which simplifies the customization or suppression of custom headers for each list/geeklet.

(See the new section (above) under the heading "PRECEDING THE LIST WITH A HEADER")

I have also assembled some sample geeklets which can be installed directly by double-clicking them (as long as GeekTool as been installed on your system, and you have copied the theGeekOFSQL.scpt to your OmniFocus script folder).

(See the geeklets zip attached below - note that these require installation of the script in Post 1 above)


These are pre-fabricated samples of the kind of Geek Tools shell geeklet that can be be run with the GeekOFSQL.scpt applescript.

They are not guaranteed to be useful, and are intended simply to provide a quick way of trying out the script.

Each of them displays a different list from your OmniFocus data. With the exception of the Active Selections geeklet, they do not need Omnifocus to be running.

The colors and font sizes etc may need to be adjusted for your desktop.


1. Install GeekTool from [url][/url]

2. Copy the script GeekOFSQL.scpt to the OmniFocus scripts folder, so that its path is:


(where ~ represents your home folder).

[Note that this is an important step, as these geeklets depend on finding the script in that location]

3. Install any or all of the geeklet (.glet) files by double-clicking them.


For reference, these Geeklets run the following commands. (The simplest way to attach or modify Geeklet commands for OmniFocus lists is, however, to run the GeekOFSQL.scpt in the Applescript script editor, and then choose the name of a Geeklet from the drop-down list).

The script can be found in the first post in this thread.

Active Selections:
osascript ~/Library/Scripts/Applications/Omnifocus/GeekOFSQL.scpt 'Active Selections --hdr=\n' | fold -s -w 60

osascript ~/Library/Scripts/Applications/Omnifocus/GeekOFSQL.scpt 'task where flagged=1 order by projectinfo, dateDue --header=Flagged ($N)\n' | fold -s -w 40

Next Action:
osascript ~/Library/Scripts/Applications/Omnifocus/GeekOFSQL.scpt 'Next Action' | fold -s -w 40

Due Soon:
osascript ~/Library/Scripts/Applications/Omnifocus/GeekOFSQL.scpt 'Due Soon order by effectiveDateDue' | fold -s -w 45

Due Now:
osascript ~/Library/Scripts/Applications/Omnifocus/GeekOFSQL.scpt 'Due Now order by effectiveDateDue' | fold -s -w 45

osascript ~/Library/Scripts/Applications/Omnifocus/GeekOFSQL.scpt 'In Inbox order by dateAdded --hdr=Inbox ($N)\n' | fold -s -w 40


RobTrew 2010-12-20 02:23 PM

Updated the script and the sample geeklets to format longer lines as hanging indents.

(Simply by piping them through a few replacements, e.g.
[INDENT][I]osascript ~/Library/Scripts/Applications/Omnifocus/GeekOFSQL.scpt 'Next Action' | tr '\r' '\n' | fold -s -w 40 | perl -pe 's/(^[^]+)/\t\1/g' | perl -pe 's//-/g' [/I][/INDENT]
I'm sure there is a more elegant way :-)


macula 2010-12-22 11:01 AM

Rob, where could I find the OmniFocus SQlite specification? Is there a complete reference available?

Thank you.

RobTrew 2010-12-22 03:10 PM

No formal documentation that I know of, but you can put a list of the fields and their types into the clipboard with code like:

[CODE]property pstrDBPath : "~/Library/Caches/com.omnigroup.OmniFocus/OmniFocusDatabase2"
property plstResults : {}

on run
set text item delimiters to return
set str to ""
set lstTables to ({"Task", "ProjectInfo", "Context", "Folder"})
repeat with oTable in lstTables
set strSQL to "PRAGMA TABLE_INFO(" & oTable & ");"
set str to str & oTable & return & return & (plstResults as string) & return & return & return
end repeat
set text item delimiters to space

set the clipboard to str
end run

on RunSQL(strSQL)
set strCmd to "sqlite3 " & pstrDBPath & space & quoted form of strSQL

set plstResults to (paragraphs of (do shell script strCmd))
end RunSQL

(Probably important to bear in mind that the schema can change, unannounced, between builds, and that reading the cache has been described on this forum as "at the deep end of not officially supported").

macula 2010-12-22 03:14 PM

Warm thanks, Rob. In the meantime, and considering my lack of your SQL chops, I resorted to the open-source "SQLite Database Browser 2.0," which also facilitates inductive reasoning about the function of each key.

sterlizzi 2010-12-25 01:42 PM

Matching Due Soon
Hi Rob,

I love your Geektool scripts.

I have a question. How can I modify the script so that the "due soon" in Geektool matches the "due soon" in Omnifocus? I have "due soon" set to 2 days in Omnifocus but it seems that the "geektool" due soon is only picking up tomorrow's tasks and missing the tomorrow's tomorrow's tasks?



RobTrew 2010-12-26 07:24 PM

Good question, and I have now updated the script.

[URL=""]Ver .09[/URL] (post 1 in this thread, above) now automatically gets the current Due Soon interval setting, as in
[INDENT][B]OF > Preferences > Data > "Due Soon" is in the next N days[/B][/INDENT]
(OF does not need to be running).


sterlizzi 2010-12-27 04:40 PM

Hi Rob,

I updated the Script. This is the behavior that I am seeing with Due Soon marked to 2 days in OF Preferences:

1) [U]Your Due Now[/U] - Only lists items that were due yesterday or earlier, which in Omnifocus is marked as Red.

2) [U]Your Due Soon[/U] - Lists both today's items, which in Omnifocus is marked as Red, and tomorrow's items, which in Omnifocus is market as Orange. However, it misses listing the items due the day after tomorrow, which in OF are also marked in Orange.

I think there may a difference in the logic between your script and OF badges. OF considers today and earlier to be red and X number of days as per OF preference starting with tomorrow to be orange.

Am I doing something wrong?

RobTrew 2010-12-28 12:15 AM

[QUOTE=sterlizzi;90929]with Due Soon marked to 2 days in OF Preferences ...

2) [U]Your Due Soon[/U] - Lists both today's items, which in Omnifocus is marked as Red, and tomorrow's items, which in Omnifocus is market as Orange. However, it misses listing the items due the day after tomorrow, which in OF are also marked in Orange.

The difference may be in our OF settings - with:
[INDENT][I]Preferences > Data > "Due Soon" is in the next 2 days[/I][/INDENT]and [INDENT][I]Prefs > Data > Default Time for Due dates[/I] at 17:00[/INDENT]
Today and Tomorrow are (this morning) orange on my system, and day after tomorrow is unmarked (black).
(I would expect the colouring to change at 17:00 this evening).

(Script ver 1.0, OF 1.8.2)


(Where Dec 30 is day after tomorrow)

My understanding of Orange and Red in OF is:

[Orange]-> ('Due Soon' in the script)
[INDENT][I]tasks where (completed is false) and [B](due date > now) and (due date < soon)[/B] and (((status of its containing project is active) and (effectively hidden of folder of its containing project is false or folder of its containing project is missing value)) or (in inbox is true))[/I][/INDENT]
[Red]-> ("Due Now" in the script)
[INDENT][I]tasks where (completed is false) and [B](due date < now)[/B] and (((status of its containing project is active) and (effectively hidden of folder of its containing project is false or folder of its containing project is missing value)) or (in inbox is true))[/I][/INDENT]
(The Sqlite SQL clauses in the script aim to match this).

There may be some subtlety here that is eluding me. Do you have a different Default Time setting, for example ?
At what time of day does there seem to be a mismatch ?


All times are GMT -8. The time now is 05:58 PM.

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