3 # Script to send instructions to all voters.
5 # How to use this script
6 # ======================
8 # You probably want to first update the subject of the e-mail that will be
9 # sent. The second line of the instructions.txt will be the subject.
11 # So let's suppose that the instructions are in instructions.txt and that you
12 # made a list of voters in maildata.txt (probably using create-tmp-tokens.pl).
13 # The format of this file should be:
16 # You should use this script like this:
17 # $ ./mail-instructions.pl maildata.txt instructions.txt
19 # This script needs a MTA to send the e-mails. If you don't have one or if
20 # you're not sure that your ISP allows you to directly send mails, it's
21 # probably better and safer to run the script from a gnome.org server.
22 # Please test this script with your own email address by creating a
23 # maildata.txt with a single entry like
24 # foo;your@address;bar
26 # You may want to look at your mail server logs (and maybe keep them) to
27 # know if the mail was delivered. There are usually 10-15 errors. In case of
28 # such errors, you can try to look for the new e-mail addresses of the voters
29 # to ask them if they want to update their registered e-mail address and
30 # receive the instructions.
32 # This program is free software: you can redistribute it and/or modify
33 # it under the terms of the GNU General Public License as published by
34 # the Free Software Foundation, either version 3 of the License, or
35 # (at your option) any later version.
37 # This program is distributed in the hope that it will be useful,
38 # but WITHOUT ANY WARRANTY; without even the implied warranty of
39 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 # GNU General Public License for more details.
42 # You should have received a copy of the GNU General Public License
43 # along with this program. If not, see <http://www.gnu.org/licenses/>.
45 __author__ = "Tobias Mueller"
46 __license__ = "GPLv3+"
47 __email__ = "tobiasmue@gnome.org"
54 from email.mime.text import MIMEText
55 from email.mime.nonmultipart import MIMENonMultipart
56 from email.charset import Charset
58 from email.MIMEText import MIMEText
59 from email.Charset import Charset
60 from email.MIMENonMultipart import MIMENonMultipart
63 (re.compile(r'^(\s*Dear )<member>', re.MULTILINE), '\\1$member'),
64 (re.compile(r'^(\s*E-mail:)', re.MULTILINE), '\\1 $email'),
65 (re.compile(r'^(\s*Vote token:)', re.MULTILINE), '\\1 $token')
68 class MTText(MIMEText):
69 def __init__(self, _text, _subtype='plain', _charset='utf-8'):
70 if not isinstance(_charset, Charset):
71 _charset = Charset(_charset)
72 if isinstance(_text,unicode):
73 _text = _text.encode(_charset.input_charset)
74 MIMENonMultipart.__init__(self, 'text', _subtype,
75 **{'charset': _charset.input_charset})
76 self.set_payload(_text, _charset)
78 def email_it(recipients_file, instructions_file):
79 instructions = file(instructions_file, "r").read().decode('utf-8').splitlines()
81 from_header = instructions.pop(0)
82 subject_header = instructions.pop(0)
84 instructions = "\n".join(instructions)
85 for re_fix in re_template_fixes:
86 instructions = re_fix[0].sub(re_fix[1], instructions)
87 template = string.Template(instructions)
89 f = file(recipients_file, "r")
90 recipient_lines = f.read().decode('utf-8').splitlines()
96 for line in recipient_lines:
98 if l.startswith("#") or l == "":
103 print "ERROR in recipients file, invalid line:"
107 member_name, member_email, token = l
109 payload = template.substitute(member=member_name, email=member_email, token=token)
110 msg = MTText(payload)
111 msg['To'] = member_email
112 msg['From'] = from_header
113 msg['Subject'] = subject_header
114 msgstr = msg.as_string()
118 s.connect('localhost')
121 s.sendmail(from_header, [member_email,], msgstr)
122 except smtplib.SMTPException:
123 print "Error: Could not send to %s (%s)!" % (member_email, member_name)
133 print "Mailed %s instructions; %s could not be mailed." % (sent, errors)
136 if __name__ == '__main__':
137 if len(sys.argv) != 3:
138 print "Usage: mail-instructions.py <recipient list> <instructions template>"
141 email_it(sys.argv[1], sys.argv[2])