pixel: Age of the geek, baby. (Leverage) (leverage: quoteageofthegeek)
pixel ([personal profile] pixel) wrote in [community profile] linux4all2010-10-17 06:47 pm

Getting Things Done, the Linux way

So we've all heard about how linux tools 'do one thing and do it well' and if we're new (or even not so new, natch!) to using linux we might not really understand what that means, and the raw flexible power that offers. You know you're on your way to a power user level when you really start thinking about how you can make your computer work for you, instead of the other way around. Here's the latest way I took a bunch of command line tools and glued them together so I could really Get Things Done. (I like the GTD style, but these tools certainly are flexible enough to be used any way you want or need.)

This is all stuff that is available in the repositories for Ubuntu 10.10, I'll provide some resource links at the bottom for other distro users.

RemindMe
Problem: I start a load of laundry and then I go back to my computer I get absorbed cranking out code, or chatting on irc or reading Dreamwidth... and 3 hours later I remember to go change the loads. Sometimes to the significant annoyance of other folks waiting to use the laundry machine.

Solution: A simple bash script that lets me put in a duration or a time, and pops up a reminder on my desktop to tell me to go change the loads.

Tools

> sudo apt-get install libnotify-bin


Lets make our bash script, I dropped this file inside my ~/bin directory, (remember to chmod +x remme to make it executable and either put it in your $PATH or tweak your $PATH to find it.)

#!/bin/bash
# remind me, its important!
# usage: remme


Usage is easy..

> remme 50m Change laundry

In 50 minutes I will get a pop-up notification using Gnome's libnotify on my desktop reminding me to change the load. Woo!



> remme @17:30 Wake mom up for dinner.

At 5:30pm I will get a pop-up reminding me that mom wants to be woken up so we can get dinner.

The message displays for 5 seconds by default. You can tweak this script using the different options from notify-send, either hit up the man page or google will get you where you want to go.

Remind
Problem: Mom says, 'I signed your little sis up for Driver's Ed next month, from the 1st to the 19th, you'll have to pick her up those days at 5pm.' This is the middle of October, guaranteed come Nov 1st I'll be sitting at home wondering where my sister is.

Solution: The grandaddy of your complex gui based scheduling software. A simple program called 'remind'. In conjunction with the above mentioned notify-send and conky, I'll be there at Nov 1st @ 4:55pm waiting to get her.

Remind wants you to put all of your reminders in a text file that it will parse and generate reminders for you, but it expects you to be smart enough to either ask for your reminders (on the command line) or to redirect it's output into something you can use.

Tools

> sudo apt-get install remind libnotify-bin conky


First, lets set up remind with a few reminders. I use a ~/.reminders file to store most of my reminders, here's a sample:

;Misc.
REM 1 Nov 2010 *1 UNTIL 19 Nov 2010 OMIT Sat Sun AT 16:55 +20 MSG %"Pick up Anna from Driver's Ed%" [t()]
REM Sun AT 10:00 +15 MSG %"Take Anna to Academic Decathlon%" [t()]
REM Sun AT 12:00 +10 MSG %"Pick up Anna from Academic Decathlon%" [t()]

;Barn
REM Mon Wed Fri Sat SKIP AT 9:30 +10 MSG Go to the %"Barn%" [t()]

;Cleaning schedule
REM Tue MSG Pick-up, vacuum and dust room
REM Thu MSG Do Laundry
REM 12 Oct 2010 *28 MSG Clean desktop
REM Mon AFTER MSG Garbage Day

;Daily reminders, only in daemon mode
IF $Daemon > 0
REM AT 23:00 MSG Go to bed!
ENDIF

The language is fairly straightforward once you've gotten the idea, REM lines are reminders, you can specify recurring reminders, on varying and sometimes very complex schedules. You can read in the man page, and at some excellent articles on 43folders.org about more ways to set up your .reminders file.

Next, I want timed reminders (such as Take Anna to Academic Decathlon scheduled AT 10:00) to pop-up on my desktop.
I set this up using notify-send again. I need to start remind in daemon mode when my desktop starts up, so that it will wake up and tell me about my reminders. In System > Preferences > Startup Applications I tell it to add a new application with the following parameters:

Name: Remind Notifications
Command: remind -z -k'notify-send --icon=dialog-information "Reminder" %s &' ~/.reminders &
Comment: Tell remind to run a daemon that will notify of timed reminders

Awesome, but what about those things that arn't timed? I could Do Laundry any time on Thursday, as long as it gets done. For that I tell conky to display my reminders for the day on my desktop. That way it's always available at a glance.

Before you do this part, make sure you've got conky running on your machine. I'll provide some more details, and screengrabs below on how I set up conky.

This takes a bit more work, and some more editing of text files. First I need a script that will clean up my reminders a bit to look nicer in conky, I called this reminders.sh and put it in ~/.conky

#!/bin/bash
# reminders.sh
# copyright 2010 by Mobilediesel
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.

#reminders=$(remind -h | fold -sw55 | sed -e "s/.*(today):/\${color grey}&\${color 99ccff}/" -e '/^$/d')
reminders=$(remind -q -r ~/.reminders | fold -sw55 | sed -e "/.*(today):/d" -e '/^$/d')
echo "$reminders"

As you can see I tweaked Mobilediesel's original script a bit[1], I left it commented-out but I never did manage to make it work properly, so if you'd like to change things, you're best off modifying off the second version. For completeness sake, fold makes the lines wrap instead of run off the edge of conky, and sed is removing the first banner bit from the remind output, and taking out any extraneous blank lines.

Then I insert the following into my .conkyrc file:
${execi 30 ~/.conky/reminders.sh}

Now like magic, conky displays a list of todays reminders right on my desktop. Sweet!

Taskwarrior
Problem: I'm getting started doing web development and I have my first project, my client, being a bit disorganized sends me things he wants me to do at random intervals, sometimes in email, sometimes on the phone, sometimes by telepathy it seems (or he tries, I don't usually get those.) I've tried to corral things as best I can, but not everyone tries to be as organized as me.

Solution: Lightning fast task manager available with a few key presses any time I'm near the computer, which shows me the things I have yet to complete right on my desktop.

Tools

> sudo apt-get install task conky


I love using task, it's fast, it's intuitive to use and it's very flexible. Here's how it looks on the command line.

Again, make sure you've got conky running first. Then we will tweak the .taskrc file to tell it how we want our tasks displayed in conky, use another short bash script to clean up the output a little more and then tell conky to display our tasks.

First we need to add the following to our .taskrc file, we're going to make use of the shadowfile feature, afaik task will only make ONE shadowfile at a time, so if you happen to be already using it, and using that shadowfile, you're gonna have to change something to make this work. Anyway, onward!

In ~/.taskrc we modify one section and add another.
You will need to find this section and modify it like so:

#Terminal
defaultwidth=200 # Without ncurses, assumed width, make this large or it will wrap in the shadowfile and look strange in conky
....
# Shadow file support
shadow.file=/tmp/shadow.txt # Location of shadow file
shadow.command=conky # Task command for shadow file
#shadow.notify=on # Footnote when updated

Then add the following to the bottom:

# task conky
report.conky.description=Shows the newest tasks
report.conky.columns=due,project,priority,description
report.conky.labels=
report.conky.sort=project+,priority-,due+
report.conky.filter=status:pending limit:10
report.conky.dateformat=m/d
report.conky.annotations=none

You can modify the columns however you like, but remember you can't sort by a column that you're not displaying. You could also modify it to display more than 10 tasks at a time with the limit option.

So that gets you the start of your output for screen, you can test it by running 'task conky' on your command line.

Next we use another bash script that will read in our shadowfile and clean it up a bit. I named mine taskconky.sh and threw it in ~/.conky with the rest. It looks like this:

#!/bin/bash
# CONKY Task Manager

width=55
shortwidth=$(( $width - 3 ))

# Set the field seperator to a newline
IFS="
"

# Loop through the file
linenum=0
for line in `cat $1`;do
linenum=$(( $linenum + 1 ))
# echo $linenum
if [ $linenum -gt 2 ] ; then
count=`echo $line |wc -c`
# echo $count
if [ $count -gt $width ]; then
temp=${line:0:$shortwidth}
echo $temp...
elif [ $count -lt $width ]; then
echo $line
fi
else
temp=${line:0:$width}
echo $temp
fi
done

You can tweak the width variable to make it look nice with your conky. I tend to write long tasks so shorter than 55 or so makes it kinda useless to figure out what I should be doing.

Finally we tell conky how to put it all together by adding the following to our .conkyrc file.
${exec ~/.conky/taskconky.sh /tmp/shadow.txt}

In the end here's how my conky looks:



See my whole desktop.
A Gist with all of the code. Including my full .conkyrc

Resources

You might also like Wyrd for helping to manage your .reminders
I use Guake and screen with screeninator to give me quick easy access to programs I use often like task.


*Note: Feedback, modifications, suggestions etc. gladly accepted. Please feel free to modify to your heart's satisfaction and give us a tour around your setup. I'm always on the lookout for tweaks and new ideas.

[1] ETA: Modified the reminders.sh script, it needs to call remind with the -q and -r flags (-q to tell it not to queue timed reminders which crashes conky D: and -r to tell it to not run RUN directives, which causes other problems.)
kerravonsen: Soolin with a half-smile: impress me (Soolin)

[personal profile] kerravonsen 2010-10-18 01:57 am (UTC)(link)
I love how one can customize things so much with Linux. Your needs are not my needs, so I've done things a bit differently. But I use taskwarrior too.
kerravonsen: Yin-Yang symbol, black and rainbow-sparkles (yin-yang)

[personal profile] kerravonsen 2010-10-18 02:39 am (UTC)(link)
I've written myself a few scripts to integrate it with IkiWiki, so that I can use it as a combined task manager and sort of mindmap for projects. That is, each project has a wiki page, where I can write notes about the project, add links to useful references, etc. The scripts are used to list the tasks for the project on the project page, by using a few other IkiWiki plugins.

For the GTD system, I use taskwarrior's tags as GTD contexts. So I have tags like "phone", "shop", "home", "code", "internet" etc.

Aside from that, I've divided my tasks into three types, each one with a different alias which uses a different taskrc file.
1. ordinary tasks (no alias, just use "task")
2. writing tasks (aliased to "writing")
3. reading list (aliases to "reading")

The reason I split them is that I realized that I had so many writing projects that it was better to treat them separately, and once I'd set up things for that, I realized that I could also use task to keep track of my reading.

I was already doing a reading list on my site, but I kept on forgetting to keep it up to date. Treading my reading list as a set of tasks with taskwarrior made it a lot easier to keep updated. Buy/borrow a new book -> add a new task. Start reading a book -> mark the task as started. Finish reading a book -> mark the task as done. With the reading list, each book is a project; that allows for re-reading books, which is half the reason for buying them. Then I can see what books I've read by going "reading complete", and what books I've yet to read by just going "reading". Hmmm, I wonder if I should use tags on the reading list to tag books by genre, since there's no point in doing GTD contexts for reading, since they would all have the same context: reading! Yes, I think I'll do that. That will help me look for what book to read next, depending on what mood I'm in. Look, you say? Well, there's 199 tasks on my reading list...

Edited 2010-10-18 02:41 (UTC)
vass: A sepia-toned line-drawing of a man in naval uniform dancing a hornpipe, his crotch prominent (Default)

[personal profile] vass 2010-10-18 05:21 am (UTC)(link)
OMG I LOVE YOU. You're making me wish my netbook used Linux. My desktop runs Ubuntu, but most of my time-wasting is done on the couch with the XP netbook.
skuf: Ubuntu Danmark logo (Ubuntu)

[personal profile] skuf 2010-10-18 04:11 pm (UTC)(link)
You lost me at "Lets make our bash script", since I've yet to learn making those, but the timed reminder seems cool. Hi, Sam!
altarwise: (Default)

[personal profile] altarwise 2010-10-18 06:52 pm (UTC)(link)
I admit, I use a web app for most of my task managing because it's easier to sync when dual-booting and computer hopping (and I use a tiling wm on my Arch box, so I don't bother with any big conky config I'll probably never see), but that little reminder script is very simple and very nifty. I'd never thought to use notify-send like that before.