]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - systems/eldiron/ejabberd/warn_xmpp_email.py
Squash changes containing private information
[perso/Immae/Config/Nix.git] / systems / eldiron / ejabberd / warn_xmpp_email.py
diff --git a/systems/eldiron/ejabberd/warn_xmpp_email.py b/systems/eldiron/ejabberd/warn_xmpp_email.py
new file mode 100755 (executable)
index 0000000..d482b43
--- /dev/null
@@ -0,0 +1,112 @@
+#!@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)