emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* GtD with org-mode and a Palm PDA
@ 2010-03-27 20:08 Tony McC
  2010-03-28 18:47 ` Łukasz Stelmach
  0 siblings, 1 reply; 2+ messages in thread
From: Tony McC @ 2010-03-27 20:08 UTC (permalink / raw)
  To: Org Mode

Dear org-moders,

I use org-mode for lots of things and love it.  Recently I have been
using it more for implementing David Allen's Getting Things Done and
have written a couple of perl scripts and a supporting shell script to
facilitate this.  I hope they might be of use to others.

I normally work at my desktop computer and when inputs arrive or things
occur to me that I'm going to have to deal with I just use org-remember
to put them into an inbox.org file.  However, I also work in other
places and keep a Palm TX with me.  I use "Slap" on the Palm to enter
similar quick thoughts and pass them to the Memos database, where I
give them a category of "Inbox".  I sync my palm with the desktop
using JPilot and then the palm2org.pl perl script moves these Inbox
memos to the end of my inbox.org file on the desktop as a preliminary
step in my weekly GtD review.  During the week I also use the ToDo list
on my Palm to decide what to work on next, checking off ToDos as they
are completed.  The same script uses these completed ToDos to
change the TODOs in my projects.org file to DONE - again, this is a
first step in my review.

I then perform my weekly review, going through projects.org and
identifying next actions, which I then toggle as TODOs and assign
tags which will become GtD contexts for the tasks (e.g. @Library,
Phone, Email etc.)  

After completing the review, the second perl script org2palm.pl uses
the list of TODOs in my projects.org to rebuild the ToDo list on the
Palm TX.  It also clears all memos from the Inbox category on the palm,
since these have now been incorporated into projects.org.  Running this
perl script as part of the org2palm shell script completes the process
by uploading the updated ToDos and Memos lists to the Palm.

I also use the Palm calendar of course, but I enter items there by
hand, so have not felt a need to automate that process.

I have pasted the scripts below rather than adding them as
attachments.  

I am happy for others to use or modify the scripts as they wish (I am
no expert perl or shell programmer and no doubt many people can think of
improvements).  I have only tested and used them on FreeBSD using
JPilot and pilot-xfer to sync the Palm TX and desktop.  I imagine they
would work about the same on Linux.  Some of the paths at the start of
the scripts would need modifying for use on Windows and the shell
script would need to be replaced by a batch file, but I don't imagine
those modifications would be too difficult. 

I hope this is of some use, I have certainly found the process helpful
in my own work.

Tony


P.S. I know Palm devices are old fashioned now, but as long as my TX
works I have no desire to use anything else and I guess there are other
orgers in a similar position.

---------------------- 
palm2org.pl:

#!/usr/bin/perl
# palm2org
############################################################
# Use the Palm ToDo list to check off completed tasks in org
# This should be run after syncing palm with jpilot and before
# the weekly GtD review.
# Also import Palm Memos in the "Inbox" category and append
# them to the org-mode inbox.org file.  These memos are
# used for collecting inputs during the week.  Once
# transferred to org-mode the program org2palm can be used
# to clear them on the palm (org2palm should be run *after*
# a GtD weekly review.
############################################################
use strict;
use warnings;
use autodie;
use File::Copy;
use Palm::ToDo;
use Palm::StdAppInfo;

# Locations of the relevant files
my $palmdir = "$ENV{HOME}/.jpilot";
my $tododb = "$palmdir/ToDoDB.pdb";
my $memodb = "$palmdir/MemosDB-PMem.pdb";
my $orgdir = "$ENV{HOME}/org";
my $projects = "$orgdir/projects.org";
my $inbox = "$orgdir/inbox.org";
my $backup_projects = "$orgdir/projects.bak";
my $backup_inbox = "$orgdir/inbox.bak";

############################################################
# Mark completed ToDos in projects.org

# Does the org projects file need to be updated?
my $savenew = 0;

# Read the existing org projects list into an array
open(my $fh, '<', $projects);
my @orglines = <$fh>;
close($fh);

# Load the Palm ToDo database
my $pdb = new Palm::PDB;
$pdb->Load($tododb);

# Use ToDos marked completed to update the org projects lines
my @records = @{$pdb->{records}};
foreach my $record (@records) {
  if ($record->{completed}) {
    my $description = $record->{description};

    # Find this record in the projects list and change TODO to DONE
    foreach my $i (0..$#orglines) {
      if ($orglines[$i] =~ /^\*+\sTODO\s+$description/ ||
          $orglines[$i] =~ /^\*+\sTODO\s\[#[A-C]\]\s+$description/) {
        $orglines[$i] =~ s/TODO/DONE/;
        $savenew++;
      }
    }
  }
}

# Update the org projects file if necessary, saving a backup
if ($savenew) {
  copy($projects, $backup_projects);
  open(my $fh, '>', $projects);
  foreach my $orgline (@orglines) {
    print $fh $orgline;
  }
  close($fh);
  print "$savenew task";
  if ($savenew > 1) {
    print "s were";
  }
  else {
    print " was";
  }
  print " marked as completed.\n";
}


############################################################
# Import inbox memos to inbox.org

# Load the Palm Memos database
$pdb->Load($memodb);

# Which category corresponds to "Inbox"?
my @categories = @{$pdb->{appinfo}{categories}};
my $inbox_id;
for my $i (0..15) {
  if ($categories[$i]->{name} eq 'Inbox') {
    $inbox_id = $i;
    last;
  }
}


# Scan through the Memos and use those in Inbox category to
# append new items to a list of memo descriptions and notes.
my @memos = ();                 # List of memo contents

my $append = 0;                 # No. of memos to append to inbox

for my $record (@{$pdb->{records}}) {
  if ($record->{category} == $inbox_id) {
    push @memos, $record->{data};
    $append++;
  }
}

# Append these items to the inbox.org file (if there are any)
# saving a backup of the file.
if ($append) {
  copy($inbox, $backup_inbox);
  open(my $fh, '>>', $inbox);
  for my $i (0..$#memos) {
    print $fh "\n** $memos[$i]\n";
  }
  close($fh);

  print "$append memo";
  if ($append > 1) {
    print "s were";
  } else {
    print " was";
  }
  print " move to the inbox.\n";
}


--------------
org2palm.pl:

#!/usr/bin/perl
# org2palm
############################################################
# Extract ToDo items from the org projects file and use them
# to build the Palm ToDo list.
# Also clear memos from the Palm Memos database that are in
# the "Inbox" category since these have already been copied
# to the inbox.org file.
# This should be run after a weekly GtD review and the new
# ToDo database should be uploaded to the palm using:
# pilot-xfer -p /dev/cuaU0 -i ToDoDB.pdb MemosDB-PMem.pdb
############################################################

use strict;
use warnings;
use autodie;
use Palm::ToDo;
use Palm::Memo;
use Palm::StdAppInfo;
use Palm::PDB;
use File::Copy;

# Locations of the relevant files
my $palmdir = "$ENV{HOME}/.jpilot";
my $tododb = "$palmdir/ToDoDB.pdb";
my $memodb = "$palmdir/MemosDB-PMem.pdb";
my $backup_todos = "$palmdir/ToDoDB.bak";
my $backup_memos = "$palmdir/MemosDB-PMem.bak";
my $projects = "$ENV{HOME}/org/projects.org";


############################################################
# Updating Palm ToDo list from org-mode TODOs

# org-mode uses priority cookies A, B, or C
# This hash maps them to PalmOS task priorities
my %priority_cookies = ('A' => 1, 'B' => 2, 'C' => 3);

my $todopdb = new Palm::ToDo;
$todopdb->Load($tododb);

# Get the list of categories for the Palm ToDo list
my @categories = @{$todopdb->{appinfo}{categories}};

# Keep lists of TODO descriptions, contexts and priorities
my @descriptions = ();
my @contexts = ();
my @priorities = ();


# Read the projects file to find TODO items
open(my $fh, '<', $projects);
while (<$fh>) {
  my $line = $_;
  my ($priority, $description, $context);

  # Skip this line unless it's a TODO
  next if $line !~ /^\*+\s+TODO/;

  if ($line =~ /^\*+\sTODO\s+\[#([A-C])\]\s+(.*)\s+:([A-Za-z_@]+):/) {
    # TODO heading with priority cookie
    ($description, $context) = ($2, $3);
    $priority = $priority_cookies{$1};
  } elsif ($line =~ /^\*+\sTODO\s+(.*)\s+:([A-Za-z_@]+):/) {
    # TODO heading without a priority cookie
    ($description, $context) = ($1, $2);
    $priority = 2;              # Default priority is medium
  } elsif ($line =~ /^\*+\sTODO\s+(.*)$/) {
    # TODO heading with description only
    $description = $1;
    $priority = 2;
    $context = 'Unfiled';
  }

  $description =~ s/\s+$//g;    # Strip trailing spaces

  push @descriptions, $description;
  push @contexts, $context;
  push @priorities, $priority;
}
close($fh);


# Create a new ToDo database, saving the old one
copy($tododb, $backup_todos);

# Delete all the existing ToDos
for my $record (@{$todopdb->{records}}) {
  $todopdb->delete_Record($record, 1);
}

# Create new ToDos using the descriptions, contexts and priorities
# gleaned from the projects file
my $task_count = @descriptions;

for my $i (0..$#descriptions) {
  my $record = $todopdb->new_Record;
  $record->{description} = $descriptions[$i];
  $record->{priority} = $priorities[$i];

  # Find the palm category corresponding to this context
  # Palm categories are stored in an array of 16 elements
  for my $j (0..15) {
    if ($todopdb->{appinfo}{categories}[$j]->{name} eq $contexts[$i]) {
      $record->{category} = $j;
    }
  }
  $todopdb->append_Record($record);
}

$todopdb->Write($tododb);
print "$task_count tasks were created\n";

############################################################
# Clear Inbox memos on Palm

my $memopdb = new Palm::Memo;
$memopdb->Load($memodb);

# Which category corresponds to "Inbox"?
@categories = @{$memopdb->{appinfo}{categories}};
my $inbox_id;
for my $i (0..15) {
  if ($categories[$i]->{name} eq 'Inbox') {
    $inbox_id = $i;
    last;
  }
}

my $deleted = 0;
for my $record (@{$memopdb->{records}}) {
  if ($record->{category} == $inbox_id) {
    $memopdb->delete_Record($record);
    $deleted++;
  }
}

if ($deleted) {
  copy($memodb, $backup_memos);
  $memopdb->Write($memodb);
  print "$deleted memo";
  if ($deleted > 1) {
    print "s were";
  } else {
    print " was";
  }
  print " removed from the Palm Inbox category\n";
}


-----------
org2palm shell script:

#!/bin/sh
# org2palm
# Create new Palm tasks database using org projects file
$HOME/perl/orgmode/org2palm.pl
echo Please press the HotSync button on the Palm TX...
/bin/sleep 5
/usr/local/bin/pilot-xfer -p /dev/cuaU0 -i $HOME/.jpilot/ToDoDB.pdb  \
				   $HOME/.jpilot/MemosDB-PMem.pdb

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-03-28 18:47 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-27 20:08 GtD with org-mode and a Palm PDA Tony McC
2010-03-28 18:47 ` Łukasz Stelmach

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).