summaryrefslogtreecommitdiff
path: root/sendmail-reinject
blob: e50c484aa3849b0fbb2fd1b9065de718eee4aee3 (plain)
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()