#! /usr/bin/env python # # Copyright (C) 2007 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. # # 2007/12/24 - MAS - Fixed a minor bug that could have resulted in adding # duplicates in non-verbose mode. # # 2021/04/12 - MAS - Lower cased list name arguments. """Add or remove addresses to/from *_these_nonmembers Usage: %(PROGRAM)s [options] Where: --list=listname / -l listname The name of the list to process. May be repeated for multiple lists. The default is to do all lists. --filter=accept|hold|reject|discard / -f accept|hold|reject|discard specify which *_these_non_members to add to and remove from. Defaults to accept for add and all filters for remove. --add=address / -a address The address is to be added to the filter. May be repeated for multiple addresses. --remove=address / -r address The address is to be removed from the filter. May be repeated for multiple addresses. --verbose / -v Prints already added or not found messages. --help / -h Print this help message and exit. The address argument can be anything legal (or illegal - it isn't validated) for *_these_nonmembers. In particular, you can add an invalid regexp which will cause Mailman errors. Be careful. You can mix adds and removes in the same invocation. If you add and remove the same address to/from the same filter, the net result will be to remove it. This script must run from Mailman's bin/ directory. """ import sys import getopt import paths from Mailman import Utils from Mailman import MailList from Mailman.i18n import _ PROGRAM = sys.argv[0] try: True, False except NameError: True = 1 False = 0 def usage(code, msg=''): if code: fd = sys.stderr else: fd = sys.stdout print >> fd, _(__doc__) if msg: print >> fd, msg sys.exit(code) def main(): try: opts, args = getopt.getopt( sys.argv[1:], 'hl:f:a:r:v', ['help', 'list=', 'filter=', 'add=', 'remove=', 'verbose']) except getopt.error, msg: usage(1, msg) lists = [] adds = [] removes = [] filter = None verbose = False for opt, arg in opts: if opt in ('-h', '--help'): usage(0) elif opt in ('-l', '--list'): arg = arg.lower() if not Utils.list_exists(arg): usage(1, _('Non-existent list: %(arg)s')) lists.append(arg) elif opt in ('-f', '--filter'): if arg == 'accept': filter = 0 elif arg == 'hold': filter = 1 elif arg == 'reject': filter = 2 elif arg == 'discard': filter = 3 else: usage(1, _('Unrecognized filter: %(arg)s')) elif opt in ('-a', '--add'): adds.append(arg) elif opt in ('-r', '--remove'): removes.append(arg) elif opt in ('-v', '--verbose'): verbose = True else: usage(1, _('Unrecognized option: %(opt)s')) if len(args) <> 0: usage(1, _('Unrecognized argument: %(args)s')) if not adds and not removes: usage(1, _('No addresses to add or remove')) if not lists: lists = Utils.list_names() try: for list in lists: mlist = MailList.MailList(list, lock=True) for address in adds: if filter in (0, None): if address in mlist.accept_these_nonmembers: if verbose: print _( "%(address)s already in %(list)s's accept_these_nonmembers") else: mlist.accept_these_nonmembers.append(address) if filter == 1: if address in mlist.hold_these_nonmembers: if verbose: print _( "%(address)s already in %(list)s's hold_these_nonmembers") else: mlist.hold_these_nonmembers.append(address) if filter == 2: if address in mlist.reject_these_nonmembers: if verbose: print _( "%(address)s already in %(list)s's reject_these_nonmembers") else: mlist.reject_these_nonmembers.append(address) if filter == 3: if address in mlist.discard_these_nonmembers: if verbose: print _( "%(address)s already in %(list)s's discard_these_nonmembers") else: mlist.discard_these_nonmembers.append(address) for address in removes: removed = False if filter in (0, None): if address not in mlist.accept_these_nonmembers: if filter == 0 and verbose: print _( "%(address)s not in %(list)s's accept_these_nonmembers") else: removed = True mlist.accept_these_nonmembers.remove(address) if filter in (1, None): if address not in mlist.hold_these_nonmembers: if filter == 1 and verbose: print _( "%(address)s not in %(list)s's hold_these_nonmembers") else: removed = True mlist.hold_these_nonmembers.remove(address) if filter in (2, None): if address not in mlist.reject_these_nonmembers: if filter == 2 and verbose: print _( "%(address)s not in %(list)s's reject_these_nonmembers") else: removed = True mlist.reject_these_nonmembers.remove(address) if filter in (3, None): if address not in mlist.discard_these_nonmembers: if filter == 3 and verbose: print _( "%(address)s not in %(list)s's discard_these_nonmembers") else: removed = True mlist.discard_these_nonmembers.remove(address) if verbose and filter == None and not removed: print _("%(address)s not in %(list)s's *_these_nonmembers") mlist.Save() finally: mlist.Unlock() if __name__ == '__main__': main()