diff options
-rw-r--r-- | Doc/library/mimetools.rst | 131 | ||||
-rw-r--r-- | Doc/library/netdata.rst | 1 | ||||
-rw-r--r-- | Lib/mimetools.py | 240 | ||||
-rw-r--r-- | Lib/test/test_mimetools.py | 76 | ||||
-rw-r--r-- | Misc/NEWS | 2 |
5 files changed, 2 insertions, 448 deletions
diff --git a/Doc/library/mimetools.rst b/Doc/library/mimetools.rst deleted file mode 100644 index 7813867..0000000 --- a/Doc/library/mimetools.rst +++ /dev/null @@ -1,131 +0,0 @@ - -:mod:`mimetools` --- Tools for parsing MIME messages -==================================================== - -.. module:: mimetools - :synopsis: Tools for parsing MIME-style message bodies. - :deprecated: - - -.. deprecated:: 2.3 - The :mod:`email` package should be used in preference to the :mod:`mimetools` - module. This module is present only to maintain backward compatibility. - -.. index:: module: rfc822 - -This module defines a subclass of the :mod:`rfc822` module's :class:`Message` -class and a number of utility functions that are useful for the manipulation for -MIME multipart or encoded message. - -It defines the following items: - - -.. class:: Message(fp[, seekable]) - - Return a new instance of the :class:`Message` class. This is a subclass of the - :class:`rfc822.Message` class, with some additional methods (see below). The - *seekable* argument has the same meaning as for :class:`rfc822.Message`. - - -.. function:: choose_boundary() - - Return a unique string that has a high likelihood of being usable as a part - boundary. The string has the form ``'hostipaddr.uid.pid.timestamp.random'``. - - -.. function:: decode(input, output, encoding) - - Read data encoded using the allowed MIME *encoding* from open file object - *input* and write the decoded data to open file object *output*. Valid values - for *encoding* include ``'base64'``, ``'quoted-printable'``, ``'uuencode'``, - ``'x-uuencode'``, ``'uue'``, ``'x-uue'``, ``'7bit'``, and ``'8bit'``. Decoding - messages encoded in ``'7bit'`` or ``'8bit'`` has no effect. The input is simply - copied to the output. - - -.. function:: encode(input, output, encoding) - - Read data from open file object *input* and write it encoded using the allowed - MIME *encoding* to open file object *output*. Valid values for *encoding* are - the same as for :meth:`decode`. - - -.. function:: copyliteral(input, output) - - Read lines from open file *input* until EOF and write them to open file - *output*. - - -.. function:: copybinary(input, output) - - Read blocks until EOF from open file *input* and write them to open file - *output*. The block size is currently fixed at 8192. - - -.. seealso:: - - Module :mod:`email` - Comprehensive email handling package; supersedes the :mod:`mimetools` module. - - Module :mod:`rfc822` - Provides the base class for :class:`mimetools.Message`. - - Module :mod:`multifile` - Support for reading files which contain distinct parts, such as MIME data. - - http://faqs.cs.uu.nl/na-dir/mail/mime-faq/.html - The MIME Frequently Asked Questions document. For an overview of MIME, see the - answer to question 1.1 in Part 1 of this document. - - -.. _mimetools-message-objects: - -Additional Methods of Message Objects -------------------------------------- - -The :class:`Message` class defines the following methods in addition to the -:class:`rfc822.Message` methods: - - -.. method:: Message.getplist() - - Return the parameter list of the :mailheader:`Content-Type` header. This is a - list of strings. For parameters of the form ``key=value``, *key* is converted - to lower case but *value* is not. For example, if the message contains the - header ``Content-type: text/html; spam=1; Spam=2; Spam`` then :meth:`getplist` - will return the Python list ``['spam=1', 'spam=2', 'Spam']``. - - -.. method:: Message.getparam(name) - - Return the *value* of the first parameter (as returned by :meth:`getplist`) of - the form ``name=value`` for the given *name*. If *value* is surrounded by - quotes of the form '``<``...\ ``>``' or '``"``...\ ``"``', these are removed. - - -.. method:: Message.getencoding() - - Return the encoding specified in the :mailheader:`Content-Transfer-Encoding` - message header. If no such header exists, return ``'7bit'``. The encoding is - converted to lower case. - - -.. method:: Message.gettype() - - Return the message type (of the form ``type/subtype``) as specified in the - :mailheader:`Content-Type` header. If no such header exists, return - ``'text/plain'``. The type is converted to lower case. - - -.. method:: Message.getmaintype() - - Return the main type as specified in the :mailheader:`Content-Type` header. If - no such header exists, return ``'text'``. The main type is converted to lower - case. - - -.. method:: Message.getsubtype() - - Return the subtype as specified in the :mailheader:`Content-Type` header. If no - such header exists, return ``'plain'``. The subtype is converted to lower case. - diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst index 076c214..ce35bfa 100644 --- a/Doc/library/netdata.rst +++ b/Doc/library/netdata.rst @@ -15,7 +15,6 @@ on the Internet. json.rst mailcap.rst mailbox.rst - mimetools.rst mimetypes.rst rfc822.rst base64.rst diff --git a/Lib/mimetools.py b/Lib/mimetools.py deleted file mode 100644 index 3ea5e1b..0000000 --- a/Lib/mimetools.py +++ /dev/null @@ -1,240 +0,0 @@ -"""Various tools used by MIME-reading or MIME-writing programs.""" - - -import os -import rfc822 -import tempfile - -__all__ = ["Message","choose_boundary","encode","decode","copyliteral", - "copybinary"] - -class Message(rfc822.Message): - """A derived class of rfc822.Message that knows about MIME headers and - contains some hooks for decoding encoded and multipart messages.""" - - def __init__(self, fp, seekable = 1): - rfc822.Message.__init__(self, fp, seekable) - self.encodingheader = \ - self.getheader('content-transfer-encoding') - self.typeheader = \ - self.getheader('content-type') - self.parsetype() - self.parseplist() - - def parsetype(self): - str = self.typeheader - if str is None: - str = 'text/plain' - if ';' in str: - i = str.index(';') - self.plisttext = str[i:] - str = str[:i] - else: - self.plisttext = '' - fields = str.split('/') - for i in range(len(fields)): - fields[i] = fields[i].strip().lower() - self.type = '/'.join(fields) - self.maintype = fields[0] - self.subtype = '/'.join(fields[1:]) - - def parseplist(self): - str = self.plisttext - self.plist = [] - while str[:1] == ';': - str = str[1:] - if ';' in str: - # XXX Should parse quotes! - end = str.index(';') - else: - end = len(str) - f = str[:end] - if '=' in f: - i = f.index('=') - f = f[:i].strip().lower() + \ - '=' + f[i+1:].strip() - self.plist.append(f.strip()) - str = str[end:] - - def getplist(self): - return self.plist - - def getparam(self, name): - name = name.lower() + '=' - n = len(name) - for p in self.plist: - if p[:n] == name: - return rfc822.unquote(p[n:]) - return None - - def getparamnames(self): - result = [] - for p in self.plist: - i = p.find('=') - if i >= 0: - result.append(p[:i].lower()) - return result - - def getencoding(self): - if self.encodingheader is None: - return '7bit' - return self.encodingheader.lower() - - def gettype(self): - return self.type - - def getmaintype(self): - return self.maintype - - def getsubtype(self): - return self.subtype - - - - -# Utility functions -# ----------------- - -try: - import _thread -except ImportError: - import _dummy_thread as _thread -_counter_lock = _thread.allocate_lock() -del _thread - -_counter = 0 -def _get_next_counter(): - global _counter - _counter_lock.acquire() - _counter += 1 - result = _counter - _counter_lock.release() - return result - -_prefix = None - -def choose_boundary(): - """Return a string usable as a multipart boundary. - - The string chosen is unique within a single program run, and - incorporates the user id (if available), process id (if available), - and current time. So it's very unlikely the returned string appears - in message text, but there's no guarantee. - - The boundary contains dots so you have to quote it in the header.""" - - global _prefix - import time - if _prefix is None: - import socket - try: - hostid = socket.gethostbyname(socket.gethostname()) - except socket.gaierror: - hostid = '127.0.0.1' - try: - uid = repr(os.getuid()) - except AttributeError: - uid = '1' - try: - pid = repr(os.getpid()) - except AttributeError: - pid = '1' - _prefix = hostid + '.' + uid + '.' + pid - return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter()) - - -# Subroutines for decoding some common content-transfer-types -# Input and output must be files opened in binary mode - -def decode(input, output, encoding): - """Decode common content-transfer-encodings (base64, quopri, uuencode).""" - if encoding == 'base64': - import base64 - return base64.decode(input, output) - if encoding == 'quoted-printable': - import quopri - return quopri.decode(input, output) - if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): - import uu - return uu.decode(input, output) - if encoding in ('7bit', '8bit'): - return output.write(input.read()) - if encoding in decodetab: - pipethrough(input, decodetab[encoding], output) - else: - raise ValueError('unknown Content-Transfer-Encoding: %s' % encoding) - -def encode(input, output, encoding): - """Encode common content-transfer-encodings (base64, quopri, uuencode).""" - if encoding == 'base64': - import base64 - return base64.encode(input, output) - if encoding == 'quoted-printable': - import quopri - return quopri.encode(input, output, 0) - if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): - import uu - return uu.encode(input, output) - if encoding in ('7bit', '8bit'): - return output.write(input.read()) - if encoding in encodetab: - pipethrough(input, encodetab[encoding], output) - else: - raise ValueError('unknown Content-Transfer-Encoding: %s' % encoding) - -# The following is no longer used for standard encodings - -# XXX This requires that uudecode and mmencode are in $PATH - -uudecode_pipe = '''( -TEMP=/tmp/@uu.$$ -sed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode -cat $TEMP -rm $TEMP -)''' - -decodetab = { - 'uuencode': uudecode_pipe, - 'x-uuencode': uudecode_pipe, - 'uue': uudecode_pipe, - 'x-uue': uudecode_pipe, - 'quoted-printable': 'mmencode -u -q', - 'base64': 'mmencode -u -b', -} - -encodetab = { - 'x-uuencode': 'uuencode tempfile', - 'uuencode': 'uuencode tempfile', - 'x-uue': 'uuencode tempfile', - 'uue': 'uuencode tempfile', - 'quoted-printable': 'mmencode -q', - 'base64': 'mmencode -b', -} - -def pipeto(input, command): - pipe = os.popen(command, 'w') - copyliteral(input, pipe) - pipe.close() - -def pipethrough(input, command, output): - (fd, tempname) = tempfile.mkstemp() - temp = os.fdopen(fd, 'w') - copyliteral(input, temp) - temp.close() - pipe = os.popen(command + ' <' + tempname, 'r') - copybinary(pipe, output) - pipe.close() - os.unlink(tempname) - -def copyliteral(input, output): - while 1: - line = input.readline() - if not line: break - output.write(line) - -def copybinary(input, output): - BUFSIZE = 8192 - while 1: - line = input.read(BUFSIZE) - if not line: break - output.write(line) diff --git a/Lib/test/test_mimetools.py b/Lib/test/test_mimetools.py deleted file mode 100644 index 1dc9178..0000000 --- a/Lib/test/test_mimetools.py +++ /dev/null @@ -1,76 +0,0 @@ -import unittest -from test import support - -import string, mimetools -import io - -msgtext1 = mimetools.Message(io.StringIO( -"""Content-Type: text/plain; charset=iso-8859-1; format=flowed -Content-Transfer-Encoding: 8bit - -Foo! -""")) - -sample = bytes(string.ascii_letters + "=" + string.digits + "\n", "ASCII") - -class MimeToolsTest(unittest.TestCase): - - def decode_encode_test(self, enc): - i = io.BytesIO(sample) - o = io.BytesIO() - mimetools.encode(i, o, enc) - i = io.BytesIO(o.getvalue()) - o = io.BytesIO() - mimetools.decode(i, o, enc) - self.assertEqual(o.getvalue(), sample) - - # Separate tests for better diagnostics - - def test_7bit(self): - self.decode_encode_test('7bit') - - def test_8bit(self): - self.decode_encode_test('8bit') - - def test_base64(self): - self.decode_encode_test('base64') - - def test_quoted_printable(self): - self.decode_encode_test('quoted-printable') - - def test_uuencode(self): - self.decode_encode_test('uuencode') - - def test_x_uuencode(self): - self.decode_encode_test('x-uuencode') - - def test_uue(self): - self.decode_encode_test('uue') - - def test_x_uue(self): - self.decode_encode_test('x-uue') - - def test_boundary(self): - s = set([""]) - for i in range(100): - nb = mimetools.choose_boundary() - self.assert_(nb not in s) - s.add(nb) - - def test_message(self): - msg = mimetools.Message(io.StringIO(str(msgtext1))) - self.assertEqual(msg.gettype(), "text/plain") - self.assertEqual(msg.getmaintype(), "text") - self.assertEqual(msg.getsubtype(), "plain") - self.assertEqual(msg.getplist(), ["charset=iso-8859-1", "format=flowed"]) - self.assertEqual(msg.getparamnames(), ["charset", "format"]) - self.assertEqual(msg.getparam("charset"), "iso-8859-1") - self.assertEqual(msg.getparam("format"), "flowed") - self.assertEqual(msg.getparam("spam"), None) - self.assertEqual(msg.getencoding(), "8bit") - -def test_main(): - support.run_unittest(MimeToolsTest) - -if __name__=="__main__": - test_main() @@ -78,6 +78,8 @@ Extension Modules Library ------- +- mimetools has been removed in favor of the email package + - Patch #2849: Remove use of rfc822 module from standard library. - Added C optimized implementation of io.StringIO. |