Ticket #1541: mail.2.diff
File mail.2.diff, 5.6 KB (added by , 17 years ago) |
---|
-
django/common/core/mail.py
4 4 5 5 from django.conf import settings 6 6 from email.MIMEText import MIMEText 7 from email.MIMEMultipart import MIMEMultipart 8 from email.MIMEBase import MIMEBase 9 from email import Encoders 10 import mimetypes 7 11 from email.Header import Header 8 12 from email.Utils import formatdate 9 13 from email import Charset … … 13 17 import time 14 18 import random 15 19 20 # Default MIME type to use for attachments if it cannot be guessed. 21 DEFAULT_ATTACHMENT_MIME_TYPE = 'application/octet-stream' 22 16 23 # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from 17 24 # some spam filters. 18 25 Charset.add_charset('utf-8', Charset.SHORTEST, Charset.QP, 'utf-8') … … 64 71 val = Header(val, settings.DEFAULT_CHARSET) 65 72 MIMEText.__setitem__(self, name, val) 66 73 74 class SafeMIMEMultipart(MIMEMultipart): 75 def __setitem__(self, name, val): 76 "Forbids multi-line headers, to prevent header injection." 77 if '\n' in val or '\r' in val: 78 raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name) 79 if name == 'Subject': 80 val = Header(val, settings.DEFAULT_CHARSET) 81 MIMEMultipart.__setitem__(self, name, val) 82 67 83 class SMTPConnection(object): 68 84 """ 69 85 A wrapper that manages the SMTP network connection. … … 161 177 self.subject = subject 162 178 self.body = body 163 179 self.connection = connection 180 self.attachments = [] 164 181 165 182 def get_connection(self, fail_silently=False): 166 183 if not self.connection: … … 169 186 170 187 def message(self): 171 188 msg = SafeMIMEText(self.body, 'plain', settings.DEFAULT_CHARSET) 189 if self.attachments: 190 body_msg = msg 191 msg = SafeMIMEMultipart() 192 msg.attach(body_msg) 193 for params in self.attachments: 194 msg.attach(self._compile_attachment(*params)) 172 195 msg['Subject'] = self.subject 173 196 msg['From'] = self.from_email 174 197 msg['To'] = ', '.join(self.to) … … (this hunk was shorter than expected) 189 212 """Send the email message.""" 190 213 return self.get_connection(fail_silently).send_messages([self]) 191 214 215 def attach(self, filename, content, mimetype=None): 216 """Attaches a file with the given filename and content.""" 217 self.attachments.append((filename, content, mimetype)) 218 219 def attach_file(self, path, mimetype=None): 220 """Attaches a file from the filesystem.""" 221 filename = os.path.basename(path) 222 f = open(path, 'rb') 223 content = f.read() 224 f.close() 225 self.attach(filename, content, mimetype) 226 227 def _compile_attachment(self, filename, content, mimetype): 228 """ 229 Compiles the given attachment to a MIME object and returns the new 230 attachment. 231 """ 232 if mimetype is None: 233 # Guess the mimetype based on the filename if possible. 234 mimetype, xx = mimetypes.guess_type(filename) 235 if mimetype is None: 236 mimetype = DEFAULT_ATTACHMENT_MIME_TYPE 237 basetype, subtype = mimetype.split('/', 1) 238 if basetype == 'text': 239 attachment = SafeMIMEText(content, subtype, settings.DEFAULT_CHARSET) 240 else: 241 # Encode non-text attachments with base64. 242 attachment = MIMEBase(basetype, subtype) 243 attachment.set_payload(content) 244 Encoders.encode_base64(attachment) 245 attachment.add_header('Content-Disposition', 'attachment', filename=filename) 246 return attachment 247 192 248 193 -- docs/email.txt Mon Jun 25 09:36:302007249 ++ docs/email.txt Tue Jun 26 14:33:28 2007 … … 198 198 .. note:: 199 199 Not all features of the ``EmailMessage`` class are available through the 200 200 ``send_mail()`` and related wrapper functions. If you wish to use advanced 201 features, such as BCC'ed recipients or multi-part e-mail, you'll need to202 create ``EmailMessage`` instances directly.201 features, such as BCC'ed recipients, file attachments, or multi-part 202 e-mail, you'll need to create ``EmailMessage`` instances directly. 203 203 204 204 In general, ``EmailMessage`` is responsible for creating the e-mail message 205 205 itself. ``SMTPConnection`` is responsible for the network connection side of … … 238 238 SMTP server needs to be told the full list of recipients when the message 239 239 is sent. If you add another way to specify recipients in your class, they 240 240 need to be returned from this method as well. 241 242 * ``attach()`` creates a new file attachment and adds it to the message. It 243 takes three arguments: ``filename``, ``content`` and ``mimetype``. 244 ``filename`` is the name of the file attachment as it will appear in the 245 email. ``content`` is the data that will be contained inside the 246 attachment. ``mimetype`` is optional, and defines the attachment's MIME 247 content type. If you omit ``mimetype``, the MIME content type will be 248 guessed from the filename of the attachment. 249 250 * ``attach_file()`` creates a new attachment using a file on the 251 filesystem, and takes two arguments. The first is the path of the file to 252 attach. The second argument is the MIME content type to use for the 253 attachment, and is optional. If the MIME type is omitted then it will be 254 guessed from the filename. 241 255 242 256 The ``SMTPConnection`` class is initialized with the host, port, username and 243 257 password for the SMTP server. If you don't specify one or more of those