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

Attachment: 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-SIG@python.org
Your options: 
https://mail.python.org/mailman/options/email-sig/archive%40mail-archive.com

Reply via email to