def parse_mimepart_address_header(mimepart, header_name): # type: (MimePart, str) -> List[List[str]] # Header parsing is complicated by the fact that: # (1) You can have multiple occurrences of the same header; # (2) Phrases or comments can be RFC2047-style encoded words; # (3) Everything is terrible. # Here, for each occurrence of the header in question, we first parse # it into a list of (phrase, addrspec) tuples and then use flanker to # decode any encoded words. # You want to do it in that order, because otherwise if you get a header # like # From: =?utf-8?Q?FooCorp=2C=20Inc.=? <*****@*****.**> # you can end up parsing 'FooCorp, Inc. <*****@*****.**> (note lack of # quoting) into two separate addresses. # Consult RFC822 Section 6.1 and RFC2047 section 5 for details. addresses = set() # type: Set[Tuple[str, str]] for section in mimepart.headers._v.getall(normalize(header_name)): for phrase, addrspec in email.utils.getaddresses([section]): if not addrspec and not phrase: continue addresses.add((decode(phrase), decode(addrspec))) # Return a list of lists because it makes it easier to compare an address # field to one which has been fetched from the db. return sorted(list(elem) for elem in addresses)
def parse_address_hval(hval): """ Given a address collection header value, parse out the name/email pairs into a list of (name, email) :param string hval: Email address strings :return set[string, string] """ addresses = set() for phrase, addrspec in rfc822.AddressList(hval).addresslist: addresses.add((decode(phrase), decode(addrspec))) return sorted(elem for elem in addresses)
def get(self, key, default=None): """ Returns header value (case-insensitive). """ v = self._v.get(normalize(key), default) if v is not None: return encodedword.decode(v) return None
def iteritems(self, raw=False): """ Returns iterator header,val pairs in the preserved order. """ if raw: return self._v.iteritems() return iter([(x[0], encodedword.decode(x[1])) for x in self._v.iteritems()])
def parse_mimepart_address_header(mimepart, header_name): # Header parsing is complicated by the fact that: # (1) You can have multiple occurrences of the same header; # (2) Phrases or comments can be RFC2047-style encoded words; # (3) Everything is terrible. # Here, for each occurrence of the header in question, we first parse # it into a list of (phrase, addrspec) tuples and then use flanker to # decode any encoded words. # You want to do it in that order, because otherwise if you get a header # like # From: =?utf-8?Q?FooCorp=2C=20Inc.=? <*****@*****.**> # you can end up parsing 'FooCorp, Inc. <*****@*****.**> (note lack of # quoting) into two separate addresses. # Consult RFC822 Section 6.1 and RFC2047 section 5 for details. addresses = set() for section in mimepart.headers._v.getall(normalize(header_name)): for phrase, addrspec in rfc822.AddressList(section).addresslist: addresses.add((decode(phrase), decode(addrspec))) # Return a list of lists because it makes it easier to compare an address # field to one which has been fetched from the db. return sorted(list(elem) for elem in addresses)
def parse_header_value(name, val): if not is_pure_ascii(val): if parametrized.is_parametrized(name, val): raise DecodingError("Unsupported value in content- header") return to_unicode(val) else: if parametrized.is_parametrized(name, val): val, params = parametrized.decode(val) if name == 'Content-Type': main, sub = parametrized.fix_content_type(val) return ContentType(main, sub, params) else: return WithParams(val, params) elif "=?" in val: # may be encoded word return encodedword.decode(val) else: return val
def parse_header_value(name, val): if not is_pure_ascii(val): if parametrized.is_parametrized(name, val): raise DecodingError("Unsupported value in content- header") return to_unicode(val) else: if parametrized.is_parametrized(name, val): val, params = parametrized.decode(val) if name == 'Content-Type': main, sub = parametrized.fix_content_type(val) return ContentType(main, sub, params) else: return WithParams(val, params) elif "=?" in val: # may be encoded word return encodedword.decode(val) else: return val
def __getitem__(self, key): v = self._v.get(normalize(key), None) if v is not None: return encodedword.decode(v) return None
def getall(self, key): """ Returns all header values by the given header name (case-insensitive). """ v = self._v.getall(normalize(key)) return [encodedword.decode(x) for x in v]