From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tony McC Subject: GtD with org-mode and a Palm PDA Date: Sat, 27 Mar 2010 20:08:00 +0000 Message-ID: <20100327200800.146e41a5@elena.home> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NvcIm-00061B-8N for emacs-orgmode@gnu.org; Sat, 27 Mar 2010 16:08:12 -0400 Received: from [140.186.70.92] (port=54186 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NvcIk-000605-4l for emacs-orgmode@gnu.org; Sat, 27 Mar 2010 16:08:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1NvcIh-0007NV-35 for emacs-orgmode@gnu.org; Sat, 27 Mar 2010 16:08:09 -0400 Received: from smtp817.mail.ukl.yahoo.com ([217.12.12.246]:46017) by eggs.gnu.org with smtp (Exim 4.69) (envelope-from ) id 1NvcIg-0007NF-Ms for emacs-orgmode@gnu.org; Sat, 27 Mar 2010 16:08:07 -0400 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org 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