aboutsummaryrefslogtreecommitdiffstats
path: root/bin/find_member
diff options
context:
space:
mode:
Diffstat (limited to 'bin/find_member')
-rwxr-xr-xbin/find_member184
1 files changed, 184 insertions, 0 deletions
diff --git a/bin/find_member b/bin/find_member
new file mode 100755
index 00000000..0656d500
--- /dev/null
+++ b/bin/find_member
@@ -0,0 +1,184 @@
+#! @PYTHON@
+#
+# Copyright (C) 1998,1999,2000,2001,2002 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.
+
+"""Find all lists that a member's address is on.
+
+Usage:
+ find_member [options] regex [regex [...]]
+
+Where:
+ --listname=listname
+ -l listname
+ Include only the named list in the search.
+
+ --exclude=listname
+ -x listname
+ Exclude the named list from the search.
+
+ --owners
+ -w
+ Search list owners as well as members.
+
+ --help
+ -h
+ Print this help message and exit.
+
+ regex
+ A Python regular expression to match against.
+
+The interaction between -l and -x is as follows. If any -l option is given
+then only the named list will be included in the search. If any -x option is
+given but no -l option is given, then all lists will be search except those
+specifically excluded.
+
+Regular expression syntax is Perl5-like, using the Python re module. Complete
+specifications are at:
+
+http://www.python.org/doc/current/lib/module-re.html
+
+Address matches are case-insensitive, but case-preserved addresses are
+displayed.
+
+"""
+
+import sys
+import re
+import getopt
+
+import paths
+from Mailman import Utils
+from Mailman import MailList
+from Mailman import Errors
+from Mailman.i18n import _
+
+AS_MEMBER = 0x01
+AS_OWNER = 0x02
+
+
+
+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 scanlists(options):
+ cres = []
+ for r in options.regexps:
+ cres.append(re.compile(r, re.IGNORECASE))
+ #
+ # dictionary of {address, (listname, ownerp)}
+ matches = {}
+ for listname in options.listnames:
+ try:
+ mlist = MailList.MailList(listname, lock=0)
+ except Errors.MMListError:
+ print _('No such list: %(listname)s')
+ continue
+ if options.owners:
+ owners = mlist.owner
+ else:
+ owners = []
+ for cre in cres:
+ for member in mlist.getMembers():
+ if cre.search(member):
+ addr = mlist.getMemberCPAddress(member)
+ entries = matches.get(addr, {})
+ aswhat = entries.get(listname, 0)
+ aswhat |= AS_MEMBER
+ entries[listname] = aswhat
+ matches[addr] = entries
+ for owner in owners:
+ if cre.search(owner):
+ entries = matches.get(addr, {})
+ aswhat = entries.get(listname, 0)
+ aswhat |= AS_OWNER
+ entries[listname] = aswhat
+ matches[addr] = entries
+ return matches
+
+
+
+class Options:
+ listnames = Utils.list_names()
+ owners = None
+
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'l:x:wh',
+ ['listname=', 'exclude=', 'owners',
+ 'help'])
+ except getopt.error, msg:
+ usage(1, msg)
+
+ options = Options()
+ loptseen = 0
+ excludes = []
+ for opt, arg in opts:
+ if opt in ('-h', '--help'):
+ usage(0)
+ elif opt in ('-l', '--listname'):
+ if not loptseen:
+ options.listnames = []
+ loptseen = 1
+ options.listnames.append(arg.lower())
+ elif opt in ('-x', '--exclude'):
+ excludes.append(arg.lower())
+ elif opt in ('-w', '--owners'):
+ options.owners = 1
+
+ for ex in excludes:
+ try:
+ options.listnames.remove(ex)
+ except ValueError:
+ pass
+
+ if not args:
+ usage(1, _('Search regular expression required'))
+
+ options.regexps = args
+
+ if not options.listnames:
+ print _('No lists to search')
+ return
+
+ matches = scanlists(options)
+ addrs = matches.keys()
+ addrs.sort()
+ for k in addrs:
+ hits = matches[k]
+ lists = hits.keys()
+ print k, _('found in:')
+ for name in lists:
+ aswhat = hits[name]
+ if aswhat & AS_MEMBER:
+ print ' ', name
+ if aswhat & AS_OWNER:
+ print ' ', name, _('(as owner)')
+
+
+
+if __name__ == '__main__':
+ main()