Changeset 5148
- Timestamp:
- 05/03/07 14:26:47 (1 year ago)
- Files:
-
- django/branches/boulder-oracle-sprint/django/conf/global_settings.py (modified) (1 diff)
- django/branches/boulder-oracle-sprint/django/core/mail.py (modified) (6 diffs)
- django/branches/boulder-oracle-sprint/docs/documentation.txt (modified) (1 diff)
- django/branches/boulder-oracle-sprint/docs/email.txt (modified) (3 diffs)
- django/branches/boulder-oracle-sprint/docs/sessions.txt (modified) (1 diff)
- django/branches/boulder-oracle-sprint/docs/settings.txt (modified) (1 diff)
- django/branches/boulder-oracle-sprint/docs/syndication_feeds.txt (modified) (1 diff)
- django/branches/boulder-oracle-sprint/docs/templates_python.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/boulder-oracle-sprint/django/conf/global_settings.py
r5079 r5148 120 120 EMAIL_HOST_USER = '' 121 121 EMAIL_HOST_PASSWORD = '' 122 EMAIL_USE_TLS = False 122 123 123 124 # List of strings representing installed apps. django/branches/boulder-oracle-sprint/django/core/mail.py
r5047 r5148 1 # Use this module for e-mailing. 1 """ 2 Tools for sending email. 3 """ 2 4 3 5 from django.conf import settings … … 5 7 from email.Header import Header 6 8 from email.Utils import formatdate 9 from email import Charset 10 import os 7 11 import smtplib 8 12 import socket 9 13 import time 10 14 import random 15 16 # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from 17 # some spam filters. 18 Charset.add_charset('utf-8', Charset.SHORTEST, Charset.QP, 'utf-8') 11 19 12 20 # Cache the hostname, but do it lazily: socket.getfqdn() can take a couple of … … 22 30 23 31 DNS_NAME = CachedDnsName() 32 33 # Copied from Python standard library and modified to used the cached hostname 34 # for performance. 35 def make_msgid(idstring=None): 36 """Returns a string suitable for RFC 2822 compliant Message-ID, e.g: 37 38 <20020201195627.33539.96671@nightshade.la.mastaler.com> 39 40 Optional idstring if given is a string used to strengthen the 41 uniqueness of the message id. 42 """ 43 timeval = time.time() 44 utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval)) 45 pid = os.getpid() 46 randint = random.randrange(100000) 47 if idstring is None: 48 idstring = '' 49 else: 50 idstring = '.' + idstring 51 idhost = DNS_NAME 52 msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, idhost) 53 return msgid 24 54 25 55 class BadHeaderError(ValueError): … … 35 65 MIMEText.__setitem__(self, name, val) 36 66 67 class SMTPConnection(object): 68 """ 69 A wrapper that manages the SMTP network connection. 70 """ 71 72 def __init__(self, host=None, port=None, username=None, password=None, 73 use_tls=None, fail_silently=False): 74 self.host = host or settings.EMAIL_HOST 75 self.port = port or settings.EMAIL_PORT 76 self.username = username or settings.EMAIL_HOST_USER 77 self.password = password or settings.EMAIL_HOST_PASSWORD 78 self.use_tls = (use_tls is not None) and use_tls or settings.EMAIL_USE_TLS 79 self.fail_silently = fail_silently 80 self.connection = None 81 82 def open(self): 83 """ 84 Ensure we have a connection to the email server. Returns whether or not 85 a new connection was required. 86 """ 87 if self.connection: 88 # Nothing to do if the connection is already open. 89 return False 90 try: 91 self.connection = smtplib.SMTP(self.host, self.port) 92 if self.use_tls: 93 self.connection.ehlo() 94 self.connection.starttls() 95 self.connection.ehlo() 96 if self.username and self.password: 97 self.connection.login(self.username, self.password) 98 return True 99 except: 100 if not self.fail_silently: 101 raise 102 103 def close(self): 104 """Close the connection to the email server.""" 105 try: 106 try: 107 self.connection.quit() 108 except socket.sslerror: 109 # This happens when calling quit() on a TLS connection 110 # sometimes. 111 self.connection.close() 112 except: 113 if self.fail_silently: 114 return 115 raise 116 finally: 117 self.connection = None 118 119 def send_messages(self, email_messages): 120 """ 121 Send one or more EmailMessage objects and return the number of email 122 messages sent. 123 """ 124 if not email_messages: 125 return 126 new_conn_created = self.open() 127 if not self.connection: 128 # We failed silently on open(). Trying to send would be pointless. 129 return 130 num_sent = 0 131 for message in email_messages: 132 sent = self._send(message) 133 if sent: 134 num_sent += 1 135 if new_conn_created: 136 self.close() 137 return num_sent 138 139 def _send(self, email_message): 140 """A helper method that does the actual sending.""" 141 if not email_message.to: 142 return False 143 try: 144 self.connection.sendmail(email_message.from_email, 145 email_message.recipients(), 146 email_message.message().as_string()) 147 except: 148 if not self.fail_silently: 149 raise 150 return False 151 return True 152 153 class EmailMessage(object): 154 """ 155 A container for email information. 156 """ 157 def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, connection=None): 158 self.to = to or [] 159 self.bcc = bcc or [] 160 self.from_email = from_email or settings.DEFAULT_FROM_EMAIL 161 self.subject = subject 162 self.body = body 163 self.connection = connection 164 165 def get_connection(self, fail_silently=False): 166 if not self.connection: 167 self.connection = SMTPConnection(fail_silently=fail_silently) 168 return self.connection 169 170 def message(self): 171 msg = SafeMIMEText(self.body, 'plain', settings.DEFAULT_CHARSET) 172 msg['Subject'] = self.subject 173 msg['From'] = self.from_email 174 msg['To'] = ', '.join(self.to) 175 msg['Date'] = formatdate() 176 msg['Message-ID'] = make_msgid() 177 if self.bcc: 178 msg['Bcc'] = ', '.join(self.bcc) 179 return msg 180 181 def recipients(self): 182 """ 183 Returns a list of all recipients of the email (includes direct 184 addressees as well as Bcc entries). 185 """ 186 return self.to + self.bcc 187 188 def send(self, fail_silently=False): 189 """Send the email message.""" 190 return self.get_connection(fail_silently).send_messages([self]) 191 37 192 def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None): 38 193 """ … … 42 197 If auth_user is None, the EMAIL_HOST_USER setting is used. 43 198 If auth_password is None, the EMAIL_HOST_PASSWORD setting is used. 44 """ 45 return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password) 199 200 NOTE: This method is deprecated. It exists for backwards compatibility. 201 New code should use the EmailMessage class directly. 202 """ 203 connection = SMTPConnection(username=auth_user, password=auth_password, 204 fail_silently=fail_silently) 205 return EmailMessage(subject, message, from_email, recipient_list, connection=connection).send() 46 206 47 207 def send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None): … … 54 214 If auth_user is None, the EMAIL_HOST_USER setting is used. 55 215 If auth_password is None, the EMAIL_HOST_PASSWORD setting is used. 56 """ 57 if auth_user is None: 58 auth_user = settings.EMAIL_HOST_USER 59 if auth_password is None: 60 auth_password = settings.EMAIL_HOST_PASSWORD 61 try: 62 server = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT) 63 if auth_user and auth_password: 64 server.login(auth_user, auth_password) 65 except: 66 if fail_silently: 67 return 68 raise 69 num_sent = 0 70 for subject, message, from_email, recipient_list in datatuple: 71 if not recipient_list: 72 continue 73 from_email = from_email or settings.DEFAULT_FROM_EMAIL 74 msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET) 75 msg['Subject'] = subject 76 msg['From'] = from_email 77 msg['To'] = ', '.join(recipient_list) 78 msg['Date'] = formatdate() 79 try: 80 random_bits = str(random.getrandbits(64)) 81 except AttributeError: # Python 2.3 doesn't have random.getrandbits(). 82 random_bits = ''.join([random.choice('1234567890') for i in range(19)]) 83 msg['Message-ID'] = "<%d.%s@%s>" % (time.time(), random_bits, DNS_NAME) 84 try: 85 server.sendmail(from_email, recipient_list, msg.as_string()) 86 num_sent += 1 87 except: 88 if not fail_silently: 89 raise 90 try: 91 server.quit() 92 except: 93 if fail_silently: 94 return 95 raise 96 return num_sent 216 217 NOTE: This method is deprecated. It exists for backwards compatibility. 218 New code should use the EmailMessage class directly. 219 """ 220 connection = SMTPConnection(username=auth_user, password=auth_password, 221 fail_silently=fail_silently) 222 messages = [EmailMessage(subject, message, sender, recipient) for subject, message, sender, recipient in datatuple] 223 return connection.send_messages(messages) 97 224 98 225 def mail_admins(subject, message, fail_silently=False): 99 226 "Sends a message to the admins, as defined by the ADMINS setting." 100 send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS], fail_silently) 227 EmailMessage(settings.EMAIL_SUBJECT_PREFIX + subject, message, 228 settings.SERVER_EMAIL, [a[1] for a in 229 settings.ADMINS]).send(fail_silently=fail_silently) 101 230 102 231 def mail_managers(subject, message, fail_silently=False): 103 232 "Sends a message to the managers, as defined by the MANAGERS setting." 104 send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS], fail_silently) 233 EmailMessage(settings.EMAIL_SUBJECT_PREFIX + subject, message, 234 settings.SERVER_EMAIL, [a[1] for a in 235 settings.MANAGERS]).send(fail_silently=fail_silently) 236 django/branches/boulder-oracle-sprint/docs/documentation.txt
r4990 r5148 95 95 The text documentation is written in ReST (ReStructured Text) format. That 96 96 means it's easy to read but is also formatted in a way that makes it easy to 97 convert into other formats, such as HTML. If you're interested, the script that 98 converts the ReST text docs into djangoproject.com's HTML lives at 99 `djangoproject.com/django_website/apps/docs/parts/build_documentation.py`_ in 100 the Django Subversion repository. 97 convert into other formats, such as HTML. If you have the `reStructuredText`_ 98 library installed, you can use ``rst2html`` to generate your own HTML files. 101 99 102 .. _ djangoproject.com/django_website/apps/docs/parts/build_documentation.py: http://code.djangoproject.com/browser/djangoproject.com/django_website/apps/docs/parts/build_documentation.py100 .. _reStructuredText: http://docutils.sourceforge.net/rst.html 103 101 104 102 Differences between versions django/branches/boulder-oracle-sprint/docs/email.txt
r5128 r5148 23 23 Mail will be sent using the SMTP host and port specified in the `EMAIL_HOST`_ 24 24 and `EMAIL_PORT`_ settings. The `EMAIL_HOST_USER`_ and `EMAIL_HOST_PASSWORD`_ 25 settings, if set, will be used to authenticate to the SMTP server. 25 settings, if set, will be used to authenticate to the SMTP server and the 26 `EMAIL_USE_TLS`_ settings will control whether a secure connection is used. 26 27 27 28 .. note:: … … 35 36 .. _EMAIL_HOST_USER: ../settings/#email-host-user 36 37 .. _EMAIL_HOST_PASSWORD: ../settings/#email-host-password 38 .. _EMAIL_USE_TLS: ../settings/#email-use-tls 37 39 38 40 … … 184 186 185 187 .. _Header injection: http://securephp.damonkohler.com/index.php/Email_Injection 188 189 The EmailMessage and SMTPConnection classes 190 =========================================== 191 192 **New in Django development version** 193 194 Django's ``send_mail()`` and ``send_mass_mail()`` functions are actually thin 195 wrappers that make use of the ``EmailMessage`` and ``SMTPConnection`` classes 196 in ``django.mail``. If you ever need to customize the way Django sends email, 197 you can subclass these two classes to suit your needs. 198 199 .. note:: 200 Not all features of the ``EmailMessage`` class are available through the 201 ``send_mail()`` and related wrapper functions. If you wish to use advanced 202 features such as including BCC recipients or multi-part email, you will 203 need to create ``EmailMessage`` instances directly. 204 205 In general, ``EmailMessage`` is responsible for creating the email message 206 itself. ``SMTPConnection`` is responsible for the network connection side of 207 the operation. This means you can reuse the same connection (an 208 ``SMTPConnection`` instance) for multiple messages. 209 210 The ``EmailMessage`` class is initialised as follows:: 211 212 email = EmailMessage(subject, body, from_email, to, bcc, connection) 213 214 All of these parameters are optional. If ``from_email`` is omitted, the value 215 from ``settings.DEFAULT_FROM_EMAIL`` is used. Both the ``to`` and ``bcc`` 216 parameters are lists of addresses. 217 218 The class has the following methods that you can use: 219 220 * ``send()`` sends the message, using either the connection that is specified 221 in the ``connection`` attribute, or creating a new connection if none already 222 exists. 223 * ``message()`` constructs a ``django.core.mail.SafeMIMEText`` object (a 224 sub-class of Python's ``email.MIMEText.MIMEText`` class) holding the 225 message to be sent. If you ever need to extend the `EmailMessage` class, 226 you will probably want to override this method to put the content you wish 227 into the MIME object. 228 * ``recipients()`` returns a lists of all the recipients of the message, 229 whether they are recorded in the ``to`` or ``bcc`` attributes. This is 230 another method you need to possibly override when sub-classing, since the 231 SMTP server needs to be told the full list of recipients when the message 232 is sent. If you add another way to specify recipients in your class, they 233 need to be returned from this method as well. 234 235 The ``SMTPConnection`` class is initialized with the host, port, username and 236 password for the SMTP server. If you don't specify one or more of those 237 options, they are read from your settings file. 238 239 If you are sending lots of messages at once, the ``send_messages()`` method of 240 the ``SMTPConnection`` class will be useful. It takes a list of ``EmailMessage`` 241 instances (or sub-classes) and sends them over a single connection. For 242 example, if you have a function called ``get_notification_email()`` that returns a 243 list of ``EmailMessage`` objects representing some periodic email you wish to 244 send out, you could send this with:: 245 246 connection = SMTPConnection() # Use default settings for connection 247 messages = get_notification_email() 248 connection.send_messages(messages) 249 django/branches/boulder-oracle-sprint/docs/sessions.txt
r4842 r5148 108 108 109 109 def login(request): 110 m = members.get_object(username__exact=request.POST['username'])110 m = Member.objects.get(username=request.POST['username']) 111 111 if m.password == request.POST['password']: 112 112 request.session['member_id'] = m.id django/branches/boulder-oracle-sprint/docs/settings.txt
r5135 r5148 428 428 or ``django.core.mail.mail_managers``. You'll probably want to include the 429 429 trailing space. 430 431 EMAIL_USE_TLS 432 ------------- 433 434 **New in Django development version** 435 436 Default: ``False`` 437 438 Whether to use a TLS (secure) connection when talking to the SMTP server. 430 439 431 440 FIXTURE_DIRS django/branches/boulder-oracle-sprint/docs/syndication_feeds.txt
r5079 r5148 647 647 """ 648 648 Takes an item, as returned by items(), and returns the item's 649 enclosure mimetype.649 enclosure MIME type. 650 650 """ 651 651 652 652 def item_enclosure_mime_type(self): 653 653 """ 654 Returns the enclosure length, in bytes,for every item in the feed.655 """ 656 657 item_enclosure_mime_type = "audio/mpeg" # Hard-coded enclosure mime-type.654 Returns the enclosure MIME type for every item in the feed. 655 """ 656 657 item_enclosure_mime_type = "audio/mpeg" # Hard-coded enclosure MIME type. 658 658 659 659 # ITEM PUBDATE -- It's optional to use one of these three. This is a django/branches/boulder-oracle-sprint/docs/templates_python.txt
r5047 r5148 346 346 collects the user's messages and deletes them from the database. 347 347 348 Note that messages are set with ``user. add_message()``. See the348 Note that messages are set with ``user.message_set.create``. See the 349 349 `message docs`_ for more. 350 350
