1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2022 Jameson Graef Rollins
import sys
import argparse
import subprocess
import email
from email.policy import default
from email.utils import parseaddr, getaddresses
def sendmail(recipients, message, sender):
"""send message via sendmail"""
cmd = [
'sendmail',
'-f', sender,
] + recipients
print(' '.join(cmd), file=sys.stderr)
subprocess.run(
cmd,
input=message.as_bytes(),
check=True,
)
def main():
parser = argparse.ArgumentParser(
description="Reinject an email message via sendmail.",
)
pgroup = parser.add_mutually_exclusive_group(required=True)
pgroup.add_argument(
'message', nargs='?', type=argparse.FileType('rb'),
help="email message path or '-' for stdin",
)
pgroup.add_argument(
'-i', '--notmuch-id',
help="message ID for notmuch extraction",
)
args = parser.parse_args()
if args.id:
import notmuch2 as notmuch
db = notmuch.Database()
query = f'id:{args.id}'
assert db.count_messages(query) == 1, "Message ID does not match exactly one message??"
for msg in db.messages(query):
path = msg.path
break
f = open(path, 'rb')
else:
f = args.message
# parse the email message
msg = email.message_from_binary_file(f, policy=default)
sender = parseaddr(msg['from'])[1]
# extract all recipients
tos = msg.get_all('to', [])
ccs = msg.get_all('cc', [])
resent_tos = msg.get_all('resent-to', [])
resent_ccs = msg.get_all('resent-cc', [])
recipients = [r[1] for r in getaddresses(tos + ccs + resent_tos + resent_ccs)]
sendmail(recipients, msg, sender)
if __name__ == '__main__':
main()
|