clone(): A new method for creating a clone of this generator (for

recursive generation).

_dispatch(): If the message object doesn't have a Content-Type:
header, check its default type instead of assuming it's text/plain.
This makes for correct generation of message/rfc822 containers.

_handle_multipart(): We can get rid of the isdigest kludge.  Just
print the message as normal and everything will work out correctly.

_handle_mulitpart_digest(): We don't need this anymore either.
This commit is contained in:
Barry Warsaw 2002-07-09 02:43:47 +00:00
parent ed53bdb02d
commit 93c40f0c3a
1 changed files with 24 additions and 27 deletions

View File

@ -83,6 +83,10 @@ class Generator:
# For backwards compatibility, but this is slower # For backwards compatibility, but this is slower
__call__ = flatten __call__ = flatten
def clone(self, fp):
"""Clone this generator with the exact same options."""
return self.__class__(fp, self._mangle_from_, self.__maxheaderlen)
# #
# Protected interface - undocumented ;/ # Protected interface - undocumented ;/
# #
@ -121,18 +125,20 @@ class Generator:
# missing too, then dispatch to self._writeBody(). # missing too, then dispatch to self._writeBody().
ctype = msg.get_type() ctype = msg.get_type()
if ctype is None: if ctype is None:
# No Content-Type: header so try the default handler # No Content-Type: header so use the default type, which must be
self._writeBody(msg) # either text/plain or message/rfc822.
else: ctype = msg.get_default_type()
# We do have a Content-Type: header. assert ctype in ('text/plain', 'message/rfc822')
specific = UNDERSCORE.join(ctype.split('/')).replace('-', '_') # We do have a Content-Type: header.
meth = getattr(self, '_handle_' + specific, None) main, sub = ctype.split('/')
specific = UNDERSCORE.join((main, sub)).replace('-', '_')
meth = getattr(self, '_handle_' + specific, None)
if meth is None:
generic = main.replace('-', '_')
meth = getattr(self, '_handle_' + generic, None)
if meth is None: if meth is None:
generic = msg.get_main_type().replace('-', '_') meth = self._writeBody
meth = getattr(self, '_handle_' + generic, None) meth(msg)
if meth is None:
meth = self._writeBody
meth(msg)
# #
# Default handlers # Default handlers
@ -196,14 +202,14 @@ class Generator:
# Default body handler # Default body handler
_writeBody = _handle_text _writeBody = _handle_text
def _handle_multipart(self, msg, isdigest=0): def _handle_multipart(self, msg):
# The trick here is to write out each part separately, merge them all # The trick here is to write out each part separately, merge them all
# together, and then make sure that the boundary we've chosen isn't # together, and then make sure that the boundary we've chosen isn't
# present in the payload. # present in the payload.
msgtexts = [] msgtexts = []
subparts = msg.get_payload() subparts = msg.get_payload()
if subparts is None: if subparts is None:
# Nothing has every been attached # Nothing has ever been attached
boundary = msg.get_boundary(failobj=_make_boundary()) boundary = msg.get_boundary(failobj=_make_boundary())
print >> self._fp, '--' + boundary print >> self._fp, '--' + boundary
print >> self._fp, '\n' print >> self._fp, '\n'
@ -214,7 +220,7 @@ class Generator:
subparts = [subparts] subparts = [subparts]
for part in subparts: for part in subparts:
s = StringIO() s = StringIO()
g = self.__class__(s, self._mangle_from_, self.__maxheaderlen) g = self.clone(s)
g.flatten(part, unixfrom=0) g.flatten(part, unixfrom=0)
msgtexts.append(s.getvalue()) msgtexts.append(s.getvalue())
# Now make sure the boundary we've selected doesn't appear in any of # Now make sure the boundary we've selected doesn't appear in any of
@ -236,14 +242,8 @@ class Generator:
# First boundary is a bit different; it doesn't have a leading extra # First boundary is a bit different; it doesn't have a leading extra
# newline. # newline.
print >> self._fp, '--' + boundary print >> self._fp, '--' + boundary
if isdigest:
print >> self._fp
# Join and write the individual parts # Join and write the individual parts
joiner = '\n--' + boundary + '\n' joiner = '\n--' + boundary + '\n'
if isdigest:
# multipart/digest types effectively add an extra newline between
# the boundary and the body part.
joiner += '\n'
self._fp.write(joiner.join(msgtexts)) self._fp.write(joiner.join(msgtexts))
print >> self._fp, '\n--' + boundary + '--', print >> self._fp, '\n--' + boundary + '--',
# Write out any epilogue # Write out any epilogue
@ -252,9 +252,6 @@ class Generator:
print >> self._fp print >> self._fp
self._fp.write(msg.epilogue) self._fp.write(msg.epilogue)
def _handle_multipart_digest(self, msg):
self._handle_multipart(msg, isdigest=1)
def _handle_message_delivery_status(self, msg): def _handle_message_delivery_status(self, msg):
# We can't just write the headers directly to self's file object # We can't just write the headers directly to self's file object
# because this will leave an extra newline between the last header # because this will leave an extra newline between the last header
@ -262,7 +259,7 @@ class Generator:
blocks = [] blocks = []
for part in msg.get_payload(): for part in msg.get_payload():
s = StringIO() s = StringIO()
g = self.__class__(s, self._mangle_from_, self.__maxheaderlen) g = self.clone(s)
g.flatten(part, unixfrom=0) g.flatten(part, unixfrom=0)
text = s.getvalue() text = s.getvalue()
lines = text.split('\n') lines = text.split('\n')
@ -278,11 +275,11 @@ class Generator:
def _handle_message(self, msg): def _handle_message(self, msg):
s = StringIO() s = StringIO()
g = self.__class__(s, self._mangle_from_, self.__maxheaderlen) g = self.clone(s)
# The payload of a message/rfc822 part should be a multipart sequence # The payload of a message/rfc822 part should be a multipart sequence
# of length 1. The zeroth element of the list should be the Message # of length 1. The zeroth element of the list should be the Message
# object for the subpart.Extract that object, stringify it, and write # object for the subpart. Extract that object, stringify it, and
# that out. # write it out.
g.flatten(msg.get_payload(0), unixfrom=0) g.flatten(msg.get_payload(0), unixfrom=0)
self._fp.write(s.getvalue()) self._fp.write(s.getvalue())