Skip to content

Commit 19d77b7

Browse files
committed
Add mail-sending module. It uses the django settings file for several
bits of configuration (e.g., mail server, any authentication required, etc.) It has different behavior based on the setting of the SERVER_MODE setting: - 'development' or 'test': the message will be sent as an attachment to ietf.tracker.archive+SERVER_MODE@gmail.com; the actual destination supplied won't be used. - 'production': the message will be sent to the addressees and a copy sent to ietf.tracker.archive+production@gmail.com . There are several functions to call, depending on what you want to pass: - send_mail_text() takes a request, "To:" list, From header (or None to default), Subject text, Body text, an optional Cc: list, and an optional dict with extra headers. - send_mail() takes a template and a context instead of the body text, and renders the template with the given context. - send_mail_subj() takes a template for the subject as well as for the body. It uses the same context to render both templates. - Legacy-Id: 159
1 parent fb5013e commit 19d77b7

2 files changed

Lines changed: 106 additions & 1 deletion

File tree

ietf/settings.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
TEMPLATE_DEBUG = DEBUG
1515

1616
ADMINS = (
17-
('Bill Fenner', 'fenner@research.att.com'),
17+
('IETF Django Developers', 'django-project@ietf.org'),
18+
('GMail Tracker Archive', 'ietf.tracker.archive+errors@gmail.com'),
1819
)
20+
DEFAULT_FROM_EMAIL = 'IETF Secretariat <ietf-secretariat-reply@ietf.org>'
1921

2022
MANAGERS = ADMINS
2123

@@ -121,6 +123,11 @@
121123
'2001:16d8:ff54::1',
122124
)
123125

126+
# Valid values:
127+
# 'production', 'test', 'development'
128+
# Override this in settings_local.py if it's not true
129+
SERVER_MODE = 'development'
130+
124131
# Put SECRET_KEY in here, or any other sensitive or site-specific
125132
# changes. DO NOT commit settings_local.py to svn.
126133
from settings_local import *

ietf/utils/mail.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from email.Utils import *
2+
from email.MIMEText import MIMEText
3+
from email.MIMEMessage import MIMEMessage
4+
from email.MIMEMultipart import MIMEMultipart
5+
import smtplib
6+
from django.conf import settings
7+
from django.template.loader import render_to_string
8+
from django.template import RequestContext
9+
10+
def add_headers(msg):
11+
if not(msg.has_key('Message-ID')):
12+
msg['Message-ID'] = make_msgid('idtracker')
13+
if not(msg.has_key('Date')):
14+
msg['Date'] = formatdate(time.time(), True)
15+
if not(msg.has_key('From')):
16+
msg['From'] = settings.DEFAULT_FROM_EMAIL
17+
return msg
18+
19+
def send_smtp(msg):
20+
'''
21+
Send a Message via SMTP, based on the django email server settings.
22+
The destination list will be taken from the To:/Cc: headers in the
23+
Message. The From address will be used if present or will default
24+
to the django setting DEFAULT_FROM_EMAIL
25+
'''
26+
add_headers(msg)
27+
(fname, frm) = parseaddr(msg.get('From'))
28+
to = [addr for name, addr in getaddresses(msg.get_all('To') + msg.get_all('Cc', []))]
29+
# todo: exception handling
30+
server = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT)
31+
if settings.DEBUG:
32+
server.set_debuglevel(1)
33+
if settings.EMAIL_HOST_USER and settings.EMAIL_HOST_PASSWORD:
34+
server.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD)
35+
server.sendmail(frm, to, msg.as_string())
36+
server.quit()
37+
38+
def copy_email(msg, to):
39+
'''
40+
Send a copy of the given email message to the given recipient.
41+
'''
42+
add_headers(msg)
43+
new = MIMEMultipart()
44+
# get info for first part.
45+
# Mode: if it's production, then "copy of a message", otherwise
46+
# "this is a message that would have been sent from"
47+
# hostname?
48+
# django settings if debugging?
49+
# Should this be a template?
50+
if settings.SERVER_MODE == 'production':
51+
new.attach(MIMEText("This is a copy of a message sent from the I-D tracker."))
52+
else:
53+
new.attach(MIMEText("The attached message would have been sent, but the tracker is in %s mode.\nIt was not sent to anybody.\n" % settings.SERVER_MODE))
54+
new.attach(MIMEMessage(msg))
55+
new['From'] = msg['From']
56+
new['Subject'] = '[Django %s] %s' % (settings.SERVER_MODE, msg.get('Subject', '[no subject]'))
57+
new['To'] = to
58+
send_smtp(new)
59+
60+
def send_mail_subj(request, to, frm, stemplate, template, context, cc=None, extra=None):
61+
'''
62+
Send an email message, exactly as send_mail(), but the
63+
subject field is a template.
64+
'''
65+
subject = render_to_string(template, context, context_instance=RequestContext(request))
66+
return send_mail(request, to, frm, subject, template, context, cc, extra)
67+
68+
def send_mail(request, to, frm, subject, template, context, cc=None, extra=None):
69+
'''
70+
Send an email to the destination [list], with the given return
71+
address (or "None" to use the default in settings.py).
72+
The body is a text/plain rendering of the template with the context.
73+
extra is a dict of extra headers to add.
74+
'''
75+
txt = render_to_string(template, context, context_instance=RequestContext(request))
76+
return send_mail_text(request, to, frm, subject, txt, cc, extra)
77+
78+
def send_mail_text(request, to, frm,subject, txt, cc=None, extra=None):
79+
msg = MIMEText(txt)
80+
if isinstance(frm, tuple):
81+
frm = formataddr(frm)
82+
if isinstance(to, list) or isinstance(to, tuple):
83+
to = ", ".join([isinstance(addr, tuple) and formataddr(addr) or addr for addr in to])
84+
if isinstance(cc, list) or isinstance(cc, tuple):
85+
cc = ", ".join([isinstance(addr, tuple) and formataddr(addr) or addr for addr in cc])
86+
if frm:
87+
msg['From'] = frm
88+
msg['To'] = to
89+
if cc:
90+
msg['Cc'] = cc
91+
msg['Subject'] = subject
92+
msg['X-Test-IDTracker'] = (settings.SERVER_MODE == 'production') and 'no' or 'yes'
93+
if extra:
94+
for k, v in extra.iteritems():
95+
msg[k] = v
96+
if settings.SERVER_MODE == 'production':
97+
send_smtp(msg)
98+
copy_email(msg, "ietf.tracker.archive+%s@gmail.com" % settings.SERVER_MODE)

0 commit comments

Comments
 (0)