Decode a message header value without converting charset. For historical reasons, this function may return either: 1. A list of length 1 containing a pair (str, None). 2. A list of (bytes, charset) pairs containing each of the decoded parts of the header. Charset is None for no
(header)
| 57 | |
| 58 | |
| 59 | def decode_header(header): |
| 60 | """Decode a message header value without converting charset. |
| 61 | |
| 62 | For historical reasons, this function may return either: |
| 63 | |
| 64 | 1. A list of length 1 containing a pair (str, None). |
| 65 | 2. A list of (bytes, charset) pairs containing each of the decoded |
| 66 | parts of the header. Charset is None for non-encoded parts of the header, |
| 67 | otherwise a lower-case string containing the name of the character set |
| 68 | specified in the encoded string. |
| 69 | |
| 70 | header may be a string that may or may not contain RFC2047 encoded words, |
| 71 | or it may be a Header object. |
| 72 | |
| 73 | An email.errors.HeaderParseError may be raised when certain decoding error |
| 74 | occurs (e.g. a base64 decoding exception). |
| 75 | |
| 76 | This function exists for backwards compatibility only. For new code, we |
| 77 | recommend using email.headerregistry.HeaderRegistry instead. |
| 78 | """ |
| 79 | # If it is a Header object, we can just return the encoded chunks. |
| 80 | if hasattr(header, '_chunks'): |
| 81 | return [(_charset._encode(string, str(charset)), str(charset)) |
| 82 | for string, charset in header._chunks] |
| 83 | # If no encoding, just return the header with no charset. |
| 84 | if not ecre.search(header): |
| 85 | return [(header, None)] |
| 86 | # First step is to parse all the encoded parts into triplets of the form |
| 87 | # (encoded_string, encoding, charset). For unencoded strings, the last |
| 88 | # two parts will be None. |
| 89 | words = [] |
| 90 | for line in header.splitlines(): |
| 91 | parts = ecre.split(line) |
| 92 | first = True |
| 93 | while parts: |
| 94 | unencoded = parts.pop(0) |
| 95 | if first: |
| 96 | unencoded = unencoded.lstrip() |
| 97 | first = False |
| 98 | if unencoded: |
| 99 | words.append((unencoded, None, None)) |
| 100 | if parts: |
| 101 | charset = parts.pop(0).lower() |
| 102 | encoding = parts.pop(0).lower() |
| 103 | encoded = parts.pop(0) |
| 104 | words.append((encoded, encoding, charset)) |
| 105 | # Now loop over words and remove words that consist of whitespace |
| 106 | # between two encoded strings. |
| 107 | droplist = [] |
| 108 | for n, w in enumerate(words): |
| 109 | if n>1 and w[1] and words[n-2][1] and words[n-1][0].isspace(): |
| 110 | droplist.append(n-1) |
| 111 | for d in reversed(droplist): |
| 112 | del words[d] |
| 113 | |
| 114 | # The next step is to decode each encoded word by applying the reverse |
| 115 | # base64 or quopri transformation. decoded_words is now a list of the |
| 116 | # form (decoded_word, charset). |
searching dependent graphs…