#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    @copyright: 2008 Lari Huttunen
    @license: MIT <http://www.opensource.org/licenses/mit-license.php>
"""
import sys
import socket
import smtplib
import optparse
from opencollab.meta import Meta, Metas
from opencollab.util.config import parseOptions
from opencollab.wiki import CLIWiki, WikiFailure

try:
    from email.mime.text import MIMEText
except:
    from email.MIMEText import MIMEText
try:
    from email.mime.multipart import MIMEMultipart
except:
    from email.MIMEMultipart import MIMEMultipart


def get_page_html(collab, page):
    content = ""
    try:
        content = collab.getPageHTML(page)
    except WikiFailure, msg:
        raise WikiFailure, msg
    else:
        return content


def send_content(url, collab, page_content, sender, recipient, subject, header, footer, page_marker):
    msg = MIMEMultipart()
    part = ''
    if subject == None:
        msg['Subject'] = "Changes at: " + url
    else:
        msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = recipient
    msg.add_header('Content-Disposition', 'inline')
    html_head = '<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html;charset=utf-8">\n<title></title>\n</head>\n<body>'
    html_foot = "\n</body>\n</html>"
    content = html_head

    if header is not None:
        content += header
    for page in page_content:
        if page_content[page] is not None:
            content += page_content[page].encode("utf-8")
        collab.setMeta(page, page_marker, replace=True)

    if footer is not None:
        content += footer
    content += html_foot
    part = MIMEText(content, "HTML", "UTF-8")
    part.add_header('Content-Disposition', 'inline')
    msg.attach(part)
    s = smtplib.SMTP()
    s.connect()
    s.sendmail(sender, recipient, msg.as_string())
    s.close()


def main():
    parser = optparse.OptionParser()
    parser.add_option("-f", "--from", dest="sender", default=None,
        metavar="SENDER", help=("Email SENDER address."))
    parser.add_option("-F", "--FOOTER", dest="footer", default=None,
        metavar="FOOTER", help=("Read last attachment from page name FOOTER."))
    parser.add_option("-H", "--HEADER",
        dest="header", default=None, metavar="HEADER",
        help=("Read email attachemnt #1 from page name HEADER."))
    parser.add_option("-m", "--marker", dest="marker",
        default=None, metavar="MARKER",
        help=("Notify MARKER key=value pair."))
    parser.add_option("-r", "--recipient",
        dest="recipient", default=None,
        metavar="RECIPIENT", help=("Email notify RECIPIENT."))
    parser.add_option("-S", "--subject",
        dest="subject", default=None, metavar="SUBJECT",
        help=("Notify email SUBJECT."))
    parser.set_usage("%prog [options]")
    pages = Metas()
    page_marker = Meta()
    page_content = {}
    ops = {}
    sect = "notifier"
    ops = parseOptions(parser, sect, search=True)
    url = ops["creds"]["url"]
    x509 = ops[sect]["x509"]
    x509_ca_file = ops[sect]["x509_ca_file"]
    verbose = ops[sect]["verbose"]
    search = ops[sect]["search"]
    if search is None:
        parser.error("You must specify MetaTable search arguments. Use -h for help.")
    sender = ops[sect]["sender"]
    if sender is None:
        parser.error("You must specify the notify sender. Use -h for help.")
    recipient = ops[sect]["recipient"]
    if recipient is None:
        parser.error("You must specify the notify recipient. Use -h for help.")
    subject = ops[sect]["subject"]
    if subject is None:
        parser.error("You must specify the notify subject. Use -h for help.")
    marker = ops[sect]["marker"]
    if marker is None:
        marker = "notified=yes"
    footer = ops[sect]["footer"]
    header = ops[sect]["header"]
    k, v = marker.split('=')
    page_marker[k].add(v)
    while True:
        try:
            collab = CLIWiki(ssl_verify_cert=x509, ssl_ca_certs=x509_ca_file, **ops['creds'])
        except WikiFailure:
            print "ERROR: Authentication failed."
        except (UnicodeError, socket.gaierror):
            sys.exit("ERROR: Not a valid URL.")
        else:
            break
    if verbose:
        print "NOTE: URL is " + url
        print "NOTE: Marker to set is " + marker
        print "NOTE: sender is " + sender
        print "NOTE: Recipient is " + recipient
        print "NOTE: Subject is '" + subject + "'"
    pages = collab.getMeta(search)
    for page in pages:
        if pages[page][k] == page_marker[k]:
            pass
        else:
            if verbose:
                print "NOTE: Rendering " + page + " to HTML"
            try:
                page_html = get_page_html(collab, page)
            except WikiFailure, msg:
                print "ERROR:", page, msg
            else:
                page_content[page] = page_html
    if page_content:
        try:
            page_html = get_page_html(collab, header)
        except WikiFailure, msg:
            header = None
        else:
            header = page_html
        try:
            page_html = get_page_html(collab, footer)
        except WikiFailure, msg:
            footer = None
        else:
            footer = page_html
        if verbose:
            print "NOTE: Notifying " + recipient + " via email."
        send_content(url, collab, page_content, sender, recipient, subject, header, footer, page_marker)
    else:
        if verbose:
            print "NOTE: No content, nothing to do. Exiting."

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print "Script interrupted via CTRL-C."
