# -*- Mode: Python -*- import cStringIO import email import email.Utils import email.MIMEImage import email.MIMEMultipart import formatter import os import smtplib import sgmllib import sys # TODO: make this actually fetch a page along with its images, # rather than relying on the browser to do it. class image_collector: def __init__ (self, file): self.file = file self.images = [] def write (self, data): self.file.write (data) def write_tag (self, tag, attrs): if attrs: self.write ( '\n<%s %s>\n' % ( tag, ' '.join (['%s="%s"' % (key, val) for key, val in attrs.items()]) ) ) else: self.write ('<%s>' % (tag,)) def catch_image (self, attrs): msg_id = email.Utils.make_msgid() if os.path.isfile (attrs['src']): self.images.append ((attrs['src'], msg_id)) # override the src attribute attrs['src'] = 'cid:%s' % (msg_id[1:-1]) self.write_tag ('img', attrs) def dictify (pairs): d = {} for key, val in pairs: d[key] = val return d class dumb_html_parser (sgmllib.SGMLParser): def __init__ (self, out): self.out = out sgmllib.SGMLParser.__init__ (self) def unknown_starttag (self, tag, attributes): self.out.write_tag (tag, dictify (attributes)) def unknown_endtag (self, tag): self.out.write ('' % (tag,)) def unknown_charref (self, ref): self.out.write ('&#%s;' % (ref,)) def unknown_entityref (self, ref): self.out.write ('&%s;' % (ref,)) def do_img (self, attributes): self.out.catch_image (dictify (attributes)) def handle_data (self, data): self.out.write (data) def send_html (file, relay, env_from, recipients): f = cStringIO.StringIO() m = email.MIMEMultipart.MIMEMultipart ('related') m_html = email.Message.Message() c = image_collector (f) p = dumb_html_parser (c) p.feed (open (file, 'rb').read()) m_html.set_payload (f.getvalue()) m_html['Content-Type'] = 'text/html' m.attach (m_html) for name, msg_id in c.images: img = email.MIMEImage.MIMEImage ( open (name, 'rb').read() ) img['Content-ID'] = msg_id m.attach (img) m['To'] = ','.join (recipients) m['From'] = env_from m['Subject'] = 'html file "%s"' % (file,) data = m.as_string() c = smtplib.SMTP (relay) c.sendmail (env_from, recips, data) c.quit() if __name__ == '__main__': import sys if len(sys.argv) < 4: sys.stderr.write ( ' Send an HTML file (plus images) as a multipart/related MIME message\n' 'Usage: %s ...\n' % ( sys.argv[0] ) ) else: file = sys.argv[1] relay = sys.argv[2] env_from = sys.argv[3] recips = sys.argv[4:] send_html (file, relay, env_from, recips)