I posted a reply in a lower thread that was buried, so I’ll re-post the script here. I’ve taken some ideas from the work previously mentioned here and refactored it a LOT to reduce the size and complexity of the code involved, and leveraged the use of upstream modules to do the heavy lifting for me.
Here is a simple script that allows you to email your Tasks to your tracks install, creating new entries and contexts and due dates at the same time (and yes, my code really IS shorter than my comments):
#!/usr/bin/perl
# _._
# /_ _`. (c) 2008, David A. Desrosiers
# (.(.)| setuid@gmail.com
# |\_/'|
# )____`\ Email-to-Tracks interface
# //_V _\ \
# (( | `(_) If you find this useful, please drop me
# / \> ' / \ an email, or send me bug reports if you find
# \ \.__./ / problems with it. I accept PayPal too! =-)
# `-' `-'
#
##############################################################################
#
# License
#
##############################################################################
#
# This script 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 2 of the License, or (at your option)
# any later version.
#
# The copyright notice must remain intact to remain in compliance with use.
#
# This script 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'll need to set this up as an alias in your MTA configuration (typically
# /etc/aliases), as follows:
#
# tracks@your-site.tld: "|/path/to/gtd-tracks-mail.pl"
#
# Don't forget to run newaliases(1) after you've modified this so it can
# update the aliases table with the new entry.
#
# Email format can be any of the following:
#
# Subject: The main description of the Task
#
# @Context
# 01/02/2003
# This is my note text
#
# or:
#
# Subject: Default Task description
#
# c: @context
# d: 2008/12/31
# n: The note text to insert
#
# Most valid date formats are accepted, and this will do its best to
# "correct" and normalize them. You can also prefix your lines with the
# modifiers above, or read the regexes below for more. For example:
# c:, context:, cxt:, con:, ct: are all valid prefixes for "context"
# n: and note: are all valid prefixes for "notes", and so on.
#
##############################################################################
use strict;
use warnings;
use XML::Simple;
use LWP::UserAgent;
use URI::Escape;
use Email::Abstract;
use Date::Manip;
use Date::Parse;
my $url = "http://your-site.tld/todos.xml";
my $contextUrl = "http://your-site.tld/contexts.xml";
# The default contextid where you want the Task added
# SELECT id,name FROM contexts;
my $contextid = "8";
my $user = "yourname";
my $password = "yourpass";
# Leave these tokens alone. They are valid as of Tracks 1.5 RESTful API.
my %todo = map { +($_ => "todo[$_]") } qw(notes context_id description due);
# Get the context legend in order to match by name
my $ua = new LWP::UserAgent;
my $req = new HTTP::Request 'GET',$contextUrl;
$req->authorization_basic($user,$password);
my $res = $ua->request($req);
my $contexts = XMLin($res->content);
# Split apart the email into Subject and Body
my $message = do { local $/; <STDIN> };
my $email = Email::Abstract->new($message);
my $subject = $email->get_header("Subject");
my $body = $email->get_body;
# These can probably be cleaned up a bit
my ($context_line) = $body =~ /^(?:c:|ct:|cxt:|con:|context:|@)\s*(.+)$/mi;
my ($date_line) = $body =~ /^(?:d:|date:)\s*(\d.*)$/m;
$date_line = UnixDate(ParseDate("today"), "%g") if (length($date_line) == 0);
my $time = str2time($date_line);
my $due_date = UnixDate(scalar gmtime($time), "%m/%d/%Y");
my ($note_line) = $body =~ /^(?:n:|note:)\s*(.*?)$/mi;
# Concatenate the data here before we send POST to the Tracks server
my $post_data =
$todo{'context_id'} . "=" . $contextid . "&" .
$todo{'description'}. "=" . uri_escape($subject) . "&" .
$todo{'notes'} . "=" . uri_escape($note_line) . "&" .
$todo{'due'} . "=" . uri_escape($due_date);
# Use LWP to do the posting ($ua was created earlier)
$req = new HTTP::Request 'POST',$url;
$req->content_type('application/x-www-form-urlencoded');
$req->content($post_data);
$req->authorization_basic($user,$password);
$res = $ua->request($req);
