could in principle also catch part file decoding errors and return an error indicator string
(as we do for received mails in the mail fetcher ahead), but sending an invalid attach-
ment is much more grievous than displaying one. Instead, the send request fails entirely
on errors.
Finally, there is also new support for encoding non-ASCII headers (both full headers
and names of email addresses) per a client-selectable encoding that defaults to UTF-8,
and the sent message save file is opened in the same mailconfig Unicode encoding mode
used to decode messages when they are fetched.
The latter policy for sent mail saves is used because the sent file may be opened to fetch
full mail text in this encoding later by clients which apply this encoding scheme. This
is intended to mirror the way that clients such as PyMailGUI save full message text in
local files to be opened and parsed later. It might fail if the mail fetcher resorted to
guessing a different and incompatible encoding, and it assumes that no message gives
rise to incompatibly encoded data in the file across multiple sessions. We could instead
keep one save file per encoding, but encodings for full message text probably will not
vary; ASCII was the original standard for full mail text, so 7- or 8-bit text is likely.
Example 13-23. PP4E\Internet\Email\mailtools\mailSender.py
"""
###############################################################################
send messages, add attachments (see init for docs, test)
###############################################################################
"""
import mailconfig # client's mailconfig
import smtplib, os, mimetypes # mime: name to type
import email.utils, email.encoders # date string, base64
from .mailTool import MailTool, SilentMailTool # 4E: package-relative
from email.message import Message # general message, obj->text
from email.mime.multipart import MIMEMultipart # type-specific messages
from email.mime.audio import MIMEAudio # format/encode attachments
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.application import MIMEApplication # 4E: use new app class
def fix_encode_base64(msgobj):
"""
4E: workaround for a genuine bug in Python 3.1 email package that prevents
mail text generation for binary parts encoded with base64 or other email
encodings; the normal email.encoder run by the constructor leaves payload
as bytes, even though it's encoded to base64 text form; this breaks email
text generation which assumes this is text and requires it to be str; net
effect is that only simple text part emails can be composed in Py 3.1 email
package as is - any MIME-encoded binary part cause mail text generation to
fail; this bug seems likely to go away in a future Python and email package,
in which case this should become a no-op; see Chapter 13 for more details;
960 | Chapter 13: Client-Side Scripting