def render(self, md): contents=[] IO = StringIO() IO.write("Mime-Version: 1.0\n") mw = MimeWriter(IO) outer = mw.startmultipartbody(self.multipart) for x in self.sections: a, b = x has_key=a.has_key if has_key('skip_expr') and a['skip_expr'].eval(md): continue inner = mw.nextpart() if has_key('type_expr'): t=a['type_expr'].eval(md) else: t=a['type'] if has_key('disposition_expr'): d=a['disposition_expr'].eval(md) else: d=a['disposition'] if has_key('encode_expr'): e=a['encode_expr'].eval(md) else: e=a['encode'] if has_key('name_expr'): n=a['name_expr'].eval(md) else: n=a['name'] if has_key('filename_expr'): f=a['filename_expr'].eval(md) else: f=a['filename'] if d: if f: inner.addheader('Content-Disposition', '%s;\n filename="%s"' % (d, f)) else: inner.addheader('Content-Disposition', d) inner.addheader('Content-Transfer-Encoding', e) if n: plist = [('name', n)] else: plist = [] innerfile = inner.startbody(t, plist, 1) output = StringIO() if e == '7bit': innerfile.write(render_blocks(b, md)) else: mimetools.encode(StringIO(render_blocks(b, md)), output, e) output.seek(0) innerfile.write(output.read()) # XXX what if self.sections is empty ??? does it matter that mw.lastpart() is called # right after mw.startmultipartbody() ? if x is self.sections[-1]: mw.lastpart() outer.seek(0) return outer.read()
def send_mail(server, port, sender, recipient, subject, message, username = '', password = '', attachment = '', mime_type = ''): from StringIO import StringIO from smtplib import SMTP from MimeWriter import MimeWriter import base64 # Build the message header. message_obj = StringIO() writer = MimeWriter(message_obj) writer.addheader('Subject', subject) writer.startmultipartbody('mixed') part = writer.nextpart() # Add the message body. body = part.startbody('text/plain') body.write(message) # And (optionally) the attachment. if attachment != '': part = writer.nextpart() part.addheader('Content-Transfer-Encoding', 'base64') body = part.startbody(mime_type) base64.encode(StringIO(attachment), body) # Finish the message. writer.lastpart() # Send the mail (and authenticate if necessary). smtp = SMTP(server, port) if username != '': smtp.login(username, password) smtp.sendmail(sender, recipient, message_obj.getvalue()) smtp.quit() return True
def render(self, md): from MimeWriter import MimeWriter # deprecated since Python 2.3! IO = StringIO() IO.write("Mime-Version: 1.0\n") mw = MimeWriter(IO) outer = mw.startmultipartbody(self.multipart) last = None for x in self.sections: a, b = x if "skip_expr" in a and a["skip_expr"].eval(md): continue inner = mw.nextpart() if "type_expr" in a: t = a["type_expr"].eval(md) else: t = a["type"] if "disposition_expr" in a: d = a["disposition_expr"].eval(md) else: d = a["disposition"] if "encode_expr" in a: e = a["encode_expr"].eval(md) else: e = a["encode"] if "name_expr" in a: n = a["name_expr"].eval(md) else: n = a["name"] if "filename_expr" in a: f = a["filename_expr"].eval(md) else: f = a["filename"] if "cid_expr" in a: cid = a["cid_expr"].eval(md) else: cid = a["cid"] if "charset_expr" in a: charset = a["charset_expr"].eval(md) else: charset = a["charset"] if d: if f: inner.addheader("Content-Disposition", '%s;\n filename="%s"' % (d, f)) else: inner.addheader("Content-Disposition", d) inner.addheader("Content-Transfer-Encoding", e) if cid: inner.addheader("Content-ID", "<%s>" % cid) if n: plist = [("name", n)] else: plist = [] if t.startswith("text/"): plist.append(("charset", charset or "us-ascii")) innerfile = inner.startbody(t, plist, 1) output = StringIO() if e == "7bit": innerfile.write(render_blocks(b, md)) else: mimetools.encode(StringIO(render_blocks(b, md)), output, e) output.seek(0) innerfile.write(output.read()) last = x # XXX what if self.sections is empty ??? does it matter that # mw.lastpart() is called right after mw.startmultipartbody() ? if last is not None and last is self.sections[-1]: mw.lastpart() outer.seek(0) return outer.read()
def render(self, md): contents=[] IO = StringIO() IO.write("Mime-Version: 1.0\n") mw = MimeWriter(IO) outer = mw.startmultipartbody(self.multipart) for x in self.sections: a, b = x has_key=a.has_key if has_key('skip_expr') and a['skip_expr'].eval(md): continue inner = mw.nextpart() if has_key('type_expr'): t=a['type_expr'].eval(md) else: t=a['type'] if has_key('disposition_expr'): d=a['disposition_expr'].eval(md) else: d=a['disposition'] if has_key('encode_expr'): e=a['encode_expr'].eval(md) else: e=a['encode'] if has_key('name_expr'): n=a['name_expr'].eval(md) else: n=a['name'] if has_key('filename_expr'): f=a['filename_expr'].eval(md) else: f=a['filename'] if has_key('cid_expr'): cid=a['cid_expr'].eval(md) else: cid=a['cid'] if has_key('charset_expr'): charset=a['charset_expr'].eval(md) else: charset=a['charset'] if d: if f: inner.addheader('Content-Disposition', '%s;\n filename="%s"' % (d, f)) else: inner.addheader('Content-Disposition', d) inner.addheader('Content-Transfer-Encoding', e) if cid: inner.addheader('Content-ID', '<%s>' % cid) if n: plist = [('name', n)] else: plist = [] if t.startswith('text/'): plist.append(('charset', charset or 'us-ascii')) innerfile = inner.startbody(t, plist, 1) output = StringIO() if e == '7bit': innerfile.write(render_blocks(b, md)) else: mimetools.encode(StringIO(render_blocks(b, md)), output, e) output.seek(0) innerfile.write(output.read()) # XXX what if self.sections is empty ??? does it matter that mw.lastpart() is called # right after mw.startmultipartbody() ? if x is self.sections[-1]: mw.lastpart() outer.seek(0) return outer.read()
def test(self): buf = StringIO.StringIO() # Toplevel headers toplevel = MimeWriter(buf) toplevel.addheader("From", "*****@*****.**") toplevel.addheader("Date", "Mon Feb 12 17:21:48 EST 1996") toplevel.addheader("To", "*****@*****.**") toplevel.addheader("MIME-Version", "1.0") # Toplevel body parts f = toplevel.startmultipartbody("knowbot", "801spam999", [("version", "0.1")], prefix=0) f.write("This is a multi-part message in MIME format.\n") # First toplevel body part: metadata md = toplevel.nextpart() md.startmultipartbody("knowbot-metadata", "802spam999") # Metadata part 1 md1 = md.nextpart() md1.addheader("KP-Metadata-Type", "simple") md1.addheader("KP-Access", "read-only") m = MimeWriter(md1.startbody("message/rfc822")) for key, value in SIMPLE_METADATA: m.addheader("KPMD-" + key, value) m.flushheaders() del md1 # Metadata part 2 md2 = md.nextpart() for key, value in COMPLEX_METADATA: md2.addheader("KP-" + key, value) f = md2.startbody("text/isl") f.write(SELLER) del md2 # Metadata part 3 md3 = md.nextpart() f = md3.startbody("message/external-body", [("access-type", "URL"), ("URL", "hdl://cnri.kss/generic-knowbot")]) m = MimeWriter(f) for key, value in EXTERNAL_METADATA: md3.addheader("KP-" + key, value) md3.startbody("text/isl") # Phantom body doesn't need to be written md.lastpart() # Second toplevel body part: code code = toplevel.nextpart() code.startmultipartbody("knowbot-code", "803spam999") # Code: buyer program source buyer = code.nextpart() buyer.addheader("KP-Module-Name", "BuyerKP") f = buyer.startbody("text/plain") f.write(BUYER) code.lastpart() # Third toplevel body part: state state = toplevel.nextpart() state.addheader("KP-Main-Module", "main") state.startmultipartbody("knowbot-state", "804spam999") # State: a bunch of assignments st = state.nextpart() st.addheader("KP-Module-Name", "main") f = st.startbody("text/plain") f.write(STATE) state.lastpart() # End toplevel body parts toplevel.lastpart() self.assertEqual(buf.getvalue(), OUTPUT)
"""Test program for MimeWriter module.
def get_standard_message(self, to, subject, author=None): """Form a standard email message from Roundup. "to" - recipients list "subject" - Subject "author" - (name, address) tuple or None for admin email Subject and author are encoded using the EMAIL_CHARSET from the config (default UTF-8). Returns a Message object and body part writer. """ # encode header values if they need to be charset = getattr(self.config, "EMAIL_CHARSET", "utf-8") tracker_name = self.config.TRACKER_NAME if charset != "utf-8": tracker = unicode(tracker_name, "utf-8").encode(charset) if not author: author = straddr((tracker_name, self.config.ADMIN_EMAIL)) else: name = author[0] if charset != "utf-8": name = unicode(name, "utf-8").encode(charset) author = straddr((encode_header(name, charset), author[1])) message = StringIO() writer = MimeWriter(message) writer.addheader("Subject", encode_header(subject, charset)) writer.addheader("To", ", ".join(to)) writer.addheader("From", author) writer.addheader("Date", formatdate(localtime=True)) # add a Precedence header so autoresponders ignore us writer.addheader("Precedence", "bulk") # Add a unique Roundup header to help filtering writer.addheader("X-Roundup-Name", encode_header(tracker_name, charset)) # and another one to avoid loops writer.addheader("X-Roundup-Loop", "hello") # finally, an aid to debugging problems writer.addheader("X-Roundup-Version", __version__) writer.addheader("MIME-Version", "1.0") return message, writer
def get_standard_message(self, to, subject, author=None): '''Form a standard email message from Roundup. "to" - recipients list "subject" - Subject "author" - (name, address) tuple or None for admin email Subject and author are encoded using the EMAIL_CHARSET from the config (default UTF-8). Returns a Message object and body part writer. ''' # encode header values if they need to be charset = getattr(self.config, 'EMAIL_CHARSET', 'utf-8') tracker_name = self.config.TRACKER_NAME if charset != 'utf-8': tracker = unicode(tracker_name, 'utf-8').encode(charset) if not author: author = straddr((tracker_name, self.config.ADMIN_EMAIL)) else: name = author[0] if charset != 'utf-8': name = unicode(name, 'utf-8').encode(charset) author = straddr((encode_header(name, charset), author[1])) message = StringIO() writer = MimeWriter(message) writer.addheader('Subject', encode_header(subject, charset)) writer.addheader('To', ', '.join(to)) writer.addheader('From', author) writer.addheader('Date', formatdate(localtime=True)) # Add a unique Roundup header to help filtering writer.addheader('X-Roundup-Name', encode_header(tracker_name, charset)) # and another one to avoid loops writer.addheader('X-Roundup-Loop', 'hello') # finally, an aid to debugging problems writer.addheader('X-Roundup-Version', __version__) writer.addheader('MIME-Version', '1.0') return message, writer