#!/usr/bin/env python

#
# Pipe an email through this script to get its content added as a
# task on Tracks GTD.
#
# Depends on httplib2: http://code.google.com/p/httplib2/

#
# Format of email message:
#
# Subject: My task name @context >project #tag1 #tag2
# Body: Add this as a note to the task
#

user = 'username'
password = 'password'
host = 'http://my.gtdify.com'

# Template used to upload tasks

todo_template = """<?xml version="1.0" encoding="UTF-8" ?>
<todo>
<description>%(description)s</description>
%(context)s
%(project)s
<notes>%(note)s</notes>
</todo>"""

import email
import sys
import base64

from httplib2 import Http
from urlparse import urljoin
from elementtree.ElementTree import parse
from StringIO import StringIO

base = urljoin(host, '/')

mail = email.message_from_file(sys.stdin)
subject = mail['Subject']
body = mail.get_payload()

title = []
project = None
context = None
tags = []

for word in subject.split():
    if word.startswith('>'):
        project = word[1:]
    elif word.startswith('@'):
        context = word[1:]
    elif word.startswith('#'):
        tags.append(word[1:])
    else:
        title.append(word)

title = ' '.join(title)

http = Http()
http.add_credentials(user, password)

def read(path):
    resp, contents = http.request(base + path, 'GET')
    return parse(StringIO(contents))

def post(path, data):
    return http.request(base + path, 'POST',
                        headers={'Content-Type': 'text/xml'},
                        body=data)

project_xml = read('projects.xml')
projects = [(p.find('name').text,
             p.find('id').text,
             p.find('default-context-id').text)

            for p in project_xml.findall('project')]

context_xml = read('contexts.xml')
contexts = [(c.find('name').text, c.find('id').text)
            for c in context_xml.findall('context')]

context_id = ''
if context:
    for c, c_id in contexts:
        if c.upper().startswith(context.upper()):
            context_id = c_id
            break

project_id = ''
if project:
    for p, p_id, c_id in projects:
        if p.upper().startswith(project.upper()):
            project_id = p_id
            context_id = context_id or c_id
	    break

if project_id:
    project_line = '<project-id>%s</project-id>' % project_id
else:
    project_line = ''

if context_id:
    context_line = '<context-id>%s</context-id>' % context_id
else:
    context_line = ''

resp, body = post('todos.xml', todo_template % {'description': title,
                                                'project': project_line,
                                                'context': context_line,
                                                'note': body})

if resp['status'] != '201':
    print "An error has occurred (%s): %s" % \
          (resp, body)
    sys.exit(-1)


