I’ve been playing around with the geeky, efficient, command-line scheduling program remind. It’s very cool once you get used to it.

I wanted to automatically export any duedates from taskwarrior, so this is what I came up with.

Export Taskwarrior Dates

I found a script that did this (written in java), but I didn’t like it. It scheduled things that weren’t due and there seemed to be a lot of overhead for a task that amounts to generating a simple text file.

Using taskwarrior’s own export function and a bit of python, I put together the following code. It generates a file for Remind to read from only tasks that have a due date set and are not blocked by another task (such as one it depends on; rare for tasks with due-dates).

remindWarrior

#!/usr/bin/python
import json, subprocess
from pprint import pprint

outfile = '/home/USERNAME/.config/reminders/taskwarrior.rem'

reminders = '# Taskwarrior Tasks with Due Dates\n'
for t in json.loads(subprocess.check_output(['task', '+DUE', '+UNBLOCKED', 'export'])):
    reminders += ("REM %s-%s-%s MSG %%\"%s%%\" (taskwarrior)\n" % (t['due'][:4],t['due'][4:6],t['due'][6:8],t['description']))

#print(reminders)

with open(outfile, 'r') as f:
    #compare file with reminders string
    if reminders != f.read():
        #write new file only if it differs from existing file
        with open(outfile, 'w') as o:
            o.write(reminders)

Run crontab -e and add a line in there to run this sucker every 5 minutes or so:

*/5 * * * * remindWarrior

As you can see, I’ve set up my reminders in a hidden directory. My ~/.reminders file includes a single line.

INCLUDE /home/USER/.config/reminders

Note also, that the script checks to see if the new file would be any different from the old file and only writes to the file if it has changed. This becomes significant later.

Automatic re-starting of Remind

I run remind as a daemon so that it will pop up reminders (using gmessage) for me. But when you change the files that remind uses, this daemon doesn’t re-read them. For that reason, and others, I created a script that would kill start the process if it isn’t running, or kill it and restart it again if it is running.

I call it reminderdaemon and it’s how I start the reminder daemon when I log in.

reminderdaemon

#!/bin/bash
XAUTHORITY=/home/USERNAME/.Xauthority
export XAUTHORITY

pid=$(ps -C rem -o pid=)
if [ -n "$pid" ]
then
	#Remind is running so restart it
	kill $pid
	rem -az -k'gmessage %s -default okay -timeout 30 -center -title Remind -display :0.0' &
else
	#Remind is NOT running so start it
	rem -az -k'gmessage %s -default okay -timeout 30 -center -title Remind -display :0.0' &
fi
exit

Incron, or how to automate the restart script when files change

Here’s something really cool that I didn’t know about for a very long time:

You probably know about cron; the service that runs things for you based on time. But there’s also a service called incron that monitors files or folders and triggers actions when those files change. Very cool.

I ran incrontab -e to edit my incron config file and put the following line in there:

/home/USER/.config/reminders IN_MODIFY /home/USER/bin/reminderdaemon

Now whenever one of the files in my .config/reminders directory is updated (including the taskwarrior.rem file), the reminder daemon restarts with the new configuration.

And remember that my remindWarrior script only writes to taskwarrior.rem if it would change the contents. This prevents unnecessarily restarting the daemon every five minutes.