#! /usr/bin/env python

# (C) Olivier Berger 2001-2002
#
# This program 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.
# 
# This program 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 should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

# $Id: mailing.py,v 1.2 2002/02/09 23:04:38 olivier Exp $
#

# This program is used to mail a message to several recipients, thus
# providing customization for each recipient.

import sys, getopt, string, re
import smtplib, time

#
# displays usage of the program, then quit
#
def usage(returncode):
    print """SYNTAX:
    """, sys.argv[0], """ -t tofile -b bodyfile
    
    tofile   : sort of CSV file containing addresses of recipients
    bodyfile : template of the mail to be sent
    """
    sys.exit(returncode)


TOFILE = None
BODYFILE = None


# read the recipients file where values are separated by | characters
def read_recipients() :
    recipientfile = open(TOFILE)
    lines = recipientfile.readlines()
    return map(lambda line : line[:-1].split('|'), lines)


def read_body() :
    bodyfile = open(BODYFILE)
    body = ""
    for line in bodyfile.readlines() :
        body = body + line
    return body


def replace_values(bodytemplate, values) :
    body = bodytemplate

    for i in range(len(values)) :
        i = i+1
        pattern = "${{%02d}}" % i

        body = string.replace(body, pattern, values[i-1])

    return body


# patterns for header of the mail
FROMPATTERN = re.compile(r"^From: *(.*)")
SUBJECTPATTERN = re.compile(r"^Subject: *(.*)")
CCPATTERN = re.compile(r"^Cc: *(.*)")



def send_message(message, to) :

    lines = string.split(message, '\n')

    # identify headers in the template
    fromvalue = None
    subjectvalue = None
    ccvalue = None
    
    for line in lines :
        if not line :
            break

        frommatches = FROMPATTERN.match(line)
        subjectmatches = SUBJECTPATTERN.match(line)
        ccmatches = CCPATTERN.match(line)

        if frommatches :
            fromvalue = frommatches.group(1)
        if subjectmatches :
            subjectvalue = subjectmatches.group(1)
        if ccmatches :
            ccvalue = ccmatches.group(1)

    # lists all addresses to which the mail will be sent
    dests = [to]

    if ccvalue :
        dests.append(ccvalue)

    print "Sending : %s, from %s to %s, dests : %s" % (subjectvalue, fromvalue, dests[0], `dests`)

    # sending the mail to its recipients using the local mailer via SMTP
    server = smtplib.SMTP('localhost')
#    server.set_debuglevel(1)
    server.sendmail(fromvalue, dests, message)
    server.quit()



if __name__ == '__main__' :


    # handle options of the program
    try: 
        opts, args = getopt.getopt(sys.argv[1:], 't:b:')
    except getopt.error, msg:
        print "getopt error: %s" % msg
        usage(1)
        
    for name, value in opts:
        if name == '-t': TOFILE = value
        elif name == '-b': BODYFILE = value
        else:
            print "argument: ", name, " invalid"
            usage(1)

    if not TOFILE or not BODYFILE:
        usage(1)

    # read the recipients file
    sets = read_recipients()

    # read the template of the mail
    bodytemplate = read_body()

    # counter to be able to pause each 10 mails send
    counter = 0

    # send mail to each recipient
    for set in sets :
        
        values = set

        # the recipient is always in first column
        recipient = values[0]

        # replace substitution variables in the template for each recipient
        body = replace_values(bodytemplate, values)

        # send message
        send_message(body, recipient)

        # pause every 10 mails for 5 secs so that the MTA doesn't explode
	counter = counter + 1
	if counter >= 10 :
		counter = 0
		print "suspending execution for 5 secs"
		time.sleep(5)

