"""Various tools used by MIME-reading or MIME-writing programs."""
__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
)