From 3d778791f91c1440fb6a5a7418d9549071ee7814 Mon Sep 17 00:00:00 2001 From: Jon Turney Date: Sat, 8 Jul 2023 13:23:11 +0100 Subject: Factor out email sending to utils Smooth out some issues when --email isn't specified, making args.email an empty list rather than None, which can't be iterated. When the To: address is 'debug', dump email to log, rather than stdout. --- calm/buffering_smtp_handler.py | 44 ++++++++++-------------------------------- calm/calm.py | 2 +- calm/utils.py | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/calm/buffering_smtp_handler.py b/calm/buffering_smtp_handler.py index f6d5f34..d0a8119 100644 --- a/calm/buffering_smtp_handler.py +++ b/calm/buffering_smtp_handler.py @@ -21,13 +21,11 @@ # -import email.message -import email.utils import logging import logging.handlers -import subprocess from . import common_constants +from . import utils class BufferingSMTPHandler(logging.handlers.BufferingHandler): @@ -60,37 +58,15 @@ class BufferingSMTPHandler(logging.handlers.BufferingHandler): msg = msg + 'SUMMARY: ' + ', '.join(['%d %s(s)' % (v, k) for (k, v) in summary.items()]) + "\r\n" - # build the email - m = email.message.Message() - m['From'] = self.fromaddr - m['To'] = ','.join(self.toaddrs) - m['Reply-To'] = self.replytoaddr - m['Bcc'] = common_constants.ALWAYS_BCC - m['Subject'] = self.subject - m['Message-Id'] = email.utils.make_msgid() - m['Date'] = email.utils.formatdate() - m['X-Calm'] = '1' - - # use utf-8 only if the message can't be ascii encoded - charset = 'ascii' - try: - msg.encode('ascii') - except UnicodeError: - charset = 'utf-8' - m.set_payload(msg, charset=charset) - - # if toaddrs consists of the single address 'debug', just dump the mail we would have sent - if self.toaddrs == ['debug']: - print('-' * 40) - for k in m: - print('%s: %s' % (k, m[k])) - print('-' * 40) - print(msg) - print('-' * 40) - else: - with subprocess.Popen(['/usr/sbin/sendmail', '-t', '-oi', '-f', self.fromaddr], stdin=subprocess.PIPE) as p: - p.communicate(m.as_bytes()) - logging.debug('sendmail: msgid %s, exit status %d' % (m['Message-Id'], p.returncode)) + hdr = {} + hdr['From'] = self.fromaddr + hdr['To'] = ','.join(self.toaddrs) + hdr['Reply-To'] = self.replytoaddr + hdr['Bcc'] = common_constants.ALWAYS_BCC + hdr['Subject'] = self.subject + hdr['X-Calm-Report'] = '1' + + utils.sendmail(hdr, msg) self.buffer = [] diff --git a/calm/calm.py b/calm/calm.py index 7ea4739..a839873 100755 --- a/calm/calm.py +++ b/calm/calm.py @@ -754,7 +754,7 @@ def main(): parser = argparse.ArgumentParser(description='Upset replacement') parser.add_argument('-d', '--daemon', action='store', nargs='?', const=pidfile_default, help="daemonize (PIDFILE defaults to " + pidfile_default + ")", metavar='PIDFILE') - parser.add_argument('--email', action='store', dest='email', nargs='?', const=common_constants.EMAILS, help="email output to maintainer and ADDRS (ADDRS defaults to '" + common_constants.EMAILS + "')", metavar='ADDRS') + parser.add_argument('--email', action='store', dest='email', nargs='?', default='', const=common_constants.EMAILS, help="email output to maintainer and ADDRS (ADDRS defaults to '" + common_constants.EMAILS + "')", metavar='ADDRS') parser.add_argument('--force', action='count', help="force regeneration of static htdocs content", default=0) parser.add_argument('--homedir', action='store', metavar='DIR', help="maintainer home directory (default: " + homedir_default + ")", default=homedir_default) parser.add_argument('--htdocs', action='store', metavar='DIR', help="htdocs output directory (default: " + htdocs_default + ")", default=htdocs_default) diff --git a/calm/utils.py b/calm/utils.py index 9f75813..47085fd 100644 --- a/calm/utils.py +++ b/calm/utils.py @@ -25,6 +25,8 @@ # utility functions # +import email.message +import email.utils import filecmp import logging import os @@ -158,3 +160,39 @@ def mtime_cache(user_function): return result return wrapper + + +def sendmail(hdr, msg): + # sending email not enabled + if not hdr['To']: + return + + # build the email + m = email.message.Message() + + for h in hdr: + m[h] = hdr[h] + m['Message-Id'] = email.utils.make_msgid() + m['Date'] = email.utils.formatdate() + m['X-Calm'] = '1' + + # use utf-8 only if the message can't be ascii encoded + charset = 'ascii' + try: + msg.encode('ascii') + except UnicodeError: + charset = 'utf-8' + m.set_payload(msg, charset=charset) + + # if To: header consists of the single address 'debug', just dump the mail we would have sent + if m['To'] == 'debug': + logging.debug('-' * 40) + for k in m: + logging.debug('%s: %s' % (k, m[k])) + logging.debug('-' * 40) + logging.debug(msg) + logging.debug('-' * 40) + else: + with subprocess.Popen(['/usr/sbin/sendmail', '-t', '-oi', '-f', hdr['From']], stdin=subprocess.PIPE) as p: + p.communicate(m.as_bytes()) + logging.debug('sendmail: msgid %s, exit status %d' % (m['Message-Id'], p.returncode)) -- cgit v1.2.3