Changeset 5547
- Timestamp:
- 06/27/07 04:44:55 (1 year ago)
- Files:
-
- django/trunk/django/core/mail.py (modified) (8 diffs)
- django/trunk/docs/email.txt (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/core/mail.py
r5146 r5547 4 4 5 5 from django.conf import settings 6 from email import Charset, Encoders 6 7 from email.MIMEText import MIMEText 8 from email.MIMEMultipart import MIMEMultipart 9 from email.MIMEBase import MIMEBase 7 10 from email.Header import Header 8 11 from email.Utils import formatdate 9 from email import Charset 12 import mimetypes 10 13 import os 11 14 import smtplib … … 17 20 # some spam filters. 18 21 Charset.add_charset('utf-8', Charset.SHORTEST, Charset.QP, 'utf-8') 22 23 # Default MIME type to use on attachments (if it is not explicitly given 24 # and cannot be guessed). 25 DEFAULT_ATTACHMENT_MIME_TYPE = 'application/octet-stream' 19 26 20 27 # Cache the hostname, but do it lazily: socket.getfqdn() can take a couple of … … 56 63 pass 57 64 58 class Safe MIMEText(MIMEText):65 class SafeHeaderMixin(object): 59 66 def __setitem__(self, name, val): 60 67 "Forbids multi-line headers, to prevent header injection." … … 63 70 if name == "Subject": 64 71 val = Header(val, settings.DEFAULT_CHARSET) 65 MIMEText.__setitem__(self, name, val) 72 # Note: using super() here is safe; any __setitem__ overrides must use 73 # the same argument signature. 74 super(SafeHeaderMixin, self).__setitem__(name, val) 75 76 class SafeMIMEText(MIMEText, SafeHeaderMixin): 77 pass 78 79 class SafeMIMEMultipart(MIMEMultipart, SafeHeaderMixin): 80 pass 66 81 67 82 class SMTPConnection(object): … … 155 170 A container for email information. 156 171 """ 157 def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, connection=None): 172 def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, 173 connection=None, attachments=None): 158 174 self.to = to or [] 159 175 self.bcc = bcc or [] … … 161 177 self.subject = subject 162 178 self.body = body 179 self.attachments = attachments or [] 163 180 self.connection = connection 164 181 … … 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 if self.body: 193 msg.attach(body_msg) 194 for attachment in self.attachments: 195 if isinstance(attachment, MIMEBase): 196 msg.attach(attachment) 197 else: 198 msg.attach(self._create_attachment(*attachment)) 172 199 msg['Subject'] = self.subject 173 200 msg['From'] = self.from_email … … 190 217 return self.get_connection(fail_silently).send_messages([self]) 191 218 219 def attach(self, filename, content=None, mimetype=None): 220 """ 221 Attaches a file with the given filename and content. 222 223 Alternatively, the first parameter can be a MIMEBase subclass, which 224 is inserted directly into the resulting message attachments. 225 """ 226 if isinstance(filename, MIMEBase): 227 self.attachements.append(filename) 228 else: 229 assert content is not None 230 self.attachments.append((filename, content, mimetype)) 231 232 def attach_file(self, path, mimetype=None): 233 """Attaches a file from the filesystem.""" 234 filename = os.path.basename(path) 235 content = open(path, 'rb').read() 236 self.attach(filename, content, mimetype) 237 238 def _create_attachment(self, filename, content, mimetype=None): 239 """ 240 Convert the filename, content, mimetype triple into a MIME attachment 241 object. 242 """ 243 if mimetype is None: 244 mimetype, _ = mimetypes.guess_type(filename) 245 if mimetype is None: 246 mimetype = DEFAULT_ATTACHMENT_MIME_TYPE 247 basetype, subtype = mimetype.split('/', 1) 248 if basetype == 'text': 249 attachment = SafeMIMEText(content, subtype, settings.DEFAULT_CHARSET) 250 else: 251 # Encode non-text attachments with base64. 252 attachment = MIMEBase(basetype, subtype) 253 attachment.set_payload(content) 254 Encoders.encode_base64(attachment) 255 attachment.add_header('Content-Disposition', 'attachment', filename=filename) 256 return attachment 257 192 258 def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None): 193 259 """ django/trunk/docs/email.txt
r5155 r5547 29 29 30 30 The character set of e-mail sent with ``django.core.mail`` will be set to 31 the value of your `DEFAULT_CHARSET setting`_.32 33 .. _DEFAULT_CHARSET setting: ../settings/#default-charset31 the value of your `DEFAULT_CHARSET`_ setting. 32 33 .. _DEFAULT_CHARSET: ../settings/#default-charset 34 34 .. _EMAIL_HOST: ../settings/#email-host 35 35 .. _EMAIL_PORT: ../settings/#email-port … … 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 to 202 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 204 This is a design feature. ``send_mail()`` and related functions were 205 originally the only interface Django provided. However, the list of 206 parameters they accepted was slowly growing over time. It made sense to 207 move to a more object-oriented design for e-mail messages and retain the 208 original functions only for backwards compatibility. 209 210 If you need to add new functionality to the e-mail infrastrcture, 211 sub-classing the ``EmailMessage`` class should make this a simple task. 203 212 204 213 In general, ``EmailMessage`` is responsible for creating the e-mail message … … 207 216 ``SMTPConnection`` instance) for multiple messages. 208 217 218 E-mail messages 219 ---------------- 220 209 221 The ``EmailMessage`` class is initialized as follows:: 210 222 211 email = EmailMessage(subject, body, from_email, to, bcc, connection) 223 email = EmailMessage(subject, body, from_email, to, 224 bcc, connection, attachments) 212 225 213 226 All of these parameters are optional. If ``from_email`` is omitted, the value 214 227 from ``settings.DEFAULT_FROM_EMAIL`` is used. Both the ``to`` and ``bcc`` 215 parameters are lists of addresses, as strings. 228 parameters are lists of addresses, as strings. The ``attachments`` parameter is 229 a list containing either ``(filename, content, mimetype)`` triples of 230 ``email.MIMEBase.MIMEBase`` instances. 216 231 217 232 For example:: … … 228 243 229 244 * ``message()`` constructs a ``django.core.mail.SafeMIMEText`` object (a 230 sub-class of Python's ``email.MIMEText.MIMEText`` class) holding the 245 sub-class of Python's ``email.MIMEText.MIMEText`` class) or a 246 ``django.core.mail.SafeMIMEMultipart`` object holding the 231 247 message to be sent. If you ever need to extend the `EmailMessage` class, 232 248 you'll probably want to override this method to put the content you wish … … 240 256 need to be returned from this method as well. 241 257 258 * ``attach()`` creates a new file attachment and adds it to the message. 259 There are two ways to call ``attach()``: 260 261 * You can pass it a single argument which is an 262 ``email.MIMBase.MIMEBase`` instance. This will be inserted directly 263 into the resulting message. 264 265 * Alternatively, you can pass ``attach()`` three arguments: 266 ``filename``, ``content`` and ``mimetype``. ``filename`` is the name 267 of the file attachment as it will appear in the email, ``content`` is 268 the data that will be contained inside the attachment and 269 ``mimetype`` is the optional MIME type for the attachment. If you 270 omit ``mimetype``, the MIME content type will be guessed from the 271 filename of the attachment. 272 273 For example:: 274 275 message.attach('design.png', img_data, 'image/png') 276 277 * ``attach_file()`` creates a new attachment using a file from your 278 filesystem. Call it with the path of the file to attach and, optionally, 279 the MIME type to use for the attachment. If the MIME type is omitted, it 280 will be guessed from the filename. The simplest use would be:: 281 282 message.attach_file('/images/weather_map.png') 283 284 SMTP network connections 285 ------------------------- 286 242 287 The ``SMTPConnection`` class is initialized with the host, port, username and 243 288 password for the SMTP server. If you don't specify one or more of those
