Projet

Général

Profil

Demande #3419 » mailing.py

Frédéric Couchet, 07/11/2018 09:30

 
1
#! /usr/bin/env python
2

    
3
# (C) Olivier Berger 2001-2002
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
# 
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
# General Public License for more details.
14
# 
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18
# 02111-1307, USA.
19
#
20

    
21
# $Id: mailing.py 26584 2015-03-18 15:57:55Z fpoulain $
22
#
23

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

    
27
import sys, getopt, string, re
28
import smtplib, time
29
import quopri
30

    
31
#
32
# displays usage of the program, then quit
33
#
34
def usage(returncode):
35
    print """SYNTAX:
36
    """, sys.argv[0], """ -t tofile -b bodyfile
37
    
38
    tofile   : sort of CSV file containing addresses of recipients
39
    bodyfile : template of the mail to be sent
40
    """
41
    sys.exit(returncode)
42

    
43

    
44
TOFILE = None
45
BODYFILE = None
46

    
47

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

    
54

    
55
def read_body() :
56
    bodyfile = open(BODYFILE)
57
    body = ""
58
    for line in bodyfile.readlines() :
59
        body = body + line
60
    return body
61

    
62

    
63
def replace_values(bodytemplate, values) :
64
    body = bodytemplate
65

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

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

    
72
    return body
73

    
74

    
75
# patterns for header of the mail
76
FROMPATTERN = re.compile(r"^From: *(.*)")
77
SUBJECTPATTERN = re.compile(r"^Subject: *(.*)")
78
CCPATTERN = re.compile(r"^Cc: *(.*)")
79
BCCPATTERN = re.compile(r"^Bcc: *(.*)")
80

    
81
def qencode_subject (message):
82
    subjectmatches = re.search (r"^Subject: *(.*)$", message, re.MULTILINE)
83
    if (subjectmatches == None): return message
84
    subjectstr = subjectmatches.group(1)
85
    qsubjectstr= "=?UTF-8?Q?" + quopri.encodestring (subjectstr) + "?="
86
    qsubjectstr= qsubjectstr.replace ("=\n", "")
87
    return message.replace (subjectstr, qsubjectstr, 1)
88

    
89
def send_message(message, to) :
90

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

    
93
    # identify headers in the template
94
    fromvalue = None
95
    subjectvalue = None
96
    ccvalue = None
97
    bccvalue = None
98
    
99
    for line in lines :
100
        if not line :
101
            break
102

    
103
        frommatches = FROMPATTERN.match(line)
104
        subjectmatches = SUBJECTPATTERN.match(line)
105
        ccmatches = CCPATTERN.match(line)
106
        bccmatches = BCCPATTERN.match(line)
107

    
108
        if frommatches :
109
            fromvalue = frommatches.group(1)
110
        if subjectmatches :
111
            subjectvalue = subjectmatches.group(1)
112
        if ccmatches :
113
            ccvalue = ccmatches.group(1)
114
        if bccmatches :
115
            bccvalue = bccmatches.group(1)
116

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

    
120
    if ccvalue :
121
        dests.append(ccvalue)
122
    if bccvalue :
123
        dests.append(bccvalue)
124

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

    
127
    # sending the mail to its recipients using the local mailer via SMTP
128
    server = smtplib.SMTP('localhost','25')
129
#    server.set_debuglevel(1)
130
    server.sendmail(fromvalue, dests, qencode_subject (message))
131
    server.quit()
132

    
133

    
134

    
135
if __name__ == '__main__' :
136

    
137

    
138
    # handle options of the program
139
    try: 
140
        opts, args = getopt.getopt(sys.argv[1:], 't:b:')
141
    except getopt.error, msg:
142
        print "getopt error: %s" % msg
143
        usage(1)
144
        
145
    for name, value in opts:
146
        if name == '-t': TOFILE = value
147
        elif name == '-b': BODYFILE = value
148
        else:
149
            print "argument: ", name, " invalid"
150
            usage(1)
151

    
152
    if not TOFILE or not BODYFILE:
153
        usage(1)
154

    
155
    # read the recipients file
156
    sets = read_recipients()
157

    
158
    # read the template of the mail
159
    bodytemplate = read_body()
160

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

    
164
    # send mail to each recipient
165
    for set in sets :
166
        
167
        values = set
168

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

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

    
175
        # send message
176
        send_message(body, recipient)
177

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

    
(1-1/4)