#!/usr/bin/env python

# Copyright 2009 (C) Pierre Duquesne <stackp@online.fr>
# Licensed under the BSD Revised License.

import imaplib
import smtplib
import sys
import optparse
import getpass
import email.parser

USAGE="imapfwd [options] USERNAME IMAPHOST SMTPHOST DESTINATION" 

def parse_args():
    "Parse command-line arguments."
    parser = optparse.OptionParser(usage=USAGE)
    parser.add_option('--pass', dest='password', default=None,
                      help="imap password")
    parser.add_option('-p', dest='port', type='int', default=None,
                      help="imap port")
    parser.add_option('--ssl', dest='ssl', default=False, 
                      action='store_true',
                      help="use SSL for imap")
    parser.add_option('--prefix', dest='prefix', default=None, 
                      action='store',
                      help="append a string to subject. ex: [box1]")
    options, remainder = parser.parse_args(sys.argv[1:])
    return options, remainder

options, args = parse_args()
try:
    username = args[0]
    imaphost = args[1]
    smtphost = args[2]
    destination = args[3]
except:
    print "Error: some arguments are missing. Try --help."
    print USAGE
    sys.exit(1)

# connect to imap
print 'Connecting to %s as user %s ...' % (imaphost, username)
if options.ssl: 
    IMAP = imaplib.IMAP4_SSL
else:
    IMAP = imaplib.IMAP4
try:
    if options.port:  
        imap_server = IMAP(imaphost, options.port)
    else:     
        imap_server = IMAP(imaphost)
    if not options.password: 
        options.password = getpass.getpass()
    imap_server.login(username, options.password)
except Exception,e:
        print 'Error:', e;  sys.exit(1)

# connect to smtp
try:
    smtp_server = smtplib.SMTP(smtphost)
except Exception, e:
    print 'Could not connect to', smtphost, e.__class__, e
    sys.exit(2)

# filter unseen messages
imap_server.select("INBOX")
resp, items = imap_server.search(None, "UNSEEN")
numbers = items[0].split()

# forward each message
sender = "%s@%s" % (username, imaphost)
for num in numbers:
    resp, data = imap_server.fetch(num, "(RFC822)")
    text = data[0][1]
    if options.prefix:
        parser = email.parser.HeaderParser()
        msg = parser.parsestr(text)
        msg['Subject'] = options.prefix + msg['Subject']
        text = msg.as_string()
    smtp_server.sendmail(sender, destination, text)
    # Flag message as Seen (may have already been done by the server anyway)
    imap_server.store(num, '+FLAGS', '\\Seen')

imap_server.close()
smtp_server.quit()
