blob: 79c6fb13233994fe5c3163f1e1a2587f1503efa0 [file] [log] [blame]
Guido van Rossum01ca3361992-07-13 14:28:59 +00001# Various tools used by MIME-reading or MIME-writing programs.
2
3
4import string
5import rfc822
6
7
8# A derived class of rfc822.Message that knows about MIME headers and
9# contains some hooks for decoding encoded and multipart messages.
10
11class Message(rfc822.Message):
12
13 def init(self, fp):
14 self = rfc822.Message.init(self, fp)
15 self.encodingheader = \
16 self.getheader('content-transfer-encoding')
17 self.typeheader = \
18 self.getheader('content-type')
19 self.parsetype()
20 self.parseplist()
21 return self
22
23 def parsetype(self):
24 str = self.typeheader
25 if str == None:
26 str = 'text/plain'
27 if ';' in str:
28 i = string.index(str, ';')
29 self.plisttext = str[i:]
30 str = str[:i]
31 else:
32 self.plisttext = ''
33 fields = string.splitfields(str, '/')
34 for i in range(len(fields)):
35 fields[i] = string.lower(string.strip(fields[i]))
36 self.type = string.joinfields(fields, '/')
37 self.maintype = fields[0]
38 self.subtype = string.joinfields(fields[1:], '/')
39
40 def parseplist(self):
41 str = self.plisttext
42 self.plist = []
43 while str[:1] == ';':
44 str = str[1:]
45 if ';' in str:
46 # XXX Should parse quotes!
47 end = string.index(str, ';')
48 else:
49 end = len(str)
50 f = str[:end]
51 if '=' in f:
52 i = string.index(f, '=')
53 f = string.lower(string.strip(f[:i])) + \
54 '=' + string.strip(f[i+1:])
55 self.plist.append(string.strip(f))
56
57 def getplist(self):
58 return self.plist
59
60 def getparam(self, name):
61 name = string.lower(name) + '='
62 n = len(name)
63 for p in self.plist:
64 if p[:n] == name:
65 return rfc822.unquote(p[n:])
66 return None
67
68 def getencoding(self):
69 if self.encodingheader == None:
70 return '7bit'
71 return self.encodingheader
72
73 def gettype(self):
74 return self.type
75
76 def getmaintype(self):
77 return self.maintype
78
79 def getsubtype(self):
80 return self.subtype
81
82
83
84
85# Utility functions
86# -----------------
87
88
89# Return a random string usable as a multipart boundary.
90# The method used is so that it is *very* unlikely that the same
91# string of characters will every occur again in the Universe,
92# so the caller needn't check the data it is packing for the
93# occurrence of the boundary.
94#
95# The boundary contains dots so you have to quote it in the header.
96
97_prefix = None
98
99def choose_boundary():
100 global _generation, _prefix, _timestamp
101 import time
102 import rand
103 if _prefix == None:
104 import socket
105 import os
106 hostid = socket.gethostbyname(socket.gethostname())
107 uid = `os.getuid()`
108 pid = `os.getpid()`
109 seed = `rand.rand()`
110 _prefix = hostid + '.' + uid + '.' + pid
111 timestamp = `time.time()`
112 seed = `rand.rand()`
113 return _prefix + '.' + timestamp + '.' + seed