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