Sending html emails with images using Django templates

 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
# -*- coding: utf-8 -*-

# Sending html emails in Django
# Report any bugs to esat @t sleytr*net
# Evren Esat Ozkan


#download and install feedparser from http://feedparser.org
#download and install StripOGram from http://www.zope.org/Members/chrisw/StripOGram
from feedparser import _sanitizeHTML
from stripogram import html2text

from django.conf import settings
from django.template import loader, Context

from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from smtplib import SMTP
import email.Charset


charset='utf-8'
smtp_server='localhost'
smtp_user=''
smtp_pass=''

email.Charset.add_charset( charset, email.Charset.SHORTEST, None, None )

def htmlmail(sbj,recip,msg,template='',texttemplate='',textmsg='',images=(), recip_name='',sender=settings.DEFAULT_FROM_EMAIL,sender_name='',charset=charset):
   '''
   if you want to use Django template system:
      use `msg` and optionally `textmsg` as template context (dict)
      and define `template` and optionally `texttemplate` variables.
   otherwise msg and textmsg variables are used as html and text message sources.
   
   if you want to use images in html message, define physical paths and ids in tuples.
   (image paths are relative to  MEDIA_ROOT)
   example: 
   images=(('email_images/logo.gif','img1'),('email_images/footer.gif','img2'))
   and use them in html like this:
   <img src="cid:img1">
   ...
   <img src="cid:img2">
   '''
   html=render(msg,template)
   if texttemplate or textmsg: text=render((textmsg or msg),texttemplate)
   else: text= html2text(_sanitizeHTML(html,charset))

   msgRoot = MIMEMultipart('related')
   msgRoot['Subject'] = sbj
   msgRoot['From'] = named(sender,sender_name)
   msgRoot['To'] =  named(recip,recip_name)
   msgRoot.preamble = 'This is a multi-part message in MIME format.'

   msgAlternative = MIMEMultipart('alternative')
   msgRoot.attach(msgAlternative)
   
   msgAlternative.attach(MIMEText(text, _charset=charset))
   msgAlternative.attach(MIMEText(html, 'html', _charset=charset))

   for img in images:
      fp = open(settings.MEDIA_ROOT+img[0], 'rb')
      msgImage = MIMEImage(fp.read())
      fp.close()
      msgImage.add_header('Content-ID', '<'+img[1]+'>')
      msgRoot.attach(msgImage)

   smtp = SMTP()
   smtp.connect(smtp_server)
   if smtp_user: smtp.login(smtp_user, smtp_pass)
   smtp.sendmail(sender, recip, msgRoot.as_string())
   smtp.quit()


def render(context,template):
   if template:
      t = loader.get_template(template)
      return t.render(Context(context))
   return context

def named(mail,name):
   if name: return '%s <%s>' % (name,mail)
   return mail

Comments

canen (on June 14, 2007):

You don't need to tie it to the project with this line

from PROJECT_NAME.settings import MEDIA_ROOT,DEFAULT_FROM_EMAIL

You can use

from django.conf import settings

See the settings docs

#

sleytr (on June 14, 2007):

Thank you. I corrected the code.

#

(Forgotten your password?)

You may use Markdown syntax here, but raw HTML will be removed.