Prepare for 3.2.1rc1 release.
[mailman.git] / port_me / find_member.py
blob0ec440c81e6c619c3f3b10566ba02527a5b0af60
1 # Copyright (C) 1998-2019 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
8 # any later version.
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 import re
19 import sys
20 import optparse
22 from mailman import errors
23 from mailman import MailList
24 from mailman.configuration import config
25 from mailman.core.i18n import _
26 from mailman.version import MAILMAN_VERSION
29 AS_MEMBER = 0x01
30 AS_OWNER = 0x02
34 def parseargs():
35 parser = optparse.OptionParser(version=MAILMAN_VERSION,
36 usage=_("""\
37 %prog [options] regex [regex ...]
39 Find all lists that a member's address is on.
41 The interaction between -l and -x (see below) is as follows. If any -l option
42 is given then only the named list will be included in the search. If any -x
43 option is given but no -l option is given, then all lists will be search
44 except those specifically excluded.
46 Regular expression syntax uses the Python 're' module. Complete
47 specifications are at:
49 http://www.python.org/doc/current/lib/module-re.html
51 Address matches are case-insensitive, but case-preserved addresses are
52 displayed."""))
53 parser.add_option('-l', '--listname',
54 type='string', default=[], action='append',
55 dest='listnames',
56 help=_('Include only the named list in the search'))
57 parser.add_option('-x', '--exclude',
58 type='string', default=[], action='append',
59 dest='excludes',
60 help=_('Exclude the named list from the search'))
61 parser.add_option('-w', '--owners',
62 default=False, action='store_true',
63 help=_('Search list owners as well as members'))
64 parser.add_option('-C', '--config',
65 help=_('Alternative configuration file to use'))
66 opts, args = parser.parse_args()
67 if not args:
68 parser.print_help()
69 print >> sys.stderr, _('Search regular expression required')
70 sys.exit(1)
71 return parser, opts, args
75 def main():
76 parser, opts, args = parseargs()
77 config.load(opts.config)
79 listnames = opts.listnames or config.list_manager.names
80 includes = set(listname.lower() for listname in listnames)
81 excludes = set(listname.lower() for listname in opts.excludes)
82 listnames = includes - excludes
84 if not listnames:
85 print _('No lists to search')
86 return
88 cres = []
89 for r in args:
90 cres.append(re.compile(r, re.IGNORECASE))
91 # dictionary of {address, (listname, ownerp)}
92 matches = {}
93 for listname in listnames:
94 try:
95 mlist = MailList.MailList(listname, lock=False)
96 except errors.MMListError:
97 print _('No such list: $listname')
98 continue
99 if opts.owners:
100 owners = mlist.owner
101 else:
102 owners = []
103 for cre in cres:
104 for member in mlist.getMembers():
105 if cre.search(member):
106 addr = mlist.getMemberCPAddress(member)
107 entries = matches.get(addr, {})
108 aswhat = entries.get(listname, 0)
109 aswhat |= AS_MEMBER
110 entries[listname] = aswhat
111 matches[addr] = entries
112 for owner in owners:
113 if cre.search(owner):
114 entries = matches.get(owner, {})
115 aswhat = entries.get(listname, 0)
116 aswhat |= AS_OWNER
117 entries[listname] = aswhat
118 matches[owner] = entries
119 addrs = matches.keys()
120 addrs.sort()
121 for k in addrs:
122 hits = matches[k]
123 lists = hits.keys()
124 print k, _('found in:')
125 for name in lists:
126 aswhat = hits[name]
127 if aswhat & AS_MEMBER:
128 print ' ', name
129 if aswhat & AS_OWNER:
130 print ' ', name, _('(as owner)')
134 if __name__ == '__main__':
135 main()