1 # Various tools used by MIME-reading or MIME-writing programs.
10 # A derived class of rfc822.Message that knows about MIME headers and
11 # contains some hooks for decoding encoded and multipart messages.
13 class Message(rfc822
.Message
):
15 def __init__(self
, fp
):
16 rfc822
.Message
.__init
__(self
, fp
)
17 self
.encodingheader
= \
18 self
.getheader('content-transfer-encoding')
20 self
.getheader('content-type')
29 i
= string
.index(str, ';')
30 self
.plisttext
= str[i
:]
34 fields
= string
.splitfields(str, '/')
35 for i
in range(len(fields
)):
36 fields
[i
] = string
.lower(string
.strip(fields
[i
]))
37 self
.type = string
.joinfields(fields
, '/')
38 self
.maintype
= fields
[0]
39 self
.subtype
= string
.joinfields(fields
[1:], '/')
47 # XXX Should parse quotes!
48 end
= string
.index(str, ';')
53 i
= string
.index(f
, '=')
54 f
= string
.lower(string
.strip(f
[:i
])) + \
55 '=' + string
.strip(f
[i
+1:])
56 self
.plist
.append(string
.strip(f
))
61 def getparam(self
, name
):
62 name
= string
.lower(name
) + '='
66 return rfc822
.unquote(p
[n
:])
69 def getencoding(self
):
70 if self
.encodingheader
== None:
72 return string
.lower(self
.encodingheader
)
77 def getmaintype(self
):
90 # Return a random string usable as a multipart boundary.
91 # The method used is so that it is *very* unlikely that the same
92 # string of characters will every occur again in the Universe,
93 # so the caller needn't check the data it is packing for the
94 # occurrence of the boundary.
96 # The boundary contains dots so you have to quote it in the header.
100 def choose_boundary():
101 global _generation
, _prefix
, _timestamp
107 hostid
= socket
.gethostbyname(socket
.gethostname())
111 _prefix
= hostid
+ '.' + uid
+ '.' + pid
112 timestamp
= `
int(time
.time())`
114 return _prefix
+ '.' + timestamp
+ '.' + seed
117 # Subroutines for decoding some common content-transfer-types
119 # XXX This requires that uudecode and mmencode are in $PATH
121 def decode(input, output
, encoding
):
122 if decodetab
.has_key(encoding
):
123 pipethrough(input, decodetab
[encoding
], output
)
126 'unknown Content-Transfer-Encoding: %s' % encoding
128 def encode(input, output
, encoding
):
129 if encodetab
.has_key(encoding
):
130 pipethrough(input, encodetab
[encoding
], output
)
133 'unknown Content-Transfer-Encoding: %s' % encoding
137 sed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode
143 'uuencode': uudecode_pipe
,
144 'x-uuencode': uudecode_pipe
,
145 'quoted-printable': 'mmencode -u -q',
146 'base64': 'mmencode -u -b',
150 'x-uuencode': 'uuencode tempfile',
151 'uuencode': 'uuencode tempfile',
152 'quoted-printable': 'mmencode -q',
153 'base64': 'mmencode -b',
156 def pipeto(input, command
):
157 pipe
= os
.popen(command
, 'w')
158 copyliteral(input, pipe
)
161 def pipethrough(input, command
, output
):
162 tempname
= tempfile
.mktemp()
164 temp
= open(tempname
, 'w')
166 print '*** Cannot create temp file', `tempname`
168 copyliteral(input, temp
)
170 pipe
= os
.popen(command
+ ' <' + tempname
, 'r')
171 copybinary(pipe
, output
)
175 def copyliteral(input, output
):
177 line
= input.readline()
181 def copybinary(input, output
):
184 line
= input.read(BUFSIZE
)