aboutsummaryrefslogblamecommitdiff
path: root/systems/eldiron/ejabberd/warn_xmpp_email.py
blob: d482b43471c3c40dcb9286a48d2cb7ad5bff7b61 (plain) (tree)















































































































                                                                                                            
#!@pythonEnv@/bin/python3

import sys
import json
import slixmpp
import asyncio
import logging
import io

CONFIG = json.load(open("@scriptEnv@", "r"))

def sanitize(string):
    import re
    from unidecode import unidecode
    return re.compile(r"[^-.A-Za-z0-9_]").sub("_", unidecode(string))

def parse_email():
    import email
    from email.header import decode_header

    mail = email.message_from_file(sys.stdin)
    try:
        d = decode_header(mail["subject"])[0]
        if d[1] is not None:
            subject = d[0].decode(d[1])
        else:
            subject = d[0]
    except Exception as e:
        subject = mail["subject"]
    sender = mail["from"]
    recipient = mail["X-Original-To"]

    body = ""
    html = None
    files = {}
    for part in mail.walk():
        if part.get_content_type() == "text/plain":
            body += "\n-------------------\n"
            try:
                body += part.get_payload(decode=True).decode(encoding=part.get_content_charset() or "utf-8")
            except Exception as e:
                body += part.get_payload(decode=False)
        elif part.get_content_type() == "text/html":
            html = part.get_payload(decode=True)
        elif part.get_content_type() != "text/html" and\
                part.get_content_maintype() != "multipart":

            filename = part.get_filename() or "{}.dat".format(part["Content-ID"])
            files[sanitize(filename)] = (part.get_content_type(), part.get_payload(decode=True))

    return [body, html, subject, sender, recipient, files]

[body, html, subject, sender, recipient, files] = parse_email()

class Bot(slixmpp.ClientXMPP):
    def __init__(self, jid, password, body, html, subject, sender, recipient, files):
        super().__init__(jid, password)

        self.got_error = False
        self.body = body
        self.html = html
        self.subject = subject
        self.sender = sender
        self.recipient = recipient
        self.files = files
        self.register_plugin('xep_0363')
        self.add_event_handler("session_start", self.session_start)
        self.add_event_handler("message", self.message)

    @asyncio.coroutine
    def session_start(self, event):
        files = []
        if self.html is not None:
            url = yield from self['xep_0363'].upload_file(
                    "mail.html",
                    content_type="text/html",
                    input_file=io.BytesIO(self.html))
            files.append(("HTML version", url))
        for f in self.files:
            url = yield from self['xep_0363'].upload_file(
                    f,
                    content_type=self.files[f][0],
                    input_file=io.BytesIO(self.files[f][1])
                    )
            files.append((f, url))

        text = """
New e-mail message from {sender}
Subject: {subject}
{body}
""".format(sender=self.sender, subject=self.subject, body=self.body)
        if len(files) > 0:
            text += "\n\nAttachments:"
        for f in files:
            text += "\n{}: {}".format(f[0], f[1])
        self.send_message(mto=self.recipient, mbody=text, msubject=self.subject, mtype='message')
        yield from asyncio.sleep(5)
        self.disconnect()

    @asyncio.coroutine
    def message(self, msg):
        if msg["type"] == "error":
            self.got_error = True

logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s')
xmpp = Bot(CONFIG["jid"], CONFIG["password"], body, html, subject, sender, recipient, files)
xmpp.connect()
xmpp.process(forever=False)
if xmpp.got_error:
    sys.exit(1)
else:
    sys.exit(0)