123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- #!/usr/bin/python3
- import smtplib
- import os
- from email.mime.multipart import MIMEMultipart
- from email.mime.text import MIMEText
- from email.utils import COMMASPACE, formatdate
- import jinja2
- from jinja2.sandbox import SandboxedEnvironment
- import redis
- import time
- import json
- import sys
- import html2text
- from subprocess import Popen, PIPE, STDOUT
- if len(sys.argv) > 2:
- percent = int(sys.argv[1])
- username = str(sys.argv[2])
- else:
- print("Args missing")
- sys.exit(1)
- while True:
- try:
- r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0, username='quota_notify', password='')
- r.ping()
- except Exception as ex:
- print('%s - trying again...' % (ex))
- time.sleep(3)
- else:
- break
- if r.get('QW_HTML'):
- try:
- env = SandboxedEnvironment()
- template = env.from_string(r.get('QW_HTML'))
- except Exception:
- print("Error: Cannot parse quota template, falling back to default template.")
- with open('/templates/quota.tpl') as file_:
- env = SandboxedEnvironment()
- template = env.from_string(file_.read())
- else:
- with open('/templates/quota.tpl') as file_:
- env = SandboxedEnvironment()
- template = env.from_string(file_.read())
- try:
- html = template.render(username=username, percent=percent)
- except (jinja2.exceptions.SecurityError, jinja2.TemplateError) as ex:
- print(f"SecurityError or TemplateError in template rendering: {ex}")
- sys.exit(1)
- text = html2text.html2text(html)
- try:
- msg = MIMEMultipart('alternative')
- msg['From'] = r.get('QW_SENDER') or "quota-warning@localhost"
- msg['Subject'] = r.get('QW_SUBJ') or "Quota warning"
- msg['Date'] = formatdate(localtime = True)
- text_part = MIMEText(text, 'plain', 'utf-8')
- html_part = MIMEText(html, 'html', 'utf-8')
- msg.attach(text_part)
- msg.attach(html_part)
- msg['To'] = username
- p = Popen(['/usr/libexec/dovecot/dovecot-lda', '-d', username, '-o', '"plugin/quota=maildir:User quota:noenforcing"'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
- p.communicate(input=bytes(msg.as_string(), 'utf-8'))
- domain = username.split("@")[-1]
- if domain and r.hget('QW_BCC', domain):
- bcc_data = json.loads(r.hget('QW_BCC', domain))
- bcc_rcpts = bcc_data['bcc_rcpts']
- if bcc_data['active'] == 1:
- for rcpt in bcc_rcpts:
- msg = MIMEMultipart('alternative')
- msg['From'] = username
- subject = r.get('QW_SUBJ') or "Quota warning"
- msg['Subject'] = subject + ' (' + username + ')'
- msg['Date'] = formatdate(localtime = True)
- text_part = MIMEText(text, 'plain', 'utf-8')
- html_part = MIMEText(html, 'html', 'utf-8')
- msg.attach(text_part)
- msg.attach(html_part)
- msg['To'] = rcpt
- server = smtplib.SMTP('postfix', 588, 'quotanotification')
- server.ehlo()
- server.sendmail(msg['From'], str(rcpt), msg.as_string())
- server.quit()
- except Exception as ex:
- print('Failed to send quota notification: %s' % (ex))
- sys.exit(1)
- try:
- sys.stdout.close()
- except:
- pass
- try:
- sys.stderr.close()
- except:
- pass
|