17db96d56Sopenharmony_ci# Copyright (C) 2001-2006 Python Software Foundation
27db96d56Sopenharmony_ci# Author: Barry Warsaw
37db96d56Sopenharmony_ci# Contact: email-sig@python.org
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ci"""Various types of useful iterators and generators."""
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci__all__ = [
87db96d56Sopenharmony_ci    'body_line_iterator',
97db96d56Sopenharmony_ci    'typed_subpart_iterator',
107db96d56Sopenharmony_ci    'walk',
117db96d56Sopenharmony_ci    # Do not include _structure() since it's part of the debugging API.
127db96d56Sopenharmony_ci    ]
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ciimport sys
157db96d56Sopenharmony_cifrom io import StringIO
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci# This function will become a method of the Message class
207db96d56Sopenharmony_cidef walk(self):
217db96d56Sopenharmony_ci    """Walk over the message tree, yielding each subpart.
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci    The walk is performed in depth-first order.  This method is a
247db96d56Sopenharmony_ci    generator.
257db96d56Sopenharmony_ci    """
267db96d56Sopenharmony_ci    yield self
277db96d56Sopenharmony_ci    if self.is_multipart():
287db96d56Sopenharmony_ci        for subpart in self.get_payload():
297db96d56Sopenharmony_ci            yield from subpart.walk()
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci# These two functions are imported into the Iterators.py interface module.
347db96d56Sopenharmony_cidef body_line_iterator(msg, decode=False):
357db96d56Sopenharmony_ci    """Iterate over the parts, returning string payloads line-by-line.
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci    Optional decode (default False) is passed through to .get_payload().
387db96d56Sopenharmony_ci    """
397db96d56Sopenharmony_ci    for subpart in msg.walk():
407db96d56Sopenharmony_ci        payload = subpart.get_payload(decode=decode)
417db96d56Sopenharmony_ci        if isinstance(payload, str):
427db96d56Sopenharmony_ci            yield from StringIO(payload)
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_cidef typed_subpart_iterator(msg, maintype='text', subtype=None):
467db96d56Sopenharmony_ci    """Iterate over the subparts with a given MIME type.
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ci    Use `maintype' as the main MIME type to match against; this defaults to
497db96d56Sopenharmony_ci    "text".  Optional `subtype' is the MIME subtype to match against; if
507db96d56Sopenharmony_ci    omitted, only the main type is matched.
517db96d56Sopenharmony_ci    """
527db96d56Sopenharmony_ci    for subpart in msg.walk():
537db96d56Sopenharmony_ci        if subpart.get_content_maintype() == maintype:
547db96d56Sopenharmony_ci            if subtype is None or subpart.get_content_subtype() == subtype:
557db96d56Sopenharmony_ci                yield subpart
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_cidef _structure(msg, fp=None, level=0, include_default=False):
607db96d56Sopenharmony_ci    """A handy debugging aid"""
617db96d56Sopenharmony_ci    if fp is None:
627db96d56Sopenharmony_ci        fp = sys.stdout
637db96d56Sopenharmony_ci    tab = ' ' * (level * 4)
647db96d56Sopenharmony_ci    print(tab + msg.get_content_type(), end='', file=fp)
657db96d56Sopenharmony_ci    if include_default:
667db96d56Sopenharmony_ci        print(' [%s]' % msg.get_default_type(), file=fp)
677db96d56Sopenharmony_ci    else:
687db96d56Sopenharmony_ci        print(file=fp)
697db96d56Sopenharmony_ci    if msg.is_multipart():
707db96d56Sopenharmony_ci        for subpart in msg.get_payload():
717db96d56Sopenharmony_ci            _structure(subpart, fp, level+1, include_default)
72