Base64 Decoding
Randall Hopper
aa8vb at yahoo.com
Thu Feb 10 08:48:32 EST 2000
Victor M. J. Ryden:
|I'm trying to use python to decode some e-amil I'm getting which
|contain MIME base64 encoded documents.
|
|I looked at the doc's for the mimetools and base64 modules. I'm confused
|because they ask for both an input AND output file name. I can understand
|the input, but not the output. There can be several encoded documents in
|a single input file, all of which have their respective file names as part
|of the encoding prelude.
|
|Has anyone any experience with this, and do you have any hints?
This should get you reasonably close.
Attached is a script I use to munge Novel Groupwise mails that I get here
occasionally. It takes a mail message and emits a modified mail message.
In particular, it parses out application/wordperfect attachments (in base64
or non-standard X-uuencode format), decodes them, and inserts both
plaintext and base64 attachments in the message. It also handles nested
mail messages.
This saves me from having to pop up Word Perfect to read my mail.
--
Randall Hopper
aa8vb at yahoo.com
-------------- next part --------------
#!/usr/local/bin/python
#
# wpmail-cvt - Converts broken Novel Groupwise X-uuencode mail containing
# WordPerfect attachments into true MIME format with base64
# encoding and content type of application/wordperfect.
# Also, kicks off WordPerfect, converts the document to
# text, and inserts that as an attachment in the mail
# message so we don't have to fire up WordPerfect.
#
# UPDATES
# 1/19/00 - Now supports nested (forwarded) rfc822 messages
#
WPD_TO_TEXT_CMD = "wp2txt"
import sys, rfc822, multifile, cgi, base64, uu, string, os, StringIO, getopt
def HandleMessage( infile ):
#
# Nuke the Lines and Content-Length headers, and print the header
#
header = rfc822.Message(infile)
del header[ 'Lines' ]
del header[ 'Content-Length' ]
# Make sure just one blank line after header
hdr_str = str(header)
if hdr_str[-1:] != '\n': hdr_str = hdr_str + '\n'
print "%s%s" % ( header.unixfrom, hdr_str )
#
# Parse the message parts
#
type, params = cgi.parse_header(header["content-type"])
if type[:10] != "multipart/":
sys.stdout.write( infile.read() )
else:
boundary = params["boundary"]
file = multifile.MultiFile(infile, 0)
file.push(boundary)
while file.next():
subheader = rfc822.Message(file)
type, params = cgi.parse_header(subheader['content-type'])
buf = StringIO.StringIO( file.read() )
# Grab the filename
filename = params.get( 'name' )
if not filename: filename = "file"
# If this is one of those non-MIME X-uuencode jobs, convert to base64
if subheader.get( 'content-transfer-encoding' ) == 'X-uuencode':
buf2 = StringIO.StringIO()
uu.decode( buf, buf2 )
buf = StringIO.StringIO( base64.encodestring( buf2.getvalue() ) )
subh_str = ( 'Content-Type: application/wordperfect; name="%s"\n'
'Content-Transfer-Encoding: base64\n'
'Content-Disposition: attachment; filename="%s"\n' )\
% ( filename, filename )
if subheader.get( 'content-description' ):
subh_str = subh_str + 'Content-Description: %s\n' % \
subheader.get( 'content-description' )
else:
subh_str = str(subheader)
# If this is a WordPerfect doc, convert it to text and insert
subheader = rfc822.Message( StringIO.StringIO( subh_str ) )
type, params = cgi.parse_header(subheader['content-type'])
if type == 'application/wordperfect':
# Decode the data, convert to text, and reinsert
base64.decode( buf, open( "/tmp/tmpfile", "wb" ) )
os.system( "%s %s %s" %
( WPD_TO_TEXT_CMD, "/tmp/tmpfile", "/tmp/tmpfile.txt" ) )
print "--%s" % boundary
print ( "Content-Type: text/plain; name=\"%s.txt\"\n"
"Content-Transfer-Encoding: 7bit\n"
"Content-Disposition: attachment; filename=\"%s.txt\"\n"
"Content-Description: Text\n" % ( filename, filename ) )
print open( "/tmp/tmpfile.txt", "r" ).read(),
print "--%s" % boundary
print subh_str
if subheader.get( 'content-type' ) == 'message/rfc822':
HandleMessage( buf )
else:
print buf.getvalue(),
file.pop()
print "--%s--\n" % boundary
#
# Parse args
#
opts, args = getopt.getopt( sys.argv[1:], 'h' )
if opts or len( args ) > 1:
print ( "FORMAT: wpmail-cvt [<filaname>]\n\n"
" <filename> - A file containing a mail message\n\n"
" If no filename is specified, input is taken from stdin" )
sys.exit(1)
#
# Parse the e-mail header, and print it
#
if args: infile = open( args[0] )
else: infile = sys.stdin
HandleMessage( infile )
More information about the Python-list
mailing list