]> git.immae.eu Git - perso/Immae/Config/Nix.git/blob - systems/eldiron/ejabberd/warn_xmpp_email.py
Squash changes containing private information
[perso/Immae/Config/Nix.git] / systems / eldiron / ejabberd / warn_xmpp_email.py
1 #!@pythonEnv@/bin/python3
2
3 import sys
4 import json
5 import slixmpp
6 import asyncio
7 import logging
8 import io
9
10 CONFIG = json.load(open("@scriptEnv@", "r"))
11
12 def sanitize(string):
13 import re
14 from unidecode import unidecode
15 return re.compile(r"[^-.A-Za-z0-9_]").sub("_", unidecode(string))
16
17 def parse_email():
18 import email
19 from email.header import decode_header
20
21 mail = email.message_from_file(sys.stdin)
22 try:
23 d = decode_header(mail["subject"])[0]
24 if d[1] is not None:
25 subject = d[0].decode(d[1])
26 else:
27 subject = d[0]
28 except Exception as e:
29 subject = mail["subject"]
30 sender = mail["from"]
31 recipient = mail["X-Original-To"]
32
33 body = ""
34 html = None
35 files = {}
36 for part in mail.walk():
37 if part.get_content_type() == "text/plain":
38 body += "\n-------------------\n"
39 try:
40 body += part.get_payload(decode=True).decode(encoding=part.get_content_charset() or "utf-8")
41 except Exception as e:
42 body += part.get_payload(decode=False)
43 elif part.get_content_type() == "text/html":
44 html = part.get_payload(decode=True)
45 elif part.get_content_type() != "text/html" and\
46 part.get_content_maintype() != "multipart":
47
48 filename = part.get_filename() or "{}.dat".format(part["Content-ID"])
49 files[sanitize(filename)] = (part.get_content_type(), part.get_payload(decode=True))
50
51 return [body, html, subject, sender, recipient, files]
52
53 [body, html, subject, sender, recipient, files] = parse_email()
54
55 class Bot(slixmpp.ClientXMPP):
56 def __init__(self, jid, password, body, html, subject, sender, recipient, files):
57 super().__init__(jid, password)
58
59 self.got_error = False
60 self.body = body
61 self.html = html
62 self.subject = subject
63 self.sender = sender
64 self.recipient = recipient
65 self.files = files
66 self.register_plugin('xep_0363')
67 self.add_event_handler("session_start", self.session_start)
68 self.add_event_handler("message", self.message)
69
70 @asyncio.coroutine
71 def session_start(self, event):
72 files = []
73 if self.html is not None:
74 url = yield from self['xep_0363'].upload_file(
75 "mail.html",
76 content_type="text/html",
77 input_file=io.BytesIO(self.html))
78 files.append(("HTML version", url))
79 for f in self.files:
80 url = yield from self['xep_0363'].upload_file(
81 f,
82 content_type=self.files[f][0],
83 input_file=io.BytesIO(self.files[f][1])
84 )
85 files.append((f, url))
86
87 text = """
88 New e-mail message from {sender}
89 Subject: {subject}
90 {body}
91 """.format(sender=self.sender, subject=self.subject, body=self.body)
92 if len(files) > 0:
93 text += "\n\nAttachments:"
94 for f in files:
95 text += "\n{}: {}".format(f[0], f[1])
96 self.send_message(mto=self.recipient, mbody=text, msubject=self.subject, mtype='message')
97 yield from asyncio.sleep(5)
98 self.disconnect()
99
100 @asyncio.coroutine
101 def message(self, msg):
102 if msg["type"] == "error":
103 self.got_error = True
104
105 logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s')
106 xmpp = Bot(CONFIG["jid"], CONFIG["password"], body, html, subject, sender, recipient, files)
107 xmpp.connect()
108 xmpp.process(forever=False)
109 if xmpp.got_error:
110 sys.exit(1)
111 else:
112 sys.exit(0)