[Mailman-Developers] Mod to list_members to show nomail, digest types

Bob Puff@NLE bob@nleaudio.com
Mon, 12 Nov 2001 02:03:30 -0500


Hey gang,

A while back someone requested a way to get the listing of nomail list members.  I recently needed not
only that, but also the ability to sort out digest mime users, and digest plain text users.
Below is a replacement list_members program (that goes in $prefix/bin) that adds four new commands 
with which to accomplish this:

  -x = exclude nomail members
  -n = list only nomail members
  -m = list digest mime members
  -l = list plain text digest members

This script was modified from the 2.0.6 Mailman code - NOT tested with 2.1!!!  Enjoy!

Bob

========cut here=============
#! /usr/bin/env python
#
# Copyright (C) 1998,1999,2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

"""List all the members of a mailing list.

Usage: %(program)s [-o file] [-r] [-d] [-p] [-h] listname

Where:

    -o file or --output file
        Write output to specified file instead of standard out.

    -r or --regular
        Print just the regular (non-digest) members.

    -d or --digest
        Print just the digest members.

    -x or --exclude
        Exclude all nomail members from list
    
    -n or --nomail
        Print only the nomail members

    -l or --plain
        Print only plain text digest members

    -m or --mime
        Print only mime digest members

    -p or --preserve
        Output member addresses case preserved the way they were added to the
        list.  Otherwise, addresses are printed in all lowercase.

    -h or --help
        Print this help message and exit.

    listname is the name of the mailing list to use.

Note that if neither -r or -d is supplied, both regular members are printed
first, followed by digest members, but no indication is given as to address
status.

"""

import sys
import string
import getopt

import paths
from Mailman import MailList
from Mailman import Errors
from Mailman import Defaults
from Mailman import mm_cfg


program = sys.argv[0]

rmem = {}
dmem = {}

def usage(status, msg=''):
    print __doc__ % globals()
    if msg:
        print msg
    sys.exit(status)



def main():
    try:
        opts, args = getopt.getopt(
            sys.argv[1:],
            'dprnmxlo:h',
            ['digest', 'regular', 'preserve', 'nomail', 'mime', 'xclude', 'plain', 'output=', 'help'])
    except getopt.error, msg:
        usage(1, msg)

    if len(args) <> 1:
        usage(1)

    listname = string.lower(args[0])
    outfile = None
    regular = None
    digest = None
    preserve = None
    nomail = None
    mimef = None
    xclude = None
    plaint = None

    for opt, arg in opts:
        if opt in ('-h', '--help'):
            usage(0)
        elif opt in ('-o', '--output'):
            outfile = arg
        elif opt in ('-r', '--regular'):
            regular = 1
        elif opt in ('-d', '--digest'):
            digest = 1
        elif opt in ('-p', '--preserve'):
            preserve = 1
        elif opt in ('-n', '--nomail'):
            nomail = 1
        elif opt in ('-m', '--mime'):
            mimef = 1
        elif opt in ('-x', '--exclude-nomail'):
            xclude = 1
        elif opt in ('-l', '--plain'):
            plaint = 1
    if plaint:
        digest = 1
    if mimef:
        digest = 1
    if regular is None and digest is None:
        regular = digest = 1
    if xclude is None and nomail is None:
        xclude = nomail = 1
    if mimef is None and plaint is None:
        mimef = plaint = 1 

    if outfile:
        try:
            fp = open(outfile, 'w')
        except IOError:
            print 'Could not open file for writing:', outfile
            sys.exit(1)
    else:
        fp = sys.stdout

    try:
        mlist = MailList.MailList(listname, lock=0)
    except Errors.MMListError, e:
        print 'No such list "%s"\n%s' % (listname, e)
        sys.exit(1)

    # filters for recipient calculation
    def delivery_enabled_p(x, s=mlist, v=mm_cfg.DisableDelivery):
        return not s.GetUserOption(x, v)
    def delivery_disabled_p(x, s=mlist, v=mm_cfg.DisableDelivery):
        return s.GetUserOption(x, v)
    def likes_mime_p(x, s=mlist, v=mm_cfg.DisableMime):
        return not s.GetUserOption(x, v)
    def hates_mime_p(x, s=mlist, v=mm_cfg.DisableMime):
        return s.GetUserOption(x, v)   

    if preserve:
         for addr in mlist.GetDeliveryMembers():
             rmem[addr] = addr
         for addr in mlist.GetDigestDeliveryMembers():
             dmem[addr] = addr
    else:
         for addr in mlist.GetMembers():
             rmem[addr] = addr
         for addr in mlist.GetDigestMembers():
             dmem[addr] = addr

    rmembers = filter(delivery_enabled_p, rmem.keys())
    rnomembers = filter(delivery_disabled_p, rmem.keys())
    dmem2 = filter(delivery_enabled_p, dmem.keys())
    dmembers = filter(hates_mime_p, dmem2)
    dmime = filter(likes_mime_p, dmem2)
    dmem2 = filter(delivery_disabled_p, dmem.keys())
    dnomembers = filter(hates_mime_p, dmem2)
    dnomime = filter(likes_mime_p, dmem2)

    stdout = sys.stdout
    try:
        sys.stdout = fp
        if regular:
            if xclude:
                for addr in rmembers:
                    print addr
            if nomail:
                for addr in rnomembers:
                    print addr
        if digest:
            if xclude:
                if plaint:
                    for addr in dmembers:
                        print addr
                if mimef:
                    for addr in dmime:
                        print addr
            if nomail:
                if plaint:
                    for addr in dnomembers:
                        print addr
                if mimef:
                    for addr in dnomime:
                        print addr

    finally:
        sys.stdout = stdout


if __name__ == '__main__':
    main()