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() |