~mailman-coders/mailman/2.1

1 by
This commit was manufactured by cvs2svn to create branch
1
#! @PYTHON@
2
#
1779 by Mark Sapiro
Bump copyright dates.
3
# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
1 by
This commit was manufactured by cvs2svn to create branch
4
#
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU General Public License
7
# as published by the Free Software Foundation; either version 2
8
# of the License, or (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
749 by tkikuchi
FSF office has moved to 51 Franklin Street.
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1 by
This commit was manufactured by cvs2svn to create branch
18
19
"""List all the members of a mailing list.
20
21
Usage: %(PROGRAM)s [options] listname
22
23
Where:
24
25
    --output file
26
    -o file
27
        Write output to specified file instead of standard out.
28
29
    --regular / -r
30
        Print just the regular (non-digest) members.
31
1340.1.3 by Axel Beckert
list_members Usage: Keep regular/digest and moderated/non-moderated options together
32
    --digest[=kind] / -d [kind]
33
        Print just the digest members.  Optional argument can be "mime" or
34
        "plain" which prints just the digest members receiving that kind of
35
        digest.
36
1 by
This commit was manufactured by cvs2svn to create branch
37
    --nomail[=why] / -n [why]
38
        Print the members that have delivery disabled.  Optional argument can
39
        be "byadmin", "byuser", "bybounce", or "unknown" which prints just the
40
        users who have delivery disabled for that reason.  It can also be
41
        "enabled" which prints just those member for whom delivery is
42
        enabled.
43
44
    --fullnames / -f
45
        Include the full names in the output.
46
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
47
    --preserve / -p
1 by
This commit was manufactured by cvs2svn to create branch
48
        Output member addresses case preserved the way they were added to the
49
        list.  Otherwise, addresses are printed in all lowercase.
50
1594 by Mark Sapiro
Added options to display (non)moderated members to list_members.
51
    --moderated / -m
52
        Print just the moderated members.  Ignores -r, -d, -n.
53
54
    --non-moderated / -M
55
        Print just the non-moderated members.  Ignores -r, -d, -n.
56
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
57
    --invalid / -i
58
        Print only the addresses in the membership list that are invalid.
59
        Ignores -r, -d, -n.
60
61
    --unicode / -u
62
        Print addresses which are stored as Unicode objects instead of normal
63
        string objects.  Ignores -r, -d, -n.
64
1 by
This commit was manufactured by cvs2svn to create branch
65
    --help
66
    -h
67
        Print this help message and exit.
68
69
    listname is the name of the mailing list to use.
70
1594 by Mark Sapiro
Added options to display (non)moderated members to list_members.
71
Note that if neither -r or -d is supplied, regular members are printed first,
72
followed by digest members, but no indication is given as to address status.
1 by
This commit was manufactured by cvs2svn to create branch
73
"""
74
75
import sys
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
76
from types import UnicodeType
1 by
This commit was manufactured by cvs2svn to create branch
77
78
import paths
79
from Mailman import mm_cfg
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
80
from Mailman import Utils
1 by
This commit was manufactured by cvs2svn to create branch
81
from Mailman import MailList
82
from Mailman import Errors
83
from Mailman import MemberAdaptor
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
84
from Mailman.i18n import C_
1 by
This commit was manufactured by cvs2svn to create branch
85
86
from email.Utils import formataddr
87
88
PROGRAM = sys.argv[0]
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
89
ENC = sys.getdefaultencoding()
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
90
COMMASPACE = ', '
91
92
try:
93
    True, False
94
except NameError:
95
    True = 1
96
    False = 0
97
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
98
1 by
This commit was manufactured by cvs2svn to create branch
99
WHYCHOICES = {'enabled' : MemberAdaptor.ENABLED,
100
              'unknown' : MemberAdaptor.UNKNOWN,
101
              'byuser'  : MemberAdaptor.BYUSER,
102
              'byadmin' : MemberAdaptor.BYADMIN,
103
              'bybounce': MemberAdaptor.BYBOUNCE,
104
              }
105
106
107
def usage(code, msg=''):
108
    if code:
109
        fd = sys.stderr
110
    else:
111
        fd = sys.stdout
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
112
    print >> fd, C_(__doc__)
1 by
This commit was manufactured by cvs2svn to create branch
113
    if msg:
114
        print >> fd, msg
115
    sys.exit(code)
116
117
118

26 by bwarsaw
Backporting various fixes and improvements from the trunk.
119
def safe(s):
120
    if not s:
121
        return ''
122
    if isinstance(s, UnicodeType):
123
        return s.encode(ENC, 'replace')
124
    return unicode(s, ENC, 'replace').encode(ENC, 'replace')
125
126
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
127
def isinvalid(addr):
128
    try:
129
        Utils.ValidateEmail(addr)
130
        return False
131
    except Errors.EmailAddressError:
132
        return True
133
134
def isunicode(addr):
135
    return isinstance(addr, UnicodeType)
136
137
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
138

1 by
This commit was manufactured by cvs2svn to create branch
139
def whymatches(mlist, addr, why):
140
    # Return true if the `why' matches the reason the address is enabled, or
141
    # in the case of why is None, that they are disabled for any reason
142
    # (i.e. not enabled).
143
    status = mlist.getDeliveryStatus(addr)
144
    if why is None:
145
        return status <> MemberAdaptor.ENABLED
146
    return status == WHYCHOICES[why]
147
148
149

150
def main():
151
    # Because of the optional arguments, we can't use getopt. :(
152
    outfile = None
153
    regular = None
154
    digest = None
155
    preserve = None
156
    nomail = None
157
    why = None
158
    kind = None
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
159
    fullnames = False
160
    invalidonly = False
161
    unicodeonly = False
1340.1.1 by Axel Beckert
Add commandline options to list (non-) moderated list members
162
    moderatedonly = False
1340.1.2 by Axel Beckert
Consistently use "non moderated" instead of "not moderated"
163
    nonmoderatedonly = False
1 by
This commit was manufactured by cvs2svn to create branch
164
165
    # Throw away the first (program) argument
166
    args = sys.argv[1:]
167
    if not args:
168
        usage(0)
169
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
170
    while True:
1 by
This commit was manufactured by cvs2svn to create branch
171
        try:
172
            opt = args.pop(0)
173
        except IndexError:
174
            usage(1)
175
        if opt in ('-h', '--help'):
176
            usage(0)
177
        elif opt in ('-f', '--fullnames'):
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
178
            fullnames = True
1 by
This commit was manufactured by cvs2svn to create branch
179
        elif opt in ('-p', '--preserve'):
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
180
            preserve = True
1 by
This commit was manufactured by cvs2svn to create branch
181
        elif opt in ('-r', '--regular'):
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
182
            regular = True
1 by
This commit was manufactured by cvs2svn to create branch
183
        elif opt in ('-o', '--output'):
184
            try:
185
                outfile = args.pop(0)
186
            except IndexError:
187
                usage(1)
188
        elif opt == '-n':
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
189
            nomail = True
1 by
This commit was manufactured by cvs2svn to create branch
190
            if args and args[0] in WHYCHOICES.keys():
191
                why = args.pop(0)
192
        elif opt.startswith('--nomail'):
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
193
            nomail = True
1 by
This commit was manufactured by cvs2svn to create branch
194
            i = opt.find('=')
195
            if i >= 0:
196
                why = opt[i+1:]
197
                if why not in WHYCHOICES.keys():
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
198
                    usage(1, C_('Bad --nomail option: %(why)s'))
1 by
This commit was manufactured by cvs2svn to create branch
199
        elif opt == '-d':
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
200
            digest = True
1 by
This commit was manufactured by cvs2svn to create branch
201
            if args and args[0] in ('mime', 'plain'):
202
                kind = args.pop(0)
203
        elif opt.startswith('--digest'):
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
204
            digest = True
1 by
This commit was manufactured by cvs2svn to create branch
205
            i = opt.find('=')
206
            if i >= 0:
207
                kind = opt[i+1:]
208
                if kind not in ('mime', 'plain'):
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
209
                    usage(1, C_('Bad --digest option: %(kind)s'))
1594 by Mark Sapiro
Added options to display (non)moderated members to list_members.
210
        elif opt in ('-m', '--moderated'):
211
            moderatedonly = True
212
            if nonmoderatedonly or invalidonly or unicodeonly:
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
213
                usage(1, C_('Only one of -m, -M, -i or -u may be specified.'))
1594 by Mark Sapiro
Added options to display (non)moderated members to list_members.
214
        elif opt in ('-M', '--non-moderated'):
215
            nonmoderatedonly = True
216
            if moderatedonly or invalidonly or unicodeonly:
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
217
                usage(1, C_('Only one of -m, -M, -i or -u may be specified.'))
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
218
        elif opt in ('-i', '--invalid'):
219
            invalidonly = True
1594 by Mark Sapiro
Added options to display (non)moderated members to list_members.
220
            if moderatedonly or nonmoderatedonly or unicodeonly:
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
221
                usage(1, C_('Only one of -m, -M, -i or -u may be specified.'))
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
222
        elif opt in ('-u', '--unicode'):
223
            unicodeonly = True
1594 by Mark Sapiro
Added options to display (non)moderated members to list_members.
224
            if moderatedonly or nonmoderatedonly or invalidonly:
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
225
                usage(1, C_('Only one of -m, -M, -i or -u may be specified.'))
1 by
This commit was manufactured by cvs2svn to create branch
226
        else:
227
            # No more options left, push the last one back on the list
228
            args.insert(0, opt)
229
            break
230
231
    if len(args) <> 1:
232
        usage(1)
233
234
    listname = args[0].lower().strip()
235
236
    if regular is None and digest is None:
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
237
        regular = digest = True
1 by
This commit was manufactured by cvs2svn to create branch
238
239
    if outfile:
240
        try:
241
            fp = open(outfile, 'w')
242
        except IOError:
1625 by Mark Sapiro
Fixed l10n to use correct charset for command-line scripts.
243
            print >> sys.stderr, C_(
244
                                 'Could not open file for writing:'), outfile
1 by
This commit was manufactured by cvs2svn to create branch
245
            sys.exit(1)
246
    else:
247
        fp = sys.stdout
248
249
    try:
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
250
        mlist = MailList.MailList(listname, lock=False)
1 by
This commit was manufactured by cvs2svn to create branch
251
    except Errors.MMListError, e:
1619.1.1 by Yasuhito FUTATSUKI at POEM
Importing locale patch for command line utils, from RHEL6 rpm source
252
        print >> sys.stderr, C_('No such list: %(listname)s')
1 by
This commit was manufactured by cvs2svn to create branch
253
        sys.exit(1)
254
255
    # Get the lowercased member addresses
256
    rmembers = mlist.getRegularMemberKeys()
257
    dmembers = mlist.getDigestMemberKeys()
258
259
    if preserve:
260
        # Convert to the case preserved addresses
261
        rmembers = mlist.getMemberCPAddresses(rmembers)
262
        dmembers = mlist.getMemberCPAddresses(dmembers)
263
1340.1.2 by Axel Beckert
Consistently use "non moderated" instead of "not moderated"
264
    if invalidonly or unicodeonly or moderatedonly or nonmoderatedonly:
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
265
        all = rmembers + dmembers
266
        all.sort()
267
        for addr in all:
268
            name = fullnames and mlist.getMemberName(addr) or ''
269
            showit = False
270
            if invalidonly and isinvalid(addr):
271
                showit = True
272
            if unicodeonly and isunicode(addr):
273
                showit = True
1340.1.1 by Axel Beckert
Add commandline options to list (non-) moderated list members
274
            if moderatedonly and mlist.getMemberOption(addr, mm_cfg.Moderate):
275
                showit = True
1594 by Mark Sapiro
Added options to display (non)moderated members to list_members.
276
            if nonmoderatedonly and not mlist.getMemberOption(addr,
277
                                                             mm_cfg.Moderate):
1340.1.1 by Axel Beckert
Add commandline options to list (non-) moderated list members
278
                showit = True
81 by bwarsaw
Backporting from the HEAD -- bin and cron scripts
279
            if showit:
280
                print >> fp, formataddr((safe(name), addr))
281
        return
1 by
This commit was manufactured by cvs2svn to create branch
282
    if regular:
283
        rmembers.sort()
284
        for addr in rmembers:
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
285
            name = fullnames and mlist.getMemberName(addr) or ''
1 by
This commit was manufactured by cvs2svn to create branch
286
            # Filter out nomails
287
            if nomail and not whymatches(mlist, addr, why):
288
                continue
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
289
            print >> fp, formataddr((safe(name), addr))
1 by
This commit was manufactured by cvs2svn to create branch
290
    if digest:
291
        dmembers.sort()
292
        for addr in dmembers:
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
293
            name = fullnames and mlist.getMemberName(addr) or ''
1 by
This commit was manufactured by cvs2svn to create branch
294
            # Filter out nomails
295
            if nomail and not whymatches(mlist, addr, why):
296
                continue
297
            # Filter out digest kinds
298
            if mlist.getMemberOption(addr, mm_cfg.DisableMime):
299
                # They're getting plain text digests
300
                if kind == 'mime':
301
                    continue
302
            else:
303
                # They're getting MIME digests
304
                if kind == 'plain':
305
                    continue
26 by bwarsaw
Backporting various fixes and improvements from the trunk.
306
            print >> fp, formataddr((safe(name), addr))
1 by
This commit was manufactured by cvs2svn to create branch
307
308
309

310
if __name__ == '__main__':
311
    main()