| | |
| | |
| | |
| |
|
| | """Various types of useful iterators and generators.""" |
| |
|
| | __all__ = [ |
| | 'body_line_iterator', |
| | 'typed_subpart_iterator', |
| | 'walk', |
| | |
| | ] |
| |
|
| | import sys |
| | from io import StringIO |
| |
|
| |
|
| | |
| | |
| | def walk(self): |
| | """Walk over the message tree, yielding each subpart. |
| | |
| | The walk is performed in depth-first order. This method is a |
| | generator. |
| | """ |
| | yield self |
| | if self.is_multipart(): |
| | for subpart in self.get_payload(): |
| | yield from subpart.walk() |
| |
|
| |
|
| | |
| | |
| | def body_line_iterator(msg, decode=False): |
| | """Iterate over the parts, returning string payloads line-by-line. |
| | |
| | Optional decode (default False) is passed through to .get_payload(). |
| | """ |
| | for subpart in msg.walk(): |
| | payload = subpart.get_payload(decode=decode) |
| | if isinstance(payload, str): |
| | yield from StringIO(payload) |
| |
|
| |
|
| | def typed_subpart_iterator(msg, maintype='text', subtype=None): |
| | """Iterate over the subparts with a given MIME type. |
| | |
| | Use `maintype' as the main MIME type to match against; this defaults to |
| | "text". Optional `subtype' is the MIME subtype to match against; if |
| | omitted, only the main type is matched. |
| | """ |
| | for subpart in msg.walk(): |
| | if subpart.get_content_maintype() == maintype: |
| | if subtype is None or subpart.get_content_subtype() == subtype: |
| | yield subpart |
| |
|
| |
|
| | |
| | def _structure(msg, fp=None, level=0, include_default=False): |
| | """A handy debugging aid""" |
| | if fp is None: |
| | fp = sys.stdout |
| | tab = ' ' * (level * 4) |
| | print(tab + msg.get_content_type(), end='', file=fp) |
| | if include_default: |
| | print(' [%s]' % msg.get_default_type(), file=fp) |
| | else: |
| | print(file=fp) |
| | if msg.is_multipart(): |
| | for subpart in msg.get_payload(): |
| | _structure(subpart, fp, level+1, include_default) |
| |
|