bytes in parts list if any encodings found (with unencoded parts encoded as
raw-unicode-escape and enc=None) but returns a single part with enc=None
that is str instead of bytes in Py3.1 if the entire header is unencoded
(must handle mixed types here); see Chapter 13 for more details/examples;
the following first attempt code was okay unless any encoded substrings, or
enc was returned as None (raised except which returned rawheader unchanged):
hdr, enc = email.header.decode_header(rawheader)[0]
return hdr.decode(enc) # fails if enc=None: no encoding or encoded substrs
"""
try:
parts = email.header.decode_header(rawheader)
decoded = []
for (part, enc) in parts: # for all substrings
if enc == None: # part unencoded?
if not isinstance(part, bytes): # str: full hdr unencoded
decoded += [part] # else do unicode decode
else:
decoded += [part.decode('raw-unicode-escape')]
else:
decoded += [part.decode(enc)]
return ' '.join(decoded)
except:
return rawheader # punt!
def decodeAddrHeader(self, rawheader):
"""
4E: decode existing i18n address header text per email and Unicode,
according to its content; must parse out first part of email address
to get i18n part: '"=?UTF-8?Q?Walmart?=" [email protected]';
From will probably have just 1 addr, but To, Cc, Bcc may have many;
decodeHeader handles nested encoded substrings within an entire hdr,
but we can't simply call it for entire hdr here because it fails if
encoded name substring ends in " quote instead of whitespace or endstr;
see also encodeAddrHeader in mailSender module for the inverse of this;
the following first attempt code failed to handle encoded substrings in
name, and raised exc for unencoded bytes parts if any encoded substrings;
namebytes, nameenc = email.header.decode_header(name)[0] (do email+MIME)
if nameenc: name = namebytes.decode(nameenc) (do Unicode?)
"""
try:
pairs = email.utils.getaddresses([rawheader]) # split addrs and parts
decoded = [] # handles name commas
for (name, addr) in pairs:
try:
name = self.decodeHeader(name) # email+MIME+Uni
except:
name = None # but uses encooded name if exc in decodeHeader
joined = email.utils.formataddr((name, addr)) # join parts
decoded.append(joined)
return ', '.join(decoded) # >= 1 addrs
except:
return self.decodeHeader(rawheader) # try decoding entire string
The mailtools Utility Package | 981