Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

ToDo Manager

by alexbio (Monk)
on Jun 03, 2010 at 19:31 UTC ( #842982=CUFP: print w/replies, xml ) Need Help??

Hello everyone. I want to share with you a small script I wrote days ago that I use to manage a plain-text ToDo list.

The usage is IMHO very simple and it is fully documented in the POD section. Just use perldoc.

Despite it was initially written for Unix like environments it works quite well also under Windows (it is all a matter of file management).

Hope you'll find it useful.

#!/usr/bin/perl # Simple command-line todo list manager. # # Copyright 2010 Alessandro Ghedini <> # -------------------------------------------------------------- # "THE BEER-WARE LICENSE" (Revision 42): # Alessandro Ghedini wrote this file. As long as you retain this # notice you can do whatever you want with this stuff. If we # meet some day, and you think this stuff is worth it, you can # buy me a beer in return. # -------------------------------------------------------------- use strict; die "For info type 'perldoc $0'\n" unless $#ARGV >= 0; my ($default_todo, $default_done); if ($^O eq 'MSWin32') { $default_todo = $ENV{USERPROFILE}."\\todo.txt"; $default_done = $ENV{USERPROFILE}."\\done.txt"; } else { $default_todo = $ENV{HOME}."/.todo"; $default_done = $ENV{HOME}."/.done"; } my $todo_file = $ENV{TODO_FILE} ne "" ? $ENV{TODO_FILE} : $default_tod +o; my $done_file = $ENV{DONE_FILE} ne "" ? $ENV{DONE_FILE} : $default_don +e; if (!(-e $todo_file)) { open(TODO_FILE, ">$todo_file") or die("Cannot create '$todo_file'. Check TODO_FILE and DONE_FILE + env variables."); close TODO_FILE; } if (!(-e $done_file)) { open(DONE_FILE, ">$done_file") or die("Cannot create '$done_file'. Check TODO_FILE and DONE_FILE + env variables."); close DONE_FILE; } my $action = $ARGV[0]; if ($action eq 'add') { splice @ARGV, 0, 1; my $msg = join ' ', @ARGV; my $txt = $msg." {".time()."}"; append_file($todo_file, $txt); print "Added new task.\n"; } elsif ($action eq 'rm') { my $id = $ARGV[1]; my @data = read_file($todo_file); splice(@data, $id-1, 1); write_file($todo_file, \@data); print "Removed task number ".$id.".\n"; } elsif ($action eq 'ls') { my $grep = $ARGV[1] ne "" ? $ARGV[1] : "(.*?)"; my @data = read_file($todo_file); print_tasks($grep, @data); } elsif ($action eq 'do') { my $id = $ARGV[1]; my @data = read_file($todo_file); my $done = $data[$id-1]; splice(@data, $id-1, 1); write_file($todo_file, \@data); chomp $done; append_file($done_file, $done); print "Task number $id marked as done and moved to $done_file.\n"; } elsif ($action eq 'ed') { my $id = $ARGV[1]; splice @ARGV, 0, 2; my $msg = join ' ', @ARGV; my @data = read_file($todo_file); $data[$id-1] = $msg." {".time()."}\n"; write_file($todo_file, \@data); print "Task number $id successfully replaced.\n"; } elsif ($action eq 'mv') { my $id = $ARGV[1]; my $new_pos = $ARGV[2]; my @data = read_file($todo_file); my $tmp = $data[$new_pos-1]; $data[$new_pos-1] = $data[$id-1]; $data[$id-1] = $tmp; write_file($todo_file, \@data); } elsif ($action eq 'done') { my $grep = $ARGV[1] ne "" ? $ARGV[1] : "(.*?)"; my @data = read_file($done_file); print_tasks($grep, @data); } else { print "ERROR: Invalid action '$action'.\n"; print "Type 'perldoc $0' for manual\n"; } sub print_tasks { my $grep = shift; my @tasks = @_; my $i = 0; foreach my $task(@tasks) { $i++; next unless $task =~ m/$grep/; $task =~ m/{(.*?)}/; my $rel_time = relative_time($1); $task =~ s/\{$1\}/\ ($rel_time\)/g; print $i." ".$task; } } sub read_file { my $file = shift; open(FILE, "<$file") or die("Cannot open $file in read mode.\n"); my @data = <FILE>; close(FILE); return @data; } sub write_file { my $file = shift; my $data_ref = shift; open(FILE, ">$file") or die("Cannot open $file in write mode.\n"); print FILE @$data_ref; close(FILE); } sub append_file { my $file = shift; my $data = shift; open(FILE, ">>$file") or die("Cannot open $file in append mode.\n" +); print FILE $data."\n"; close(FILE); } sub relative_time { my $time_value = shift; my $now = time(); my $delta = $now - $time_value; if($delta < 60) { return 'less than a minute ago'; } elsif($delta < 120) { return 'about a minute ago'; } elsif($delta < (45*60)) { return int($delta / 60) . ' minutes ago'; } elsif($delta < (90*60)) { return 'about an hour ago'; } elsif($delta < (24*60*60)) { return 'about ' . int($delta / 3600) . ' hours ago'; } elsif($delta < (48*60*60)) { return '1 day ago'; } else { return int($delta / 86400) . ' days ago'; } } __END__ =head1 NAME ToDo - A simple command-line todo list manager. =head1 USAGE B<ToDo> I<ACTION> I<ARGS> =head1 ACTIONS =over =item B<add SOME TEXT @LIST> Add a task to your todo list. List notation optional. =item B<rm NUMBER> Remove task on line NUMBER from your todo list. =item B<ls TERM> Show tasks that contain TERM. If no TERM specified, the entire list is showed. =item B<done TERM> As ls but for already done tasks. =item B<do NUMBER> Mark the task on line NUMBER as done. It moves the task from todo file to done file. =item B<ed NUMBER "Some text"> Replace the task on line NUMBER with the text given. =item B<mv NUMBER POSITION> Move the task on line NUMBER to line POSITION and the task on POSITION to NUMBER. =back =head1 CONFIGURATION Set TODO_FILE and DONE_FILE environment variables, to your todo and do +ne files locations. Defaults ~/.todo and ~/.done. =cut
Alex's Log -

Replies are listed 'Best First'.
Re: ToDo Manager
by Anonymous Monk on Jun 04, 2010 at 03:30 UTC

      thanks for sharing ....could plz provide some discription about this script like wat this script will do? and how it works?....great work .once again thanks for sharing

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://842982]
Approved by lostjimmy
Front-paged by Arunbear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (6)
As of 2018-02-19 08:45 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (260 votes). Check out past polls.