# -*- 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 ('</%s>' % (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 <html_file> <smtp_relay> <from> <recip0> <recip1> ...\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)
