Tue Jan 29 17:00:44 IST 2008

Date::Manip, remind and remindme

I use remind(short howto) to keep my calendar of events and reminders. Its a wonderful utility - and all commandline. I split up the birthdays, anniversaries, personally important days, and the usual stuff into different files, and include them in my ~/.reminders file. Here's what my .reminders looks like :

gera@gera-laptop:~$ cat .reminders 
include /home/gera/reminders/birthdays
include /home/gera/reminders/anniversaries
include /home/gera/reminders/impdates
include /home/gera/reminders/stuff

All this works well, except for a small issue. It takes too much time for me to add reminders for my day-to-day tasks. Firing up an editor and typing all that remind syntax is something that can be avoided. Also, it really hurts to look at the calendar to figure out fuzzy dates like "tomorrow", or "sat". I was planning to write this big Perl script which would do the heavy lifting for me. Instead, I found Date::Manip which already does the heavy lifting. It understands stuff like "tomorrow" and "sun". I just needed a small 'remindme' script then :

#!/usr/bin/perl -w
use strict;

use Date::Manip;
use Fcntl qw(:flock);

my $reminders = "$ENV{HOME}/reminders/stuff";

my $argstring = join (" ", @ARGV);
my ($when, $what);

(undef, $when, $what) = ($argstring =~ /^(on |)(.*?) to (.*)$/);
quit("what?") unless $what;
quit("when?") unless $when;

# form the line to be appended
my $date = ParseDate($when);
quit("cannot parse date") unless $date;

my $line = UnixDate($date, "REM %b %e %Y +1 MSG");
$line .= " $what %b.%\n";

# write in file

# open lock file
open LOCK, ">$reminders.lock" or quit("cannot open $reminders.lock : $!");
flock LOCK, LOCK_EX or quit("cannot obtain lock : $!");

# open data file, write and close data file
open REMINDERS, ">>$reminders" or quit("cannot open $reminders : $!");
print REMINDERS $line;
close REMINDERS;

# release locks
flock LOCK, LOCK_UN;
close LOCK;

exit (0);

sub quit
{
        my $msg = shift;
        print STDERR $msg, "\n";
        exit (-1);
}

Now, I can use it like this :

$ remindme on sat to eat everything I can
$ remindme tomorrow to pay the phone bill
$ remindme next week to think up of something useful to say
$ remindme next thursday to find something better to do

nifty, eh?

update: bugfixed the script. An extra space creeped up between the '+' and the '1'. Thanks to AmitU for pointing that out.
update 2: added the capability to get reminded n days in advance - a feature suggested by AmitU in the comments, but with a different syntax ("remindme next week to do this for 2 days"). Also, remindme's git repository and home page. The repository contains the bash-completion script as well.


Posted by gera | Permanent Link | Categories: tricks, perl, code | [ 5 ]