2005-07-16 00:47:19 +08:00
|
|
|
# Use this module for e-mailing.
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2006-04-11 11:19:57 +08:00
|
|
|
from django.conf import settings
|
2005-07-13 09:25:57 +08:00
|
|
|
from email.MIMEText import MIMEText
|
2006-05-14 01:18:42 +08:00
|
|
|
from email.Header import Header
|
2007-02-25 23:55:31 +08:00
|
|
|
from email.Utils import formatdate
|
|
|
|
import smtplib
|
2006-11-07 23:32:18 +08:00
|
|
|
import socket
|
|
|
|
import time
|
|
|
|
import random
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2007-02-17 14:01:17 +08:00
|
|
|
# Cache the hostname, but do it lazily: socket.getfqdn() can take a couple of
|
|
|
|
# seconds, which slows down the restart of the server.
|
|
|
|
class CachedDnsName(object):
|
|
|
|
def __str__(self):
|
|
|
|
return self.get_fqdn()
|
|
|
|
|
|
|
|
def get_fqdn(self):
|
|
|
|
if not hasattr(self, '_fqdn'):
|
|
|
|
self._fqdn = socket.getfqdn()
|
|
|
|
return self._fqdn
|
|
|
|
|
|
|
|
DNS_NAME = CachedDnsName()
|
2006-11-10 11:28:58 +08:00
|
|
|
|
2005-12-30 06:12:54 +08:00
|
|
|
class BadHeaderError(ValueError):
|
|
|
|
pass
|
|
|
|
|
2005-12-30 04:33:56 +08:00
|
|
|
class SafeMIMEText(MIMEText):
|
|
|
|
def __setitem__(self, name, val):
|
|
|
|
"Forbids multi-line headers, to prevent header injection."
|
|
|
|
if '\n' in val or '\r' in val:
|
2005-12-30 06:12:54 +08:00
|
|
|
raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
|
2006-05-14 01:18:42 +08:00
|
|
|
if name == "Subject":
|
|
|
|
val = Header(val, settings.DEFAULT_CHARSET)
|
2005-12-30 04:33:56 +08:00
|
|
|
MIMEText.__setitem__(self, name, val)
|
|
|
|
|
2007-02-26 00:29:09 +08:00
|
|
|
def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None):
|
2005-07-13 09:25:57 +08:00
|
|
|
"""
|
|
|
|
Easy wrapper for sending a single message to a recipient list. All members
|
|
|
|
of the recipient list will see the other recipients in the 'To' field.
|
2007-02-26 00:29:09 +08:00
|
|
|
|
|
|
|
If auth_user is None, the EMAIL_HOST_USER setting is used.
|
|
|
|
If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
|
2005-07-13 09:25:57 +08:00
|
|
|
"""
|
2006-03-23 03:47:15 +08:00
|
|
|
return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password)
|
2005-07-13 09:25:57 +08:00
|
|
|
|
2007-02-26 00:29:09 +08:00
|
|
|
def send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None):
|
2005-07-13 09:25:57 +08:00
|
|
|
"""
|
|
|
|
Given a datatuple of (subject, message, from_email, recipient_list), sends
|
|
|
|
each message to each recipient list. Returns the number of e-mails sent.
|
|
|
|
|
|
|
|
If from_email is None, the DEFAULT_FROM_EMAIL setting is used.
|
2006-03-23 03:47:15 +08:00
|
|
|
If auth_user and auth_password are set, they're used to log in.
|
2007-02-26 00:29:09 +08:00
|
|
|
If auth_user is None, the EMAIL_HOST_USER setting is used.
|
|
|
|
If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
|
2005-07-13 09:25:57 +08:00
|
|
|
"""
|
2007-02-26 00:29:09 +08:00
|
|
|
if auth_user is None:
|
|
|
|
auth_user = settings.EMAIL_HOST_USER
|
|
|
|
if auth_password is None:
|
|
|
|
auth_password = settings.EMAIL_HOST_PASSWORD
|
2005-07-13 09:25:57 +08:00
|
|
|
try:
|
2006-04-11 11:23:03 +08:00
|
|
|
server = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT)
|
2006-03-23 03:47:15 +08:00
|
|
|
if auth_user and auth_password:
|
|
|
|
server.login(auth_user, auth_password)
|
2005-07-13 09:25:57 +08:00
|
|
|
except:
|
|
|
|
if fail_silently:
|
|
|
|
return
|
|
|
|
raise
|
|
|
|
num_sent = 0
|
|
|
|
for subject, message, from_email, recipient_list in datatuple:
|
|
|
|
if not recipient_list:
|
|
|
|
continue
|
2006-04-11 11:19:57 +08:00
|
|
|
from_email = from_email or settings.DEFAULT_FROM_EMAIL
|
2006-05-14 01:18:42 +08:00
|
|
|
msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET)
|
2005-07-13 09:25:57 +08:00
|
|
|
msg['Subject'] = subject
|
|
|
|
msg['From'] = from_email
|
|
|
|
msg['To'] = ', '.join(recipient_list)
|
2007-02-25 23:55:31 +08:00
|
|
|
msg['Date'] = formatdate()
|
2006-11-10 11:28:58 +08:00
|
|
|
try:
|
|
|
|
random_bits = str(random.getrandbits(64))
|
|
|
|
except AttributeError: # Python 2.3 doesn't have random.getrandbits().
|
|
|
|
random_bits = ''.join([random.choice('1234567890') for i in range(19)])
|
2006-11-11 01:42:47 +08:00
|
|
|
msg['Message-ID'] = "<%d.%s@%s>" % (time.time(), random_bits, DNS_NAME)
|
2006-05-02 09:31:56 +08:00
|
|
|
try:
|
|
|
|
server.sendmail(from_email, recipient_list, msg.as_string())
|
|
|
|
num_sent += 1
|
|
|
|
except:
|
|
|
|
if not fail_silently:
|
|
|
|
raise
|
|
|
|
try:
|
|
|
|
server.quit()
|
|
|
|
except:
|
|
|
|
if fail_silently:
|
|
|
|
return
|
|
|
|
raise
|
2005-07-13 09:25:57 +08:00
|
|
|
return num_sent
|
|
|
|
|
|
|
|
def mail_admins(subject, message, fail_silently=False):
|
2006-03-23 03:47:15 +08:00
|
|
|
"Sends a message to the admins, as defined by the ADMINS setting."
|
2006-04-11 11:19:57 +08:00
|
|
|
send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS], fail_silently)
|
2005-07-13 09:25:57 +08:00
|
|
|
|
|
|
|
def mail_managers(subject, message, fail_silently=False):
|
2006-03-23 03:47:15 +08:00
|
|
|
"Sends a message to the managers, as defined by the MANAGERS setting."
|
2006-04-11 11:19:57 +08:00
|
|
|
send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS], fail_silently)
|