1*cda5da8dSAndroid Build Coastguard Worker# Copyright (C) 2001-2007 Python Software Foundation 2*cda5da8dSAndroid Build Coastguard Worker# Author: Barry Warsaw, Thomas Wouters, Anthony Baxter 3*cda5da8dSAndroid Build Coastguard Worker# Contact: [email protected] 4*cda5da8dSAndroid Build Coastguard Worker 5*cda5da8dSAndroid Build Coastguard Worker"""A parser of RFC 2822 and MIME email messages.""" 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard Worker__all__ = ['Parser', 'HeaderParser', 'BytesParser', 'BytesHeaderParser', 8*cda5da8dSAndroid Build Coastguard Worker 'FeedParser', 'BytesFeedParser'] 9*cda5da8dSAndroid Build Coastguard Worker 10*cda5da8dSAndroid Build Coastguard Workerfrom io import StringIO, TextIOWrapper 11*cda5da8dSAndroid Build Coastguard Worker 12*cda5da8dSAndroid Build Coastguard Workerfrom email.feedparser import FeedParser, BytesFeedParser 13*cda5da8dSAndroid Build Coastguard Workerfrom email._policybase import compat32 14*cda5da8dSAndroid Build Coastguard Worker 15*cda5da8dSAndroid Build Coastguard Worker 16*cda5da8dSAndroid Build Coastguard Workerclass Parser: 17*cda5da8dSAndroid Build Coastguard Worker def __init__(self, _class=None, *, policy=compat32): 18*cda5da8dSAndroid Build Coastguard Worker """Parser of RFC 2822 and MIME email messages. 19*cda5da8dSAndroid Build Coastguard Worker 20*cda5da8dSAndroid Build Coastguard Worker Creates an in-memory object tree representing the email message, which 21*cda5da8dSAndroid Build Coastguard Worker can then be manipulated and turned over to a Generator to return the 22*cda5da8dSAndroid Build Coastguard Worker textual representation of the message. 23*cda5da8dSAndroid Build Coastguard Worker 24*cda5da8dSAndroid Build Coastguard Worker The string must be formatted as a block of RFC 2822 headers and header 25*cda5da8dSAndroid Build Coastguard Worker continuation lines, optionally preceded by a `Unix-from' header. The 26*cda5da8dSAndroid Build Coastguard Worker header block is terminated either by the end of the string or by a 27*cda5da8dSAndroid Build Coastguard Worker blank line. 28*cda5da8dSAndroid Build Coastguard Worker 29*cda5da8dSAndroid Build Coastguard Worker _class is the class to instantiate for new message objects when they 30*cda5da8dSAndroid Build Coastguard Worker must be created. This class must have a constructor that can take 31*cda5da8dSAndroid Build Coastguard Worker zero arguments. Default is Message.Message. 32*cda5da8dSAndroid Build Coastguard Worker 33*cda5da8dSAndroid Build Coastguard Worker The policy keyword specifies a policy object that controls a number of 34*cda5da8dSAndroid Build Coastguard Worker aspects of the parser's operation. The default policy maintains 35*cda5da8dSAndroid Build Coastguard Worker backward compatibility. 36*cda5da8dSAndroid Build Coastguard Worker 37*cda5da8dSAndroid Build Coastguard Worker """ 38*cda5da8dSAndroid Build Coastguard Worker self._class = _class 39*cda5da8dSAndroid Build Coastguard Worker self.policy = policy 40*cda5da8dSAndroid Build Coastguard Worker 41*cda5da8dSAndroid Build Coastguard Worker def parse(self, fp, headersonly=False): 42*cda5da8dSAndroid Build Coastguard Worker """Create a message structure from the data in a file. 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard Worker Reads all the data from the file and returns the root of the message 45*cda5da8dSAndroid Build Coastguard Worker structure. Optional headersonly is a flag specifying whether to stop 46*cda5da8dSAndroid Build Coastguard Worker parsing after reading the headers or not. The default is False, 47*cda5da8dSAndroid Build Coastguard Worker meaning it parses the entire contents of the file. 48*cda5da8dSAndroid Build Coastguard Worker """ 49*cda5da8dSAndroid Build Coastguard Worker feedparser = FeedParser(self._class, policy=self.policy) 50*cda5da8dSAndroid Build Coastguard Worker if headersonly: 51*cda5da8dSAndroid Build Coastguard Worker feedparser._set_headersonly() 52*cda5da8dSAndroid Build Coastguard Worker while True: 53*cda5da8dSAndroid Build Coastguard Worker data = fp.read(8192) 54*cda5da8dSAndroid Build Coastguard Worker if not data: 55*cda5da8dSAndroid Build Coastguard Worker break 56*cda5da8dSAndroid Build Coastguard Worker feedparser.feed(data) 57*cda5da8dSAndroid Build Coastguard Worker return feedparser.close() 58*cda5da8dSAndroid Build Coastguard Worker 59*cda5da8dSAndroid Build Coastguard Worker def parsestr(self, text, headersonly=False): 60*cda5da8dSAndroid Build Coastguard Worker """Create a message structure from a string. 61*cda5da8dSAndroid Build Coastguard Worker 62*cda5da8dSAndroid Build Coastguard Worker Returns the root of the message structure. Optional headersonly is a 63*cda5da8dSAndroid Build Coastguard Worker flag specifying whether to stop parsing after reading the headers or 64*cda5da8dSAndroid Build Coastguard Worker not. The default is False, meaning it parses the entire contents of 65*cda5da8dSAndroid Build Coastguard Worker the file. 66*cda5da8dSAndroid Build Coastguard Worker """ 67*cda5da8dSAndroid Build Coastguard Worker return self.parse(StringIO(text), headersonly=headersonly) 68*cda5da8dSAndroid Build Coastguard Worker 69*cda5da8dSAndroid Build Coastguard Worker 70*cda5da8dSAndroid Build Coastguard Worker 71*cda5da8dSAndroid Build Coastguard Workerclass HeaderParser(Parser): 72*cda5da8dSAndroid Build Coastguard Worker def parse(self, fp, headersonly=True): 73*cda5da8dSAndroid Build Coastguard Worker return Parser.parse(self, fp, True) 74*cda5da8dSAndroid Build Coastguard Worker 75*cda5da8dSAndroid Build Coastguard Worker def parsestr(self, text, headersonly=True): 76*cda5da8dSAndroid Build Coastguard Worker return Parser.parsestr(self, text, True) 77*cda5da8dSAndroid Build Coastguard Worker 78*cda5da8dSAndroid Build Coastguard Worker 79*cda5da8dSAndroid Build Coastguard Workerclass BytesParser: 80*cda5da8dSAndroid Build Coastguard Worker 81*cda5da8dSAndroid Build Coastguard Worker def __init__(self, *args, **kw): 82*cda5da8dSAndroid Build Coastguard Worker """Parser of binary RFC 2822 and MIME email messages. 83*cda5da8dSAndroid Build Coastguard Worker 84*cda5da8dSAndroid Build Coastguard Worker Creates an in-memory object tree representing the email message, which 85*cda5da8dSAndroid Build Coastguard Worker can then be manipulated and turned over to a Generator to return the 86*cda5da8dSAndroid Build Coastguard Worker textual representation of the message. 87*cda5da8dSAndroid Build Coastguard Worker 88*cda5da8dSAndroid Build Coastguard Worker The input must be formatted as a block of RFC 2822 headers and header 89*cda5da8dSAndroid Build Coastguard Worker continuation lines, optionally preceded by a `Unix-from' header. The 90*cda5da8dSAndroid Build Coastguard Worker header block is terminated either by the end of the input or by a 91*cda5da8dSAndroid Build Coastguard Worker blank line. 92*cda5da8dSAndroid Build Coastguard Worker 93*cda5da8dSAndroid Build Coastguard Worker _class is the class to instantiate for new message objects when they 94*cda5da8dSAndroid Build Coastguard Worker must be created. This class must have a constructor that can take 95*cda5da8dSAndroid Build Coastguard Worker zero arguments. Default is Message.Message. 96*cda5da8dSAndroid Build Coastguard Worker """ 97*cda5da8dSAndroid Build Coastguard Worker self.parser = Parser(*args, **kw) 98*cda5da8dSAndroid Build Coastguard Worker 99*cda5da8dSAndroid Build Coastguard Worker def parse(self, fp, headersonly=False): 100*cda5da8dSAndroid Build Coastguard Worker """Create a message structure from the data in a binary file. 101*cda5da8dSAndroid Build Coastguard Worker 102*cda5da8dSAndroid Build Coastguard Worker Reads all the data from the file and returns the root of the message 103*cda5da8dSAndroid Build Coastguard Worker structure. Optional headersonly is a flag specifying whether to stop 104*cda5da8dSAndroid Build Coastguard Worker parsing after reading the headers or not. The default is False, 105*cda5da8dSAndroid Build Coastguard Worker meaning it parses the entire contents of the file. 106*cda5da8dSAndroid Build Coastguard Worker """ 107*cda5da8dSAndroid Build Coastguard Worker fp = TextIOWrapper(fp, encoding='ascii', errors='surrogateescape') 108*cda5da8dSAndroid Build Coastguard Worker try: 109*cda5da8dSAndroid Build Coastguard Worker return self.parser.parse(fp, headersonly) 110*cda5da8dSAndroid Build Coastguard Worker finally: 111*cda5da8dSAndroid Build Coastguard Worker fp.detach() 112*cda5da8dSAndroid Build Coastguard Worker 113*cda5da8dSAndroid Build Coastguard Worker 114*cda5da8dSAndroid Build Coastguard Worker def parsebytes(self, text, headersonly=False): 115*cda5da8dSAndroid Build Coastguard Worker """Create a message structure from a byte string. 116*cda5da8dSAndroid Build Coastguard Worker 117*cda5da8dSAndroid Build Coastguard Worker Returns the root of the message structure. Optional headersonly is a 118*cda5da8dSAndroid Build Coastguard Worker flag specifying whether to stop parsing after reading the headers or 119*cda5da8dSAndroid Build Coastguard Worker not. The default is False, meaning it parses the entire contents of 120*cda5da8dSAndroid Build Coastguard Worker the file. 121*cda5da8dSAndroid Build Coastguard Worker """ 122*cda5da8dSAndroid Build Coastguard Worker text = text.decode('ASCII', errors='surrogateescape') 123*cda5da8dSAndroid Build Coastguard Worker return self.parser.parsestr(text, headersonly) 124*cda5da8dSAndroid Build Coastguard Worker 125*cda5da8dSAndroid Build Coastguard Worker 126*cda5da8dSAndroid Build Coastguard Workerclass BytesHeaderParser(BytesParser): 127*cda5da8dSAndroid Build Coastguard Worker def parse(self, fp, headersonly=True): 128*cda5da8dSAndroid Build Coastguard Worker return BytesParser.parse(self, fp, headersonly=True) 129*cda5da8dSAndroid Build Coastguard Worker 130*cda5da8dSAndroid Build Coastguard Worker def parsebytes(self, text, headersonly=True): 131*cda5da8dSAndroid Build Coastguard Worker return BytesParser.parsebytes(self, text, headersonly=True) 132