Message.py
上传用户:gyjinxi
上传日期:2007-01-04
资源大小:159k
文件大小:5k
- try: import locale; locale.setlocale(locale.LC_ALL,"")
- except: pass
- import mimetools, mimify, re, multifile, base64, string, time
- try: from cStringIO import StringIO
- except: from StringIO import StringIO
- mime_head_quopri = re.compile('=\?iso-8859-[12]\?q\?([^? tn]+)\?=', re.I)
- mime_head_base64 = re.compile('=\?iso-8859-[12]\?b\?([^? tn]+)\?=', re.I)
- def mime_decode(line, isBase64=0):
- if isBase64: return base64.decodestring(line)
- else: return mimify.mime_decode(line)
-
- # mimify.mime_decode_header only decodes quoted printable
- # this one also handles base64 encoded headers
- def mime_decode_header(line):
- '''Decode a header line to 8bit.'''
- newline = ''
- pos = 0
- while 1:
- res = mime_head_quopri.search(line, pos)
- if res is None:
- res = mime_head_base64.search(line, pos)
- if res is None: break
- else: isBase64 = 1
- else: isBase64 = 0
- match = res.group(1)
- # convert underscores to spaces (before =XX conversion!)
- match = string.join(string.split(match, '_'), ' ')
- newline = newline + line[pos:res.start(0)] + mime_decode(match, isBase64)
- pos = res.end(0)
- return newline + line[pos:]
-
- class Message(mimetools.Message):
- """A real MIME-message class :-)
- Handles multipart messages and
- helps decoding parts as well as headers.
- Disadvantage: slow on long mails :-(
- """
-
- def __init__(self, fp, preview=0):
- mimetools.Message.__init__(self, fp)
- self.body = ""
- self.parts = []
- self.encoding = self.getencoding()
- self.boundary = self.getparam("boundary")
- disp = self.getheader("content-disposition") or ""
- f = string.find(disp, 'filename="')
- if f <> -1: #XXX VERY BAD HACK!!!
- self.filename = disp[f+10:string.find(disp, '"', f+10)]
- else:
- self.filename = None
- self.parsed = 0
- self.processHeaders()
- if not preview: self.parse()
-
- def processHeaders(self):
- self.Lines = self["Lines"]
- if self.Lines: self.Lines = int(self.Lines)
- self.Subject = self["Subject"]
- self.FromName, self.FromAddr = self.getaddr("From")
- self.Sender = "%s <%s>" % (self.FromName, self.FromAddr)
- self.ReplyToName, self.ReplyToAddr = self.getaddr("Reply-To")
- self.ToName, self.ToAddr = self.getaddr("To")
- self.CcName, self.CcAddr = self.getaddr("Cc")
- self.BccName, self.BccAddr = self.getaddr("Bcc")
- self.UserAgent = self["X-Mailer"] or self["User-Agent"]
- self.Date = self.getdate("Date")
- if self.Date:
- self.DateStr = time.strftime(
- "%a, %d. %b %Yn %H:%M", self.Date)
- self.DateShortStr = time.strftime("%D %T", self.Date)
- else:
- self.DateStr = self.DateShortStr = "(no date)"
- def parse(self):
- if self.parsed: return
- self.rewindbody()
- if self.boundary:
- mf = multifile.MultiFile(self.fp)
- mf.push(self.boundary)
- while mf.next():
- self.parts.append(Message(mf))
- mf.pop()
- else:
- self.body = self.fp.read()
- self.parsed = 1
- def decode(self):
- if self.encoding in ['7bit', '8bit']:
- return self.body
- try:
- self.rewindbody()
- out = StringIO()
- mimetools.decode(StringIO(self.body), out, self.encoding)
- return out.getvalue()
- except:
- raise ValueError, "MIME part decoding failed"
-
- def getheader(self, name, default=None):
- header = mimetools.Message.getheader(self, name, default)
- if header:
- return mime_decode_header(header)
- def getaddr(self, name):
- name, addr = mimetools.Message.getaddr(self, name)
- if name: return mime_decode_header(name), addr
- else: return name, addr
-
- def getdate(self, name):
- try: return mimetools.Message.getdate(self, name)
- except: pass
-
- def __getitem__(self, name):
- return self.getheader(name)
-
- def __str__(self):
- # rebuild the message
- f = StringIO()
- f.write('%sn' % string.join(
- map(mimify.mime_encode_header, self.headers), ''))
- if self.parts: # multipart message
- for p in self.parts:
- f.write('n--%sn' % self.boundary)
- f.write(str(p))
- f.write('n--%s--n' % self.boundary)
- else:
- f.write(self.body or "")
- return f.getvalue()