#!/usr/bin/python2
#
# Fetch unread messages from an IMAP inbox and add as tixi inbox entries

import imaplib
import ConfigParser
import os
import sys
import subprocess
import email
from email.header import decode_header
from datetime import datetime

now = datetime.now

def sync_tixi():
    subprocess.Popen(['tixi', '-s'])
    pass

def get_body(msg):
    maintype = msg.get_content_maintype()
    if maintype == 'multipart':
        for part in msg.get_payload():
            if part.get_content_maintype == 'text':
                return part.get_payload()
    elif maintype == 'text':
        return msg.get_payload()
    else:
        return None

# First, sync the tixi
sync_tixi()

# Read config
config = ConfigParser.ConfigParser()
config.read([os.path.expanduser('~/.tixisync')])
INDENT_BODY = '    '

# Connect to the IMAP server
if config.get('server', 'ssl'):
    connectfn = imaplib.IMAP4_SSL
else:
    connectfn = imaplib.IMAP4

trustedsenders = [a.strip() for a in config.get('user', 'trusted').split(',')]

M = connectfn(config.get('server', 'host'), config.get('server', 'port'))
M.login(config.get('account', 'username'), config.get('account', 'password'))

M.select('Inbox')
status, msgids = M.search(None, 'UNSEEN')

# For each unseen message, add a row to the Tixi inbox
for msgid in msgids[0].split():
    if not msgid:
        continue

    stat, data = M.fetch(msgid, '(RFC822)')
    if stat != 'OK':
        continue

    msg = email.message_from_string(data[0][1])
    sender = email.utils.parseaddr(msg['From'])[1]
    subject = msg['Subject']
    body = get_body(msg)

    if sender not in trustedsenders:
        print "ERROR: Untrusted sender:", msg['From'], " IGNORING"
        continue

    if body:
        body = body.strip().replace('\r', '')
        if body:
            body = '\n' + body
            body = body.replace('\n', '\n' + INDENT_BODY)
    else:
        body=''

    subparts = decode_header(subject)
    subject = ' '.join((s[0].decode(s[1]).encode('utf-8') if s[1] else s[0]) for s in subparts)

    if subject.lower().startswith('get '):
        # Return page to mailer
        filename = subject[4:]
        if os.path.relpath(filename).startswith(os.pardir):
            print "ERROR: Path outside tixi base directory requested"
            print subject, msg['From']
            # Exit with error to get alerts from cron
            sys.exit(1)

        print "Sending %s to %s" % (filename, sender)
        p1 = subprocess.Popen(['tixi', '-S', '-r', filename], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mail', '-S', 'encoding=quoted-printable', '-s', 'Tixi: ' + filename, sender], stdin=p1.stdout)
    else:
        output = subject + body
        print output
        subprocess.Popen(['tixi', '-S', '-i', output])
        subprocess.Popen(['tixi', '-S', '-a', 'diary/'+now().strftime('%Y-%m-%d'), 
                                            now().strftime('\n%H:%M: ') + output])

M.logout()

# ... and sync the tixi again
sync_tixi()
