xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/email/parser.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
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