#!/usr/bin/perl
#===============================================================================
#
# FILE: gtd.pl
#
# USAGE: ./gtd.pl
#
# DESCRIPTION: A desktop command line companion to mobileGTD on a s60 v3
# Symbian phone
#
# REQUIREMENTS: Perl
# AUTHOR: Daryn Hanright
# VERSION: 1.0
# CREATED: 16/01/09 15:12:18 NZDT
# REVISION: ---
#===============================================================================
# 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 .
use strict;
use warnings;
use Data::Dumper;
my $basedir = "/home/user/mobilegtd";
my $dir = "$basedir/\@Projects";
my %gtd = &readStuff;
my $stuffToDo = $ARGV[0];
my $whatToDo = $ARGV[1];
#$whatToDo = "[SOME TEXT] p:0 a:0 f:Poo s:+";
if (!$whatToDo) {
$whatToDo = "[] p: a: f: s:";
}
if (!$stuffToDo) {
$stuffToDo = "help";
}
my ($p) = $whatToDo =~ m@p:(.*?)(\s|$)@g;
my ($a) = $whatToDo =~ m@a:(.*?)(\s|$)@g;
my ($f) = $whatToDo =~ m@f:(.*?)(\s|$)@g;
my ($s) = $whatToDo =~ m@s:(.*?)(\s|$)@g;
my ($text) = $whatToDo =~ m@\[(.*?)\](\s|$)@g;
if ("list" =~ /^$stuffToDo$/i) { listProjects(); }
elsif ("la" =~ /^$stuffToDo$/i) { listProjectsWithActions(); }
elsif ("lp" =~ /^$stuffToDo$/i) { listProjectActions($p,$s);}
elsif ("status" =~ /^$stuffToDo$/i) { changeStatusAction($p,$a,$s); }
elsif ("addp" =~ /^$stuffToDo$/i) { addProject ($text); }
elsif ("add" =~ /^$stuffToDo$/i) { addActionToProject ($s,$text,$f,$p); }
elsif ("dela" =~ /^$stuffToDo$/i) { deleteAction ($p,$a); }
elsif ("delp" =~ /^$stuffToDo$/i) { deleteProject ($p); }
elsif ("proj" =~ /^$stuffToDo$/i) { projectProcess ($p,"\@Done"); }
elsif ("review" =~ /^$stuffToDo$/i) { projectProcess ($p,"\@Review"); }
elsif ("defer" =~ /^$stuffToDo$/i) { projectProcess ($p,"\@Someday"); }
elsif ("tickle" =~ /^$stuffToDo$/i) { projectProcess ($p,"\@Tickle"); }
elsif ("actoday" =~ /^$stuffToDo$/i) { actionToday ($p,$a,"\@Today"); }
elsif ("today" =~ /^$stuffToDo$/i) { whatsToday (); }
elsif ("dtoday" =~ /^$stuffToDo$/i) { doneToday ($a); }
elsif ("info" =~ /^$stuffToDo$/i) { addUpdateInfo ($p,$text); }
elsif ("folder" =~ /^$stuffToDo$/i) { changeActionFolder ($p,$a,$text); }
elsif ("projrn" =~ /^$stuffToDo$/i) { renameProject ($p,$text); }
elsif ("other" =~ /^$stuffToDo$/i) { otherStuff (); }
elsif ("act" =~ /^$stuffToDo$/i) { activateProject ($p); }
elsif ("help" =~ /^$stuffToDo$/i) { helpStuff(); }
else { helpStuff(); }
sub helpStuff {
print "A MobileGTD command line companion written in Perl\n";
print "By Daryn Hanright\n";
print "Usage: gtd.pl \"\"\n";
print "==================================================\n";
print "Options:\n";
print " list - list all projects\n";
print " la - list all projects with actions\n";
print " lp - list all actions for a given project - parameters: p\n";
print " status - change status of action in given project - parameters: p,a,s\n";
print " add - add action to project - parameters: [TEXT],a,f,s\n";
print " addp - add project - parameters: [TEXT]\n";
print " dela - delete action from given project - parameters: p,a\n";
print " delp - delete project - parameters: p\n";
print " proj - move project to \@Done - parameters: p\n";
print " review - move project to \@Review - parameters: p\n";
print " defer - move project to \@Someday - parameters: p\n";
print " tickle - move project to \@Tickle - parameters: p\n";
print " actoday - copy action to \@Today - parameters: p,a\n";
print " today - what actions am I doing today: p\n";
print " dtoday - action done today - parameters: a\n";
print " projrn - rename project - parameters: p,[TEXT]\n";
print " info - add/update info of project - parameters: p,[TEXT]\n";
print " other - list projects deferred, in review etc etc\n";
print " act - activate project from other - parameters: p\n";
print " folder - change folder of action in given project - parameters: p,a,[TEXT]\n";
print "\n";
print "parameters:\n";
print " p: - project number\n";
print " a: - action number\n";
print " s:+/-/! - status of project\n";
print " f: - folder of project\n";
print " [TEXT] - text to be added\n";
print "\n";
}
# TODO
sub whatsToday {
opendir (D1, "$basedir/\@Today");
my @f1 = readdir(D1);
closedir (D1);
my $i = 0;
foreach my $t1 (@f1) {
my ($matching) = $t1 =~ m@\.act$@g;
if ($matching) {
$t1 =~ s@.act@@g;
print "\[$i\] $t1\n";
$i++;
}
}
}
sub doneToday {
my ($actionPassed) = @_;
opendir (D1, "$basedir/\@Today");
my @f1 = readdir(D1);
closedir (D1);
my $i = 0;
foreach my $t1 (@f1) {
my ($matching) = $t1 =~ m@\.act$@g;
if ($matching) {
if ($actionPassed == $i) {
unlink ("$basedir/\@Today/$t1");
}
$i++;
}
}
}
sub otherStuff {
my @all = &getOtherStuff();
my $num = 0;
foreach my $files (@all) {
my ($matching) = $files =~ m@\.prj$@g;
if ($matching) {
my ($dir,$fileName) = split '\^',$files;
print "\[$num\] $dir - $fileName\n";
$num++;
}
}
}
sub activateProject {
my ($countPassed) = @_;
my @all = &getOtherStuff();
my $num = 0;
foreach my $files (@all) {
my ($matching) = $files =~ m@\.prj$@g;
if ($matching) {
my ($dirTemp,$fileName) = split '\^',$files;
if ($num == $countPassed) {
system ("mv $dir/$dirTemp/$fileName $dir");
}
$num++;
}
}
}
sub getOtherStuff {
opendir (D1, "$dir/\@Review");
my @f1 = readdir(D1);
closedir (D1);
my $i = 0;
foreach my $t1 (@f1) {
$f1[$i] = "\@Review^" . $t1;
$i++;
}
opendir (D2, "$dir/\@Done");
my @f2 = readdir(D2);
closedir (D2);
$i = 0;
foreach my $t2 (@f2) {
$f2[$i] = "\@Done^" . $t2;
$i++;
}
opendir (D3, "$dir/\@Someday");
my @f3 = readdir(D3);
closedir (D3);
$i = 0;
foreach my $t3 (@f3) {
$f3[$i] = "\@Someday^" . $t3;
$i++;
}
opendir (D4, "$dir/\@Tickle");
my @f4 = readdir(D4);
closedir (D4);
$i = 0;
foreach my $t4 (@f4) {
$f4[$i] = "\@Tickle^" . $t4;
$i++;
}
my @all = (@f1,@f2,@f3,@f4);
return @all;
}
sub readStuff {
opendir (DIR, $dir);
my @FILES = readdir(DIR);
closedir(DIR);
my %gtd = ();
my @gtdData = ();
my $i = 0;
foreach my $files (@FILES) {
my ($matching) = $files =~ m@\.prj$@g;
if ($matching) {
open (DAT, $dir."/".$files) || die ("Could not open file");
$files =~ s@\.prj@@g;
@gtdData=;
for ($i = 0; $i < @gtdData; $i++) {
my $data = $gtdData[$i];
my ($status) = $data =~ m@^[+-]\s+@g;
my ($folder) = $data =~ m@^[+-]\s+(.*?)\s+@g;
my $tempdata = $data;
$tempdata =~ s@^[+-]\s+@@g;
if ($folder) {
$tempdata =~ s@^$folder@@g;
}
$tempdata =~ s/^\s+//;
$tempdata =~ s/\s+$//;
if ($status) {
$status =~ s/^\s+//;
$status =~ s/\s+$//;
my ($testi) = $i =~ m@^\d$@;
if ($testi) {
$i = "0" . $i;
}
$gtd{$files}{$i}{"status"} = $status;
$gtd{$files}{$i}{"action"} = $tempdata;
$gtd{$files}{$i}{"folder"} = $folder;
} else {
$gtd{$files}{$i}{"do"} = $data;
}
}
close(DAT);
$i = 0;
}
}
return %gtd;
}
# list all projects
sub listProjects {
my $countProjects2 = 0;
print "======================================\n";
print "Current Projects\n";
while (my ( $key, $value ) = each(%gtd)) {
print "$countProjects2 - $key\n";
$countProjects2++;
}
print "\n";
}
sub addProject {
my ($title) = @_;
my $file = $dir . "/" . $title . ".prj";
open (DAT, ">$file") || die ("Could not open file");
print DAT "# DO: put desctiption of project here\n";
close(DAT);
}
sub renameProject {
my ($countPassed,$newProjectName) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
foreach my $key3 (sort (keys(%$project))) {
my $entryStatus = $project->{$key3}->{"status"};
my $entryAction = $project->{$key3}->{"action"};
my $entryFolder = $project->{$key3}->{"folder"};
if ($key3 == $countPassed) {
my $projFile = $dir."/".$newProjectName.".prj";
unlink ($dir."/".$projectName.".prj");
printProject($projFile, %$project);
printAction($entryStatus,$entryAction,$entryFolder,$newProjectName);
}
}
}
# list all projects with actions
sub listProjectsWithActions {
my $countProjects = 0;
while (my ( $key, $value ) = each(%gtd)) {
print "======================================\n";
print "$countProjects - $key\n";
foreach my $key3 (sort (keys(%$value))) {
my $entryStatus = $value->{$key3}->{"status"};
my $entryAction = $value->{$key3}->{"action"};
my $entryFolder = $value->{$key3}->{"folder"};
my $entryDo = $value->{$key3}->{"do"};
if ($entryDo) {
print "$entryDo";
} else {
print "\[$key3\] $entryStatus $entryAction $entryFolder\n";
}
}
print "\n";
$countProjects++;
}
}
# list given project with actions
# example - list project 0
sub listProjectActions {
my ($countPassed,$statusPassed) = @_;
if (!$statusPassed) {
$statusPassed = "all";
}
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
print "======================================\n";
print "Project: \[$countPassed\] $projectName\n";
foreach my $key3 (sort (keys(%$project))) {
my $entryStatus = $project->{$key3}->{"status"};
my $entryAction = $project->{$key3}->{"action"};
my $entryFolder = $project->{$key3}->{"folder"};
my $entryDo = $project->{$key3}->{"do"};
if ($entryDo) {
print "$entryDo";
} else {
if ($statusPassed eq $entryStatus) {
print "\[$key3\] $entryStatus $entryAction $entryFolder\n";
}
if ($statusPassed eq "all") {
print "\[$key3\] $entryStatus $entryAction $entryFolder\n";
}
}
}
print "======================================\n";
}
# change status of action within project
sub changeStatusAction {
my ($countPassed,$actionPassed,$actionChange) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
foreach my $key3 (sort (keys(%$project))) {
my $entryStatus = $project->{$key3}->{"status"};
my $entryAction = $project->{$key3}->{"action"};
my $entryFolder = $project->{$key3}->{"folder"};
if ($key3 == $actionPassed) {
my $projFile = $dir."/".$projectName.".prj";
$project->{$key3}->{"status"} = $actionChange;
printProject($projFile, %$project);
printAction($actionChange,$entryAction,$entryFolder,$projectName);
}
}
}
sub changeActionFolder {
my ($countPassed,$actionPassed,$folderChange) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
foreach my $key3 (sort (keys(%$project))) {
my $entryStatus = $project->{$key3}->{"status"};
my $entryAction = $project->{$key3}->{"action"};
my $entryFolder = $project->{$key3}->{"folder"};
if ($key3 == $actionPassed) {
my $projFile = $dir."/".$projectName.".prj";
my $oldFolder = $project->{$key3}->{"folder"};
$project->{$key3}->{"folder"} = $folderChange;
printProject($projFile, %$project);
if (-d $basedir . "/" . $folderChange) {
# print "everything cool";
} else {
mkdir $basedir . "/" . $folderChange or die;
}
$entryAction =~ s@ @\\ @g;
system ("mv " . $basedir . "/" . $oldFolder . "/" . $entryAction . ".act " . $basedir . "/" . $folderChange);
}
}
}
# delete action
sub deleteAction {
my ($countPassed,$actionPassed) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
foreach my $key3 (sort (keys(%$project))) {
my $entryStatus = $project->{$key3}->{"status"};
my $entryAction = $project->{$key3}->{"action"};
my $entryFolder = $project->{$key3}->{"folder"};
if ($key3 == $actionPassed) {
delete $project->{$key3};
my $projFile = $dir."/".$projectName.".prj";
printProject($projFile, %$project);
unlink ($basedir."/".$entryFolder."/".$entryAction.".act");
}
}
}
# delete project
sub deleteProject {
my ($countPassed) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
my $projFile = $dir."/".$projectName.".prj";
unlink ($projFile);
}
sub addUpdateInfo {
my ($countPassed, $info) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
my $projFile = $dir."/".$projectName.".prj";
my $data = '';
open (FILE, "<$projFile");
read FILE, $data, 100000;
close FILE;
open (FILE, ">$projFile");
my ($matchDO) = $data =~ m@^#\sDO:(.*)@g;
if ($matchDO) {
$data =~ s@$matchDO@ $info@g;
print FILE $data;
} else {
print FILE "# DO: " . $info . "\n" . $data;
}
close FILE;
}
sub projectProcess {
my ($countPassed,$folder) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
my $projFile = $dir."/".$projectName.".prj";
if (-d $dir . "/$folder") {
#print "everything good";
} else {
mkdir $dir . "/$folder" or die;
}
system ("mv $projFile $dir/$folder");
}
sub actionToday {
my ($countPassed, $actionPassed, $folder) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ($countPassed == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $project = $gtd{$projectName};
if (-d $basedir . "/$folder") {
#print "everything good";
} else {
mkdir $basedir . "/$folder" or die;
}
foreach my $key3 (sort (keys(%$project))) {
my $entryStatus = $project->{$key3}->{"status"};
my $entryAction = $project->{$key3}->{"action"};
my $entryFolder = $project->{$key3}->{"folder"};
$entryAction =~ s@ @\\ @g;
if ($key3 == $actionPassed) {
system ("cp $basedir/$entryFolder/$entryAction.act $basedir/$folder");
}
}
}
# print out project
sub printProject {
my ($passedFile, %passedGTD) = @_;
my $tempFile = $passedFile;
$tempFile =~ s@ @\\ @g;
#print "$passedFile";
#system ("cp $tempFile $tempFile.bak");
open (DAT, ">$passedFile") || die ("Could not open file");
foreach my $key3 (sort (keys(%passedGTD))) {
my $projStatus = $passedGTD{$key3}{"status"};
my $projAction = $passedGTD{$key3}{"action"};
my $projFolder = $passedGTD{$key3}{"folder"};
my $projDo = $passedGTD{$key3}{"do"};
if ($key3 == 0) {
print DAT "$projDo";
} else {
print DAT "$projStatus $projFolder $projAction\n";
}
}
close(DAT);
}
sub printAction {
my ($entrystatus,$entryaction,$entryfolder,$projectname) = @_;
#$entryaction =~ s@ @\\ @g;
my $file = $basedir . "/" . $entryfolder . "/" . $entryaction . ".act";
open (DAT, ">$file") || die ("Could not open file");
print DAT "$entrystatus $entryfolder $entryaction\n";
print DAT "Project: $projectname";
close(DAT);
}
sub addActionToProject {
my ($entrystatus,$entryaction,$entryfolder,$projectcount) = @_;
my $countProjects = 0;
my $projectName = '';
while (my $key = each(%gtd)) {
if ( $projectcount == $countProjects) {
$projectName = $key;
}
$countProjects++;
}
my $proj = $dir."/".$projectName.".prj";
my $file = $basedir . "/" . $entryfolder . "/" . $entryaction . ".act";
if (-d $basedir . "/" . $entryfolder) {
# print "everything cool";
} else {
mkdir $basedir . "/" . $entryfolder or die;
}
open (FILE, ">>$proj") || die ("Could not open file");
print FILE "$entrystatus $entryfolder $entryaction\n";
close(FILE);
open (DAT, ">$file") || die ("Could not open file");
print DAT "$entrystatus $entryfolder $entryaction\n";
print DAT "Project: $projectName";
close(DAT);
}