]>
Commit | Line | Data |
---|---|---|
1a64deeb IB |
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) |