Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1 | #!/usr/bin/python3 |
| 2 | |
| 3 | import smtplib |
| 4 | import os |
| 5 | from email.mime.multipart import MIMEMultipart |
| 6 | from email.mime.text import MIMEText |
| 7 | from email.utils import COMMASPACE, formatdate |
| 8 | import jinja2 |
| 9 | from jinja2 import Template |
| 10 | import redis |
| 11 | import time |
Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 12 | import json |
Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 13 | import sys |
| 14 | import html2text |
| 15 | from subprocess import Popen, PIPE, STDOUT |
| 16 | |
| 17 | if len(sys.argv) > 2: |
| 18 | percent = int(sys.argv[1]) |
| 19 | username = str(sys.argv[2]) |
| 20 | else: |
| 21 | print("Args missing") |
| 22 | sys.exit(1) |
| 23 | |
| 24 | while True: |
| 25 | try: |
| 26 | r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0) |
| 27 | r.ping() |
| 28 | except Exception as ex: |
| 29 | print('%s - trying again...' % (ex)) |
| 30 | time.sleep(3) |
| 31 | else: |
| 32 | break |
| 33 | |
| 34 | if r.get('QW_HTML'): |
| 35 | try: |
| 36 | template = Template(r.get('QW_HTML')) |
| 37 | except: |
| 38 | print("Error: Cannot parse quarantine template, falling back to default template.") |
| 39 | with open('/templates/quota.tpl') as file_: |
| 40 | template = Template(file_.read()) |
| 41 | else: |
| 42 | with open('/templates/quota.tpl') as file_: |
| 43 | template = Template(file_.read()) |
| 44 | |
| 45 | html = template.render(username=username, percent=percent) |
| 46 | text = html2text.html2text(html) |
| 47 | |
| 48 | try: |
| 49 | msg = MIMEMultipart('alternative') |
| 50 | msg['From'] = r.get('QW_SENDER') or "quota-warning@localhost" |
| 51 | msg['Subject'] = r.get('QW_SUBJ') or "Quota warning" |
| 52 | msg['Date'] = formatdate(localtime = True) |
| 53 | text_part = MIMEText(text, 'plain', 'utf-8') |
| 54 | html_part = MIMEText(html, 'html', 'utf-8') |
| 55 | msg.attach(text_part) |
| 56 | msg.attach(html_part) |
| 57 | msg['To'] = username |
| 58 | p = Popen(['/usr/lib/dovecot/dovecot-lda', '-d', username, '-o', '"plugin/quota=maildir:User quota:noenforcing"'], stdout=PIPE, stdin=PIPE, stderr=STDOUT) |
| 59 | p.communicate(input=bytes(msg.as_string(), 'utf-8')) |
| 60 | |
Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 61 | domain = username.split("@")[-1] |
| 62 | if domain and r.hget('QW_BCC', domain): |
| 63 | bcc_data = json.loads(r.hget('QW_BCC', domain)) |
| 64 | bcc_rcpts = bcc_data['bcc_rcpts'] |
| 65 | if bcc_data['active'] == 1: |
| 66 | for rcpt in bcc_rcpts: |
| 67 | msg = MIMEMultipart('alternative') |
| 68 | msg['From'] = username |
| 69 | subject = r.get('QW_SUBJ') or "Quota warning" |
| 70 | msg['Subject'] = subject + ' (' + username + ')' |
| 71 | msg['Date'] = formatdate(localtime = True) |
| 72 | text_part = MIMEText(text, 'plain', 'utf-8') |
| 73 | html_part = MIMEText(html, 'html', 'utf-8') |
| 74 | msg.attach(text_part) |
| 75 | msg.attach(html_part) |
| 76 | msg['To'] = rcpt |
| 77 | server = smtplib.SMTP('postfix', 588, 'quotanotification') |
| 78 | server.ehlo() |
| 79 | server.sendmail(msg['From'], str(rcpt), msg.as_string()) |
| 80 | server.quit() |
| 81 | |
Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 82 | except Exception as ex: |
| 83 | print('Failed to send quota notification: %s' % (ex)) |
| 84 | sys.exit(1) |
| 85 | |
| 86 | try: |
| 87 | sys.stdout.close() |
| 88 | except: |
| 89 | pass |
| 90 | |
| 91 | try: |
| 92 | sys.stderr.close() |
| 93 | except: |
| 94 | pass |