"""Various tools used by MIME-reading or MIME-writing programs."""
from warnings import filterwarnings, catch_warnings
filterwarnings("ignore", ".*rfc822 has been removed", DeprecationWarning)
from warnings import warnpy3k
warnpy3k("in 3.x, mimetools has been removed in favor of the email package",
__all__ = ["Message","choose_boundary","encode","decode","copyliteral",
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.getheader('content-transfer-encoding')
self.getheader('content-type')
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:])
# XXX Should parse quotes!
f = f[:i].strip().lower() + \
self.plist.append(f.strip())
def getparam(self, name):
name = name.lower() + '='
return rfc822.unquote(p[n:])
result.append(p[:i].lower())
if self.encodingheader is None:
return self.encodingheader.lower()
import dummy_thread as thread
_counter_lock = thread.allocate_lock()
"""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."""
hostid = socket.gethostbyname(socket.gethostname())
_prefix = hostid + '.' + uid + '.' + pid
return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter())
# Subroutines for decoding some common content-transfer-types
def decode(input, output, encoding):
"""Decode common content-transfer-encodings (base64, quopri, uuencode)."""
return base64.decode(input, output)
if encoding == 'quoted-printable':
return quopri.decode(input, output)
if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
return uu.decode(input, output)
if encoding in ('7bit', '8bit'):
return output.write(input.read())
if encoding in decodetab:
pipethrough(input, decodetab[encoding], output)
'unknown Content-Transfer-Encoding: %s' % encoding
def encode(input, output, encoding):
"""Encode common content-transfer-encodings (base64, quopri, uuencode)."""
return base64.encode(input, output)
if encoding == 'quoted-printable':
return quopri.encode(input, output, 0)
if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
return uu.encode(input, output)
if encoding in ('7bit', '8bit'):
return output.write(input.read())
if encoding in encodetab:
pipethrough(input, encodetab[encoding], output)
'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
sed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode
'uuencode': uudecode_pipe,
'x-uuencode': uudecode_pipe,
'quoted-printable': 'mmencode -u -q',
'base64': 'mmencode -u -b',
'x-uuencode': 'uuencode tempfile',
'uuencode': 'uuencode tempfile',
'x-uue': 'uuencode tempfile',
'uue': 'uuencode tempfile',
'quoted-printable': 'mmencode -q',
def pipeto(input, command):
pipe = os.popen(command, 'w')
def pipethrough(input, command, output):
(fd, tempname) = tempfile.mkstemp()
temp = os.fdopen(fd, 'w')
pipe = os.popen(command + ' <' + tempname, 'r')
def copyliteral(input, output):
def copybinary(input, output):
line = input.read(BUFSIZE)