From 59aadbb537da3961579e8cc8ec7e497886438253 Mon Sep 17 00:00:00 2001 From: Patrick Cernko <pcernko@mpi-klsb.mpg.de> Date: Wed, 17 Jan 2024 10:17:58 +0100 Subject: [PATCH] reading member config exported from `mailman-subscribers3.py --json` generating member.dump from member config added moderated resp. whitelisted members to corresponding list if list is "open" resp. moderated, thus writing out modlist.txt set creation_email to first owner in XML normalize all emails for LDAP users to their primary mail address to allow mapping membership/ownership for logged in users --- gen_config.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/gen_config.py b/gen_config.py index 145cff1..293a130 100755 --- a/gen_config.py +++ b/gen_config.py @@ -5,16 +5,31 @@ import sys import argparse import xml.etree.ElementTree as ET +import json +import mpildap +def normalize_email(email): + lp, domain = email.split('@') + ldap_mail = mpildap.ldaps(f'&(istEmailName={lp})(istMailDomainReceive={domain})', 'mail', unique=True) + if ldap_mail: + return ldap_mail[0] + return email parser = argparse.ArgumentParser(description='import mailman list to sympa') parser.add_argument('input') +parser.add_argument('membersin') parser.add_argument('output') parser.add_argument('info') parser.add_argument('blocklist') parser.add_argument('whitelist') +parser.add_argument('modlist') +parser.add_argument('membersout') args = parser.parse_args() +members = {} +with open(args.membersin) as fd: + for m, d in json.load(fd).items(): + members[normalize_email(m)] = d old_vars = {} with open(args.input) as fd: @@ -94,11 +109,13 @@ if old_vars['anonymous_list']: ET.SubElement(xml, 'anonymous_sender').text = old_vars['new_listname'] + '@' + old_vars['robot'] # send +moderated = False if old_vars['generic_nonmember_action'] == 0: # accept ET.SubElement(xml, 'send').text = 'public' elif old_vars['generic_nonmember_action'] >= 1: # hold, reject, discard if old_vars['default_member_moderation']: ET.SubElement(xml, 'send').text = 'editorkey' + moderated = True else: ET.SubElement(xml, 'send').text = 'privateoreditorkey' @@ -150,14 +167,14 @@ else: # digest_footer not used -# XXX: does this work? +ET.SubElement(xml, "creation_email").text = normalize_email(old_vars['owner'][0]) for owner in old_vars['owner']: o = ET.SubElement(xml, "owner", attrib={'multiple':'1'}) - ET.SubElement(o, "email").text = owner + ET.SubElement(o, "email").text = normalize_email(owner) for mod in old_vars['moderator']: o = ET.SubElement(xml, "editor", attrib={'multiple':'1'}) - ET.SubElement(o, "email").text = mod + ET.SubElement(o, "email").text = normalize_email(mod) tree = ET.ElementTree(xml) @@ -167,6 +184,9 @@ except Exception as e: print(f'Failed to write XML for sympa: {e}', file=sys.stderr) exit(1) +with open(args.info, mode='w') as fd: + fd.write(old_vars['info']) + blocklist = [] for black in sorted(set(old_vars['ban_list'] + old_vars['hold_these_nonmembers'] + old_vars['reject_these_nonmembers'] + old_vars['discard_these_nonmembers'])): for char in '*^$': @@ -186,11 +206,52 @@ for white in sorted(set(old_vars['accept_these_nonmembers'])): if char in white: print(f"whitelist entry '{white}' contains regexp char '{char}', this won't work!", file=sys.stderr) whitelist.append(white) +if moderated: + for m, d in members.items(): + if d['_mod'] == 'off': + print(f'Whitelisting member "{m}" for list with moderated policy', file=sys.stderr) + whitelist.append(m) if whitelist: # ensure non-empty file ends with newline whitelist.append('') with open(args.whitelist, mode='w') as fd: fd.write('\n'.join(whitelist)) +modlist = [] +if not moderated: + for m, d in members.items(): + if d['_mod'] == 'on': + print(f'Mod-listing member "{m}" for list with open policy', file=sys.stderr) + modlist.append(m) +if modlist: + # ensure non-empty file ends with newline + modlist.append('') +with open(args.modlist, mode='w') as fd: + fd.write('\n'.join(modlist)) + with open(args.info, mode='w') as fd: fd.write(old_vars['info']) + +with open(args.membersout, mode='w') as fd: + for m, d in members.items(): + email = m + gecos = d['_realname'] + reception = 'mail' + if d['_nomail'] != "off": + reception = 'nomail' + elif d['_digest'] == 'on': + if d['_plain'] == 'on': + reception = 'digestplain' + else: + reception = 'digest' + elif d['_notmetoo'] == 'on': + reception = 'not_me' + visibility = 'noconceal' + if d['_hide'] == 'on': + visibility = 'conceal' + print(f"""email {email} +gecos {gecos} +reception {reception} +subscribed 1 +visibility {visibility} +""", file=fd) -- GitLab