Nodewatch for Productivity
November 4, 2013Recently, I contributed the nodewatch.py plugin to Leo. I wrote this as a way to keep myself productive, and have an at-a-glimpse look at important nodes in my workbook.leo file. I thought I'd share the @nodewatch
definitions I hacked together to help with this.
Some important notes:
- The snippets below are on gist, which does not to my knowledge allow syntax highlighting without a file suffix. Ignore the .py in the filenames -- those are node headlines.
- These definitons require Terry Brown's todo.py plugin to be enabled, else they will throw exceptions and not work.
- These definitions use python-dateutil's relativedelta to make my life easier. You'll need to
pip install python-dateutil
to get these scripts to work.
Some preliminaries first. All four of the @nodewatch definitions I have below use the same << imports >>
and get_tasks_by_date
nodes as children. I used clones for this, to keep them all in sync. Here's << imports >>
:
import datetime | |
import operator | |
from dateutil.relativedelta import relativedelta # do a 'pip install python-dateutil' for this |
And here's get_tasks_by_date
:
## workhorse | |
def get_tasks_by_date(date, comparator=operator.lt): | |
n = [] | |
for v in c.all_unique_nodes(): | |
duedate = c.cleo.getat(v, 'duedate') | |
nextworkdate = c.cleo.getat(v, 'nextworkdate') | |
priority = c.cleo.getat(v, 'priority') | |
if priority: priority = int(priority) | |
if (((duedate and comparator(duedate,date)) or | |
(nextworkdate and comparator(nextworkdate,date))) | |
and priority != 100): | |
n.append(v) | |
return n |
Alright... now, get_tasks_by_date() returns a list of vnodes that are not marked 'done' by todo.py, but have a duedate or nextworkdate such that comparator(date,otherdate) is True. That does all the hard work. Next up is 4 very similar @nodewatch definitions:
@language python | |
<< imports >> | |
@others | |
categoryname = 'LTD: 00 Past Due' | |
today = datetime.date.today() | |
tasks = get_tasks_by_date(today, comparator=operator.lt) | |
c.theNodewatchController.add(categoryname, tasks) |
@language python | |
<< imports >> | |
@others | |
categoryname = 'LTD: 01 Due Today' | |
today = datetime.date.today() | |
tasks = get_tasks_by_date(today, comparator=operator.eq) | |
c.theNodewatchController.add(categoryname, tasks) |
@language python | |
<< imports >> | |
@others | |
categoryname = 'LTD: 02 Due Tomorrow' | |
today = datetime.date.today() + relativedelta(days=1) | |
tasks = get_tasks_by_date(today, comparator=operator.eq) | |
c.theNodewatchController.add(categoryname, tasks) |
@language python | |
<< imports >> | |
@others | |
categoryname = 'LTD: 03 Due This Week' | |
today = datetime.date.today() + relativedelta(days=7) | |
tasks = get_tasks_by_date(today, comparator=operator.le) | |
c.theNodewatchController.add(categoryname, tasks) |
Putting this all together under your @settings
node, and clicking the Refresh button (or running the command nodewatch-update
), you now have 4 categories in your Nodewatch GUI's drop-down box: 'LTD: 00 Past Due', 'LTD: 01 Due Today', 'LTD: 02 Due Tomorrow', and 'LTD: 03 Due This Week'. This will help you get fast looks at what you need to focus on today, tomorrow, and this week.
Unfortunately, the get_tasks_by_date
code is a bit ugly and really dense, and it required a read through of the todo.py source, and understanding of the operator module... but it packs a lot of filtering power into those lines, making other due-date sorting @nodewatch definitions easier in the future. For example, you could define a @nodewatch Due This Month
script with:
@language python | |
<< imports >> | |
@others | |
categoryname = 'LTD: 04 Due This Month' | |
today = datetime.date.today() + relativedelta(months=1) | |
tasks = get_tasks_by_date(today, comparator=operator.le) | |
c.theNodewatchController.add(categoryname, tasks) |
Plenty of other things can be done with nodewatch, but this is my primary usage so far.