l.s.m.sendmail : module documentation

Part of lp.services.mail

The One True Way to send mail from the Launchpad application.

Uses zope.sendmail.interfaces.IMailer, so you can subscribe to IMailSentEvent or IMailErrorEvent to record status.

TODO: We should append a signature to messages sent through simple_sendmail and sendmail with a message explaining 'this came from launchpad' and a link to click on to change their messaging settings -- stub 2004-10-21

Function do_paranoid_email_content_validation Validate various bits of the email.
Function do_paranoid_envelope_to_validation Ensure the envelope_to addresses are valid.
Function append_footer Append a footer to an email, following signature conventions.
Function format_address Formats a name and address to be used as an email header.
Function format_address_for_person Helper function to call format_address for a person.
Function set_immediate_mail_delivery Enable or disable immediate mail delivery.
Function simple_sendmail Send an email from from_addr to to_addrs with the subject and body
Class MailController Message generation interface closer to peoples' mental model.
Function simple_sendmail_from_person Sends a mail using the given person as the From address.
Function get_addresses_from_header Get the email addresses specificed in an email header.
Function validate_message Validate that the supplied message is suitable for sending.
Function sendmail Send an email.message.Message
Function get_msgid Undocumented
Function raw_sendmail Send a raw RFC8222 email message.
def do_paranoid_email_content_validation(from_addr, to_addrs, subject, body):
Validate various bits of the email.

Extremely paranoid parameter checking is required to ensure we raise an exception rather than stick garbage in the mail queue. Currently, the Z3 mailer is too forgiving and accepts badly formatted emails which the delivery mechanism then can't send.

An AssertionError will be raised if one of the parameters is invalid.

def do_paranoid_envelope_to_validation(to_addrs):
Ensure the envelope_to addresses are valid.

This is extracted from do_paranoid_email_content_validation, so that it can be applied to the actual envelope_to addresses, not the to header. The to header and envelope_to addresses may vary independently, and the to header cannot break Z3.

def append_footer(main, footer):
Append a footer to an email, following signature conventions.

    If there is no footer, do nothing.
    If there is already a signature, append an additional footer.
    If there is no existing signature, append '-- 
' and a footer.

    :param main: The main content, which may have a signature.
    :param footer: An additional footer to append.
    :return: a new version of main that includes the footer.
    
def format_address(name, address):

Formats a name and address to be used as an email header.

>>> format_address('Name', 'foo@bar.com')
'Name <foo@bar.com>'
>>> format_address('', 'foo@bar.com')
'foo@bar.com'
>>> format_address(None, u'foo@bar.com')
'foo@bar.com'

It handles unicode and characters that need quoting as well.

>>> format_address(u'F\xf4\xf4 Bar', 'foo.bar@canonical.com')
'=?utf-8?b?RsO0w7QgQmFy?= <foo.bar@canonical.com>'
>>> format_address('Foo [Baz] Bar', 'foo.bar@canonical.com')
'"Foo \\[Baz\\] Bar" <foo.bar@canonical.com>'

Really long names doesn't get folded, since we're not constructing an email header here.

>>> formatted_address = format_address(
...     'a '*100, 'long.name@example.com')
>>> '\n' in formatted_address
False
def format_address_for_person(person):
Helper function to call format_address for a person.
def set_immediate_mail_delivery(enabled):
Enable or disable immediate mail delivery.

Mail is by default queued until the transaction is committed. But if a script requires that mail violate transactions, immediate mail delivery can be enabled.

def simple_sendmail(from_addr, to_addrs, subject, body, headers=None, bulk=True):
Send an email from from_addr to to_addrs with the subject and body provided. to_addrs can be a list, tuple, or ASCII string.

Arbitrary headers can be set using the headers parameter. If the value for a given key in the headers dict is a list or tuple, the header will be added to the message once for each value in the list.

Note however that the Precedence header will be set to bulk by default, overriding any Precedence header in headers.

Returns the Message-Id.

def simple_sendmail_from_person(person, to_addrs, subject, body, headers=None):
Sends a mail using the given person as the From address.

It works just like simple_sendmail, excepts that it ensures that the From header is properly encoded.

def get_addresses_from_header(email_header):

Get the email addresses specificed in an email header.

>>> get_addresses_from_header('one@example.com')
['one@example.com']
>>> get_addresses_from_header('one@example.com, two@example.com')
['one@example.com', 'two@example.com']
>>> get_addresses_from_header('One\n <one@example.com>')
['One <one@example.com>']
>>> get_addresses_from_header('One\r\n <one@example.com>')
['One <one@example.com>']
>>> get_addresses_from_header(
...     '"One, A" <one.a@example.com>,\n'
...     ' "Two, B" <two.b@example.com>')
['"One, A" <one.a@example.com>', '"Two, B" <two.b@example.com>']
def validate_message(message):
Validate that the supplied message is suitable for sending.
def sendmail(message, to_addrs=None, bulk=True):
Send an email.message.Message

If you just need to send dumb ASCII or Unicode, simple_sendmail will be easier for you. Sending attachments or multipart messages will need to use this method.

From:, To: and Subject: headers should already be set. Message-Id:, Date:, and Reply-To: headers will be set if they are not already. Errors-To: and Return-Path: headers will always be set. The more we look valid, the less we look like spam.

If to_addrs is None, the message will be sent to all the addresses specified in the To: and CC: headers.

Uses zope.sendmail.interfaces.IMailer, so you can subscribe to IMailSentEvent or IMailErrorEvent to record status.

This function looks at the config singleton for configuration as to where to send the mail; in particular for whether this code is running in zopeless mode, and for a sendmail_to_stdout attribute for testing.

Returns the Message-Id

ParametersbulkBy default, a Precedence: bulk header is added to the message. Pass False to disable this.
def get_msgid():
Undocumented
def raw_sendmail(from_addr, to_addrs, raw_message, message_detail):
Send a raw RFC8222 email message.

All headers and encoding should already be done, as the message is spooled out verbatim to the delivery agent.

You should not need to call this method directly, although it may be necessary to pass on signed or encrypted messages.

Returns the message-id.

Parametersmessage_detailString of detail about the message to be recorded to help with debugging, eg the message subject.
API Documentation for Launchpad, generated by pydoctor at 2022-06-16 00:00:12.