Provides nifty interface for email composing and sending via SMTP impo

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""
Provides nifty interface for email composing and sending via SMTP.
"""
import logging
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.Header import Header
import smtplib
import socket
import settings
# Storage for emails. In debug mode all emails sending with
# EmailMessage will be stored in debug_cache variable
debug_cache = []
def format_header(value, charset):
"""
Format value to make it safe for using in email headers.
"""
try:
value.decode('ascii')
except (UnicodeDecodeError, UnicodeEncodeError):
return Header(value.encode(charset), charset)
else:
return value
class EmailMessage(object):
"""
Provide nifty interface for email composing and sending via SMTP.
"""
def __init__(self, to_email, from_email, subject, body, text_body=None, charset='utf-8'):
self.to_email = to_email
self.from_email = from_email
self.subject = subject
self.body = body
self.text_body = text_body
self.from_email = from_email
self.charset = charset
def as_message(self):
"""
Return python email.MIMEMultipart.MIMEMultipart object.
"""
msg = MIMEMultipart()
# Following headers are useful to show the email correctly
# in your recipient's email box, and to avoid being marked
# as spam. They are NOT essential to the sendmail call later
msg['Subject'] = format_header(self.subject, self.charset)
msg['From'] = format_header(self.from_email, self.charset)
msg['Reply-to'] = format_header(self.from_email, self.charset)
msg['To'] = format_header(self.to_email, self.charset)
msg.preamble = 'Multipart message'
msg.epilogue = ''
# Encapsulate the plain text and html versions of the message body in an
# 'alternative' part, so MUAs can decide which they want to display.
msg_alternative = MIMEMultipart('alternative')
msg.attach(msg_alternative)
if not self.text_body is None:
part = MIMEText(self.text_body.encode(self.charset),
_charset=self.charset,
_subtype='plain')
msg_alternative.attach(part)
if not self.body is None:
part = MIMEText(self.body.encode(self.charset),
_charset=self.charset,
_subtype='html')
msg_alternative.attach(part)
return msg
def as_string(self):
"""
Return textual representation of email message suitable
for sending via SMTP.
"""
return self.as_message().as_string()
def send(self, smtp_host=None, smtp_port=None, debug=False):
"""
Send message via SMTP.
Return True or False indicating the success of message sending.
"""
if smtp_host is None:
smtp_host = settings.DEFAULT_SMTP_HOST
if smtp_port is None:
smtp_port = settings.DEFAULT_SMTP_PORT
logging.debug('\n\n')
logging.debug(u'Sending email')
logging.debug('from=[%s]' % self.from_email)
logging.debug('to=[%s]' % self.to_email)
logging.debug('subject=[%s]' % self.subject)
logging.debug(u'body:\n%s' % self.body)
logging.debug(u'text_body:\n%s' % self.text_body)
logging.debug('\n\n')
if debug:
debug_cache.append(self.as_message())
logging.debug('Saving message in debug cache')
return True
else:
logging.debug('Sending message via SMTP')
try:
s = smtplib.SMTP()
s.connect(smtp_host, smtp_port)
s.sendmail(self.from_email, self.to_email, self.as_string())
s.close()
except (socket.error, smtplib.SMTPException), ex:
logging.error(ex)
return False
else:
return True