Converts message to a bytestring and passes it to sendmail. The arguments are as for sendmail, except that msg is an email.message.Message object. If from_addr is None or to_addrs is None, these arguments are taken from the headers of the Message as described in RFC
(self, msg, from_addr=None, to_addrs=None,
mail_options=(), rcpt_options=())
| 911 | return senderrs |
| 912 | |
| 913 | def send_message(self, msg, from_addr=None, to_addrs=None, |
| 914 | mail_options=(), rcpt_options=()): |
| 915 | """Converts message to a bytestring and passes it to sendmail. |
| 916 | |
| 917 | The arguments are as for sendmail, except that msg is an |
| 918 | email.message.Message object. If from_addr is None or to_addrs is |
| 919 | None, these arguments are taken from the headers of the Message as |
| 920 | described in RFC 5322 (a ValueError is raised if there is more than |
| 921 | one set of 'Resent-' headers). Regardless of the values of from_addr and |
| 922 | to_addr, any Bcc field (or Resent-Bcc field, when the Message is a |
| 923 | resent) of the Message object won't be transmitted. The Message |
| 924 | object is then serialized using email.generator.BytesGenerator and |
| 925 | sendmail is called to transmit the message. If the sender or any of |
| 926 | the recipient addresses contain non-ASCII and the server advertises the |
| 927 | SMTPUTF8 capability, the policy is cloned with utf8 set to True for the |
| 928 | serialization, and SMTPUTF8 and BODY=8BITMIME are asserted on the send. |
| 929 | If the server does not support SMTPUTF8, an SMTPNotSupported error is |
| 930 | raised. Otherwise the generator is called without modifying the |
| 931 | policy. |
| 932 | |
| 933 | """ |
| 934 | # 'Resent-Date' is a mandatory field if the Message is resent (RFC 5322 |
| 935 | # Section 3.6.6). In such a case, we use the 'Resent-*' fields. However, |
| 936 | # if there is more than one 'Resent-' block there's no way to |
| 937 | # unambiguously determine which one is the most recent in all cases, |
| 938 | # so rather than guess we raise a ValueError in that case. |
| 939 | # |
| 940 | # TODO implement heuristics to guess the correct Resent-* block with an |
| 941 | # option allowing the user to enable the heuristics. (It should be |
| 942 | # possible to guess correctly almost all of the time.) |
| 943 | |
| 944 | self.ehlo_or_helo_if_needed() |
| 945 | resent = msg.get_all('Resent-Date') |
| 946 | if resent is None: |
| 947 | header_prefix = '' |
| 948 | elif len(resent) == 1: |
| 949 | header_prefix = 'Resent-' |
| 950 | else: |
| 951 | raise ValueError("message has more than one 'Resent-' header block") |
| 952 | if from_addr is None: |
| 953 | # Prefer the sender field per RFC 5322 section 3.6.2. |
| 954 | from_addr = (msg[header_prefix + 'Sender'] |
| 955 | if (header_prefix + 'Sender') in msg |
| 956 | else msg[header_prefix + 'From']) |
| 957 | from_addr = email.utils.getaddresses([from_addr])[0][1] |
| 958 | if to_addrs is None: |
| 959 | addr_fields = [f for f in (msg[header_prefix + 'To'], |
| 960 | msg[header_prefix + 'Bcc'], |
| 961 | msg[header_prefix + 'Cc']) |
| 962 | if f is not None] |
| 963 | to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)] |
| 964 | # Make a local copy so we can delete the bcc headers. |
| 965 | msg_copy = copy.copy(msg) |
| 966 | del msg_copy['Bcc'] |
| 967 | del msg_copy['Resent-Bcc'] |
| 968 | international = False |
| 969 | try: |
| 970 | ''.join([from_addr, *to_addrs]).encode('ascii') |