6 from email.mime.multipart import MIMEMultipart
7 from email.mime.text import MIMEText
8 from email.mime.image import MIMEImage
9 from email.header import Header
11 from email.MIMEMultipart import MIMEMultipart
12 from email.MIMEText import MIMEText
13 from email.MIMEImage import MIMEImage
14 from email.Header import Header
16 from django.core.mail import DNS_NAME
17 from smtplib import SMTP
18 from forum import settings
19 from django.template import loader, Context, Template
20 from forum.utils.html import sanitize_html
21 from forum.context import application_settings
22 from forum.utils.html2text import HTML2Text
23 from threading import Thread
25 def send_msg_list(msgs, sender=None):
27 connection = SMTP(str(settings.EMAIL_HOST), str(settings.EMAIL_PORT),
28 local_hostname=DNS_NAME.get_fqdn())
31 if (bool(settings.EMAIL_USE_TLS)):
36 if settings.EMAIL_HOST_USER and settings.EMAIL_HOST_PASSWORD:
37 connection.login(str(settings.EMAIL_HOST_USER), str(settings.EMAIL_HOST_PASSWORD))
40 sender = str(settings.DEFAULT_FROM_EMAIL)
42 for email, msg in msgs:
44 connection.sendmail(sender, [email], msg)
49 except socket.sslerror:
54 def html2text(s, ignore_tags=(), indent_width=4, page_width=80):
55 ignore_tags = [t.lower() for t in ignore_tags]
56 parser = HTML2Text(ignore_tags, indent_width, page_width)
63 if isinstance(data, (tuple, list)) and len(data) == 2:
64 return '%s <%s>' % data
68 def create_msg(subject, sender, recipient, html, text, images):
69 msgRoot = MIMEMultipart('related')
70 msgRoot['Subject'] = subject
71 msgRoot['From'] = named(sender)
72 msgRoot['To'] = named(recipient)
73 msgRoot.preamble = 'This is a multi-part message from %s.' % unicode(settings.APP_SHORT_NAME).encode('utf8')
75 msgAlternative = MIMEMultipart('alternative')
76 msgRoot.attach(msgAlternative)
78 msgAlternative.attach(MIMEText(text, _charset='utf-8'))
79 msgAlternative.attach(MIMEText(html, 'html', _charset='utf-8'))
83 fp = open(img[0], 'rb')
84 msgImage = MIMEImage(fp.read())
86 msgImage.add_header('Content-ID', '<'+img[1]+'>')
87 msgRoot.attach(msgImage)
91 return msgRoot.as_string()
93 def send_email(subject, recipients, template, context={}, sender=None, images=[], threaded=True):
95 sender = (unicode(settings.APP_SHORT_NAME), unicode(settings.DEFAULT_FROM_EMAIL))
98 images = [(os.path.join(str(settings.UPFILES_FOLDER), os.path.basename(str(settings.APP_LOGO))), 'logo')]
100 context.update(application_settings(None))
101 html_body = loader.get_template(template).render(Context(context))
102 txt_body = html2text(html_body)
104 if isinstance(recipients, str):
105 recipients = [recipients]
109 for recipient in recipients:
110 if isinstance(recipient, str):
111 recipient_data = ('recipient', recipient)
112 recipient_context = None
113 elif isinstance(recipient, (list, tuple)) and len(recipient) == 2:
114 name, email = recipient
115 recipient_data = (name, email)
116 recipient_context = None
117 elif isinstance(recipient, (list, tuple)) and len(recipient) == 3:
118 name, email, recipient_context = recipient
119 recipient_data = (name, email)
121 raise Exception('bad argument for recipients')
123 if recipient_context is not None:
124 recipient_context = Context(recipient_context)
125 msg_html = Template(html_body).render(recipient_context)
126 msg_txt = Template(txt_body).render(recipient_context)
131 msg = create_msg(subject, sender, recipient_data, msg_html, msg_txt, images)
132 msgs.append((email, msg))
135 thread = Thread(target=send_msg_list, args=[msgs])
136 thread.setDaemon(True)
142 def send_template_email(recipients, template, context):
143 t = loader.get_template(template)
144 context.update(dict(recipients=recipients, settings=settings))
145 t.render(Context(context))
147 def create_and_send_mail_messages(messages):
148 if not settings.EMAIL_HOST:
151 sender = Header(unicode(settings.APP_SHORT_NAME), 'utf-8')
152 sender.append('<%s>' % unicode(settings.DEFAULT_FROM_EMAIL))
153 sender = u'%s <%s>' % (unicode(settings.APP_SHORT_NAME), unicode(settings.DEFAULT_FROM_EMAIL))
156 connection = SMTP(str(settings.EMAIL_HOST), str(settings.EMAIL_PORT),
157 local_hostname=DNS_NAME.get_fqdn())
159 if (bool(settings.EMAIL_USE_TLS)):
161 connection.starttls()
164 if settings.EMAIL_HOST_USER and settings.EMAIL_HOST_PASSWORD:
165 connection.login(str(settings.EMAIL_HOST_USER), str(settings.EMAIL_HOST_PASSWORD))
168 sender = str(settings.DEFAULT_FROM_EMAIL)
170 for recipient, subject, html, text, media in messages:
171 msgRoot = MIMEMultipart('related')
173 msgRoot['Subject'] = Header(subject, 'utf-8')
174 msgRoot['From'] = sender
176 to = Header(recipient.username, 'utf-8')
177 to.append('<%s>' % recipient.email)
180 msgRoot.preamble = 'This is a multi-part message from %s.' % unicode(settings.APP_SHORT_NAME).encode('utf8')
182 msgAlternative = MIMEMultipart('alternative')
183 msgRoot.attach(msgAlternative)
185 msgAlternative.attach(MIMEText(text.encode('utf-8'), _charset='utf-8'))
186 msgAlternative.attach(MIMEText(html.encode('utf-8'), 'html', _charset='utf-8'))
188 for alias, location in media.items():
189 fp = open(location, 'rb')
190 msgImage = MIMEImage(fp.read())
192 msgImage.add_header('Content-ID', '<'+alias+'>')
193 msgRoot.attach(msgImage)
196 connection.sendmail(sender, [recipient.email], msgRoot.as_string())
202 except socket.sslerror: