1*cda5da8dSAndroid Build Coastguard Worker# Copyright (C) 2001-2006 Python Software Foundation 2*cda5da8dSAndroid Build Coastguard Worker# Author: Barry Warsaw 3*cda5da8dSAndroid Build Coastguard Worker# Contact: [email protected] 4*cda5da8dSAndroid Build Coastguard Worker 5*cda5da8dSAndroid Build Coastguard Worker"""Various types of useful iterators and generators.""" 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard Worker__all__ = [ 8*cda5da8dSAndroid Build Coastguard Worker 'body_line_iterator', 9*cda5da8dSAndroid Build Coastguard Worker 'typed_subpart_iterator', 10*cda5da8dSAndroid Build Coastguard Worker 'walk', 11*cda5da8dSAndroid Build Coastguard Worker # Do not include _structure() since it's part of the debugging API. 12*cda5da8dSAndroid Build Coastguard Worker ] 13*cda5da8dSAndroid Build Coastguard Worker 14*cda5da8dSAndroid Build Coastguard Workerimport sys 15*cda5da8dSAndroid Build Coastguard Workerfrom io import StringIO 16*cda5da8dSAndroid Build Coastguard Worker 17*cda5da8dSAndroid Build Coastguard Worker 18*cda5da8dSAndroid Build Coastguard Worker 19*cda5da8dSAndroid Build Coastguard Worker# This function will become a method of the Message class 20*cda5da8dSAndroid Build Coastguard Workerdef walk(self): 21*cda5da8dSAndroid Build Coastguard Worker """Walk over the message tree, yielding each subpart. 22*cda5da8dSAndroid Build Coastguard Worker 23*cda5da8dSAndroid Build Coastguard Worker The walk is performed in depth-first order. This method is a 24*cda5da8dSAndroid Build Coastguard Worker generator. 25*cda5da8dSAndroid Build Coastguard Worker """ 26*cda5da8dSAndroid Build Coastguard Worker yield self 27*cda5da8dSAndroid Build Coastguard Worker if self.is_multipart(): 28*cda5da8dSAndroid Build Coastguard Worker for subpart in self.get_payload(): 29*cda5da8dSAndroid Build Coastguard Worker yield from subpart.walk() 30*cda5da8dSAndroid Build Coastguard Worker 31*cda5da8dSAndroid Build Coastguard Worker 32*cda5da8dSAndroid Build Coastguard Worker 33*cda5da8dSAndroid Build Coastguard Worker# These two functions are imported into the Iterators.py interface module. 34*cda5da8dSAndroid Build Coastguard Workerdef body_line_iterator(msg, decode=False): 35*cda5da8dSAndroid Build Coastguard Worker """Iterate over the parts, returning string payloads line-by-line. 36*cda5da8dSAndroid Build Coastguard Worker 37*cda5da8dSAndroid Build Coastguard Worker Optional decode (default False) is passed through to .get_payload(). 38*cda5da8dSAndroid Build Coastguard Worker """ 39*cda5da8dSAndroid Build Coastguard Worker for subpart in msg.walk(): 40*cda5da8dSAndroid Build Coastguard Worker payload = subpart.get_payload(decode=decode) 41*cda5da8dSAndroid Build Coastguard Worker if isinstance(payload, str): 42*cda5da8dSAndroid Build Coastguard Worker yield from StringIO(payload) 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard Worker 45*cda5da8dSAndroid Build Coastguard Workerdef typed_subpart_iterator(msg, maintype='text', subtype=None): 46*cda5da8dSAndroid Build Coastguard Worker """Iterate over the subparts with a given MIME type. 47*cda5da8dSAndroid Build Coastguard Worker 48*cda5da8dSAndroid Build Coastguard Worker Use `maintype' as the main MIME type to match against; this defaults to 49*cda5da8dSAndroid Build Coastguard Worker "text". Optional `subtype' is the MIME subtype to match against; if 50*cda5da8dSAndroid Build Coastguard Worker omitted, only the main type is matched. 51*cda5da8dSAndroid Build Coastguard Worker """ 52*cda5da8dSAndroid Build Coastguard Worker for subpart in msg.walk(): 53*cda5da8dSAndroid Build Coastguard Worker if subpart.get_content_maintype() == maintype: 54*cda5da8dSAndroid Build Coastguard Worker if subtype is None or subpart.get_content_subtype() == subtype: 55*cda5da8dSAndroid Build Coastguard Worker yield subpart 56*cda5da8dSAndroid Build Coastguard Worker 57*cda5da8dSAndroid Build Coastguard Worker 58*cda5da8dSAndroid Build Coastguard Worker 59*cda5da8dSAndroid Build Coastguard Workerdef _structure(msg, fp=None, level=0, include_default=False): 60*cda5da8dSAndroid Build Coastguard Worker """A handy debugging aid""" 61*cda5da8dSAndroid Build Coastguard Worker if fp is None: 62*cda5da8dSAndroid Build Coastguard Worker fp = sys.stdout 63*cda5da8dSAndroid Build Coastguard Worker tab = ' ' * (level * 4) 64*cda5da8dSAndroid Build Coastguard Worker print(tab + msg.get_content_type(), end='', file=fp) 65*cda5da8dSAndroid Build Coastguard Worker if include_default: 66*cda5da8dSAndroid Build Coastguard Worker print(' [%s]' % msg.get_default_type(), file=fp) 67*cda5da8dSAndroid Build Coastguard Worker else: 68*cda5da8dSAndroid Build Coastguard Worker print(file=fp) 69*cda5da8dSAndroid Build Coastguard Worker if msg.is_multipart(): 70*cda5da8dSAndroid Build Coastguard Worker for subpart in msg.get_payload(): 71*cda5da8dSAndroid Build Coastguard Worker _structure(subpart, fp, level+1, include_default) 72