Hi Matt, thanks for your hints.
On Sonntag, 12. Juni 2016 13:01:13 Matthew Dixon Cowles wrote: > Pete, > > > Note, that the subject line is missing. In my real filter, it left > > the current execution frame, and execution continued one or two > > level up the stack. > > The only thing I've run into that's like that is when an exception is > raised in a function that I didn't think would do that and was caught > in a place that I didn't expect. Yes, sure, that's a more common situation. > That it happens with the logging module and a non-ASCII encoding but > only when run in an environment with very few environment variables > also suggests something like that to me. > > I realize that that's not what your example code suggests, but if it > were obvious it would already be fixed. Yes, of course. BTW, I even tried to recreate the way, that postfix ought to run the filter with no positive result, either. There's something fishy going on here. Meanwhile, I've reduced the code to the bare minimum (attached). I also noticed, that the example mail is displayed in funny ways in my MUA, therefore attached again gzipped.. Thanks, Pete
umlaut-subject-2.mail.gz
Description: application/gzip
#!/usr/bin/env python3
import sys
import getopt
import logging
import subprocess
import email
import email.policy
import email.header
import email.generator
logfile = '/tmp/mail_filter_test.log'
logformat = '%(asctime)s [%(name)s] %(levelname)5s: %(message)s'
encoding = 'utf-8'
# setup logging
log = logging.getLogger('mail_filter_test')
EX_TEMPFAIL = 75 # queue and retry
SILLY_BEHAVIOR = 1
if SILLY_BEHAVIOR:
logging.basicConfig(
level = logging.DEBUG,
format = logformat,
filename = logfile,
)
else:
log.setLevel(logging.DEBUG)
filelog = logging.FileHandler(logfile, encoding = encoding)
filelog.setLevel(logging.DEBUG)
filelog.setFormatter(logging.Formatter(logformat))
log.addHandler(filelog)
def decode_header(value):
if value is not None:
value = str(email.header.make_header(email.header.decode_header(value)))
return value
def mail_filter(sender, recipients):
log.debug('parse message')
msg = email.message_from_binary_file(sys.stdin.buffer)
subject = decode_header(msg.get('subject'))
log.debug('subject: %s', subject)
sendmail = ['/usr/sbin/sendmail', '-G', '-i', '-f', sender, '--'] + recipients
log.debug('call %s', sendmail)
p = subprocess.Popen(sendmail, stdin = subprocess.PIPE)
email.generator.BytesGenerator(p.stdin).flatten(msg)
p.stdin.close()
return p.wait()
if __name__ == '__main__':
try:
optlist, recipients = getopt.getopt(sys.argv[1:], 'f:', 'from=')
except getopt.error as msg:
print(msg, file = sys.stderr, flush = True)
sys.exit(EX_TEMPFAIL)
sender = None
for opt, par in optlist:
if opt in ('-f', '--from'):
sender = par
if not sender or not recipients:
print('Usage: %s -f from-address to-addresses.. < mail' % sys.argv[0],
file = sys.stderr, flush = True)
sys.exit(EX_TEMPFAIL)
sys.exit(mail_filter(sender, recipients))
_______________________________________________ Email-SIG mailing list [email protected] Your options: https://mail.python.org/mailman/options/email-sig/archive%40mail-archive.com
