commit e9b94a2adbe6dc45922c5784b503658272f8b74b Author: Adam Goldsmith Date: Sat Dec 24 14:04:29 2022 -0500 Initial Commit diff --git a/mailman_sync.py b/mailman_sync.py new file mode 100755 index 0000000..86f9332 --- /dev/null +++ b/mailman_sync.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 + +""" +Update Mailman 2 lists via a json API of the form {"LIST": ["ADDRESS", ...]} +""" + +import argparse +from pathlib import Path +import subprocess + +import requests + + +def sync_members(mailman_bin: Path, mailing_list: str, members: list[str]): + members_file = "\n".join(members) + output = subprocess.run( + [ + mailman_bin / "sync_members", + "--no-change", + "--welcome-msg=no", + "--goodbye-msg=no", + "--notifyadmin=no", + "--file", + "-", + mailing_list, + ], + input=members_file, + capture_output=True, + check=True, + ) + print(output) + + +def main(mailman_bin: Path, api: str, token: str, list_suffix: str): + r = requests.get(api, headers={"Authorization": "Token " + token}) + if not r.ok: + print(f"Failed to get mailing list data from api: {r.status_code} {r.text}") + return + + existing_lists = subprocess.run( + [mailman_bin / "list_lists", "-b"], capture_output=True, check=True + ).stdout.split("\n") + certification_lists = r.json() + for name, members in certification_lists.items(): + print(name, "\n".join(members)) + if name + list_suffix in existing_lists: + sync_members(mailman_bin, name, members) + + +if __name__ == "__main__": + argp = argparse.ArgumentParser(description=__doc__) + argp.add_argument( + "--bin", + default="/usr/local/mailman", + type=Path, + help="Path to Mailman site admin scripts (default %(default)s)", + ) + argp.add_argument("--api", required=True, help="API endpoint to retrieve JSON from") + argp.add_argument("--token", required=True, help="Authorization Token for API") + argp.add_argument("--list-suffix", help="Suffix for mailing lists") + args = argp.parse_args() + + main(args.bin, args.api, args.token, args.list_suffix)