summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xMailman/bin/add_members.py216
-rw-r--r--bin/Makefile.in7
-rwxr-xr-xbin/add_members255
-rwxr-xr-xconfigure11
-rw-r--r--configure.in3
5 files changed, 226 insertions, 266 deletions
diff --git a/Mailman/bin/add_members.py b/Mailman/bin/add_members.py
new file mode 100755
index 000000000..0adcda518
--- /dev/null
+++ b/Mailman/bin/add_members.py
@@ -0,0 +1,216 @@
+# Copyright (C) 1998-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+import os
+import sys
+import optparse
+
+from cStringIO import StringIO
+from email.Utils import parseaddr
+
+from Mailman import Errors
+from Mailman import MailList
+from Mailman import Message
+from Mailman import Utils
+from Mailman import i18n
+from Mailman import mm_cfg
+
+_ = i18n._
+__i18n_templates__ = True
+
+
+
+def parseargs():
+ parser = optparse.OptionParser(version=mm_cfg.MAILMAN_VERSION,
+ usage=_("""\
+%prog [options] listname
+
+Add members to a list. 'listname' is the name of the Mailman list you are
+adding members to; the list must already exist.
+
+You must supply at least one of -r and -d options. At most one of the
+files can be '-'.
+"""))
+ parser.add_option('-r', '--regular-members-file',
+ type='string', dest='regular', help=_("""\
+A file containing addresses of the members to be added, one address per line.
+This list of people become non-digest members. If file is '-', read addresses
+from stdin."""))
+ parser.add_option('-d', '--digest-members-file',
+ type='string', dest='digest', help=_("""\
+Similar to -r, but these people become digest members."""))
+ parser.add_option('-w', '--welcome-msg',
+ type='string', metavar='<y|n>', help=_("""\
+Set whether or not to send the list members a welcome message, overriding
+whatever the list's 'send_welcome_msg' setting is."""))
+ parser.add_option('-a', '--admin-notify',
+ type='string', metavar='<y|n>', help=_("""\
+Set whether or not to send the list administrators a notification on the
+success/failure of these subscriptions, overriding whatever the list's
+'admin_notify_mchanges' setting is."""))
+ opts, args = parser.parse_args()
+ if not args:
+ parser.print_help()
+ print >> sys.stderr, _('Missing listname')
+ sys.exit(1)
+ if len(args) > 1:
+ parser.print_help()
+ print >> sys.stderr, _('Unexpected arguments')
+ sys.exit(1)
+ if opts.welcome_msg is not None:
+ ch = opts.welcome_msg[0].lower()
+ if ch == 'y':
+ opts.welcome_msg = True
+ elif ch == 'n':
+ opts.welcome_msg = False
+ else:
+ parser.print_help()
+ print >> sys.stderr, _('Illegal value for -w: $opts.welcome_msg')
+ sys.exit(1)
+ if opts.admin_notify is not None:
+ ch = opts.admin_notify[0].lower()
+ if ch == 'y':
+ opts.admin_notify = True
+ elif ch == 'n':
+ opts.admin_notify = False
+ else:
+ parser.print_help()
+ print >> sys.stderr, _('Illegal value for -a: $opts.admin_notify')
+ sys.exit(1)
+ if opts.regular is None and opts.digest is None:
+ parser.print_help()
+ print >> sys.stderr, _('At least one of -r or -d is required')
+ sys.exit(1)
+ if opts.regular == '-' and opts.digest == '-':
+ parser.print_help()
+ print >> sys.stderr, _("-r and -d cannot both be '-'")
+ sys.exit(1)
+ return parser, opts, args
+
+
+
+def readfile(filename):
+ if filename == '-':
+ fp = sys.stdin
+ else:
+ fp = open(filename)
+ # Strip all the lines of whitespace and discard blank lines
+ try:
+ return [line.strip() for line in fp if line]
+ finally:
+ if fp is not sys.stdin:
+ fp.close()
+
+
+
+class Tee:
+ def __init__(self, outfp):
+ self._outfp = outfp
+
+ def write(self, msg):
+ sys.stdout.write(msg)
+ self._outfp.write(msg)
+
+
+class UserDesc:
+ pass
+
+
+
+def addall(mlist, members, digest, ack, outfp):
+ tee = Tee(outfp)
+ for member in members:
+ userdesc = UserDesc()
+ userdesc.fullname, userdesc.address = parseaddr(member)
+ userdesc.digest = digest
+
+ try:
+ mlist.ApprovedAddMember(userdesc, ack, 0)
+ except Errors.MMAlreadyAMember:
+ print >> tee, _('Already a member: $member')
+ except Errors.MMBadEmailError:
+ if userdesc.address == '':
+ print >> tee, _('Bad/Invalid email address: blank line')
+ else:
+ print >> tee, _('Bad/Invalid email address: $member')
+ except Errors.MMHostileAddress:
+ print >> tee, _('Hostile address (illegal characters): $member')
+ else:
+ print >> tee, _('Subscribed: $member')
+
+
+
+def main():
+ parser, opts, args = parseargs()
+
+ listname = args[0].lower().strip()
+ try:
+ mlist = MailList.MailList(listname)
+ except Errors.MMUnknownListError:
+ parser.print_help()
+ print >> sys.stderr, _('No such list: $listname')
+ sys.exit(1)
+
+ # Set up defaults
+ if opts.welcome_msg is None:
+ send_welcome_msg = mlist.send_welcome_msg
+ else:
+ send_welcome_msg = opts.welcome_msg
+ if opts.admin_notify is None:
+ admin_notify = mlist.admin_notify_mchanges
+ else:
+ admin_notify = opts.admin_notify
+
+ otrans = i18n.get_translation()
+ # Read the regular and digest member files
+ try:
+ if opts.digest:
+ dmembers = readfile(opts.digest)
+ else:
+ dmembers = []
+ if opts.regular:
+ nmembers = readfile(opts.regular)
+ else:
+ nmembers = []
+
+ if not dmembers and not nmembers:
+ print _('Nothing to do.')
+ sys.exit(0)
+
+ s = StringIO()
+ i18n.set_language(mlist.preferred_language)
+ if nmembers:
+ addall(mlist, nmembers, False, send_welcome_msg, s)
+
+ if dmembers:
+ addall(mlist, dmembers, True, send_welcome_msg, s)
+
+ if admin_notify:
+ subject = _('$mlist.real_name subscription notification')
+ msg = Message.UserNotification(
+ mlist.owner, Utils.get_site_email(), subject, s.getvalue(),
+ mlist.preferred_language)
+ msg.send(mlist)
+
+ mlist.Save()
+ finally:
+ mlist.Unlock()
+ i18n.set_translation(otrans)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 46ae3f09a..dbf6bc295 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -44,7 +44,7 @@ SCRIPTSDIR= $(prefix)/bin
SHELL= /bin/sh
-SCRIPTS= mmshell add_members \
+SCRIPTS= mmshell \
remove_members clone_member update \
sync_members check_db withlist check_perms find_member \
config_list dumpdb cleanarch \
@@ -53,8 +53,9 @@ SCRIPTS= mmshell add_members \
msgfmt.py discard \
reset_pw.py templ2pot.py po2templ.py
-LN_SCRIPTS= arch change_pw inject list_lists list_members list_owners \
- mmsitepass newlist rmlist show_qfiles unshunt version
+LN_SCRIPTS= add_members arch change_pw inject list_lists list_members \
+ list_owners mmsitepass newlist rmlist show_qfiles unshunt \
+ version
BUILDDIR= ../build/bin
diff --git a/bin/add_members b/bin/add_members
deleted file mode 100755
index fdc3f02b8..000000000
--- a/bin/add_members
+++ /dev/null
@@ -1,255 +0,0 @@
-#! @PYTHON@
-#
-# Copyright (C) 1998-2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# argv[1] should be the name of the list.
-# argv[2] should be the list of non-digested users.
-# argv[3] should be the list of digested users.
-
-# Make sure that the list of email addresses doesn't contain any comments,
-# like majordomo may throw in. For now, you just have to remove them manually.
-
-"""Add members to a list from the command line.
-
-Usage:
- add_members [options] listname
-
-Options:
-
- --regular-members-file=file
- -r file
- A file containing addresses of the members to be added, one
- address per line. This list of people become non-digest
- members. If file is `-', read addresses from stdin. Note that
- -n/--non-digest-members-file are deprecated synonyms for this option.
-
- --digest-members-file=file
- -d file
- Similar to above, but these people become digest members.
-
- --welcome-msg=<y|n>
- -w <y|n>
- Set whether or not to send the list members a welcome message,
- overriding whatever the list's `send_welcome_msg' setting is.
-
- --admin-notify=<y|n>
- -a <y|n>
- Set whether or not to send the list administrators a notification on
- the success/failure of these subscriptions, overriding whatever the
- list's `admin_notify_mchanges' setting is.
-
- --help
- -h
- Print this help message and exit.
-
- listname
- The name of the Mailman list you are adding members to. It must
- already exist.
-
-You must supply at least one of -r and -d options. At most one of the
-files can be `-'.
-"""
-
-import sys
-import os
-import getopt
-from cStringIO import StringIO
-
-import paths
-# Import this /after/ paths so that the sys.path is properly hacked
-from email.Utils import parseaddr
-
-from Mailman import MailList
-from Mailman import Utils
-from Mailman import Message
-from Mailman import Errors
-from Mailman import mm_cfg
-from Mailman import i18n
-
-_ = i18n._
-
-
-
-def usage(status, msg=''):
- if status:
- fd = sys.stderr
- else:
- fd = sys.stdout
- print >> fd, _(__doc__)
- if msg:
- print >> fd, msg
- sys.exit(status)
-
-
-
-def readfile(filename):
- if filename == '-':
- fp = sys.stdin
- closep = 0
- else:
- fp = open(filename)
- closep = 1
- # strip all the lines of whitespace and discard blank lines
- lines = filter(None, [line.strip() for line in fp.readlines()])
- if closep:
- fp.close()
- return lines
-
-
-
-class Tee:
- def __init__(self, outfp):
- self.__outfp = outfp
-
- def write(self, msg):
- sys.stdout.write(msg)
- self.__outfp.write(msg)
-
-
-class UserDesc: pass
-
-
-
-def addall(mlist, members, digest, ack, outfp):
- tee = Tee(outfp)
- for member in members:
- userdesc = UserDesc()
- userdesc.fullname, userdesc.address = parseaddr(member)
- userdesc.digest = digest
-
- try:
- mlist.ApprovedAddMember(userdesc, ack, 0)
- except Errors.MMAlreadyAMember:
- print >> tee, _('Already a member: %(member)s')
- except Errors.MMBadEmailError:
- if userdesc.address == '':
- print >> tee, _('Bad/Invalid email address: blank line')
- else:
- print >> tee, _('Bad/Invalid email address: %(member)s')
- except Errors.MMHostileAddress:
- print >> tee, _('Hostile address (illegal characters): %(member)s')
- else:
- print >> tee, _('Subscribed: %(member)s')
-
-
-
-def main():
- try:
- opts, args = getopt.getopt(sys.argv[1:],
- 'a:n:r:d:w:h',
- ['admin-notify=',
- 'regular-members-file=',
- 'non-digest-members-file=',
- 'digest-members-file=',
- 'welcome-msg=',
- 'help'])
- except getopt.error, msg:
- usage(1, msg)
-
- if len(args) <> 1:
- usage(1)
-
- listname = args[0].lower().strip()
- nfile = None
- dfile = None
- send_welcome_msg = None
- admin_notif = None
- for opt, arg in opts:
- if opt in ('-h', '--help'):
- usage(0)
- elif opt in ('-d', '--digest-members-file'):
- dfile = arg
- # Deprecate -/--non-digest-members-file or consistency with
- # list_members
- elif opt in ('-r', '--regular-members-file'):
- nfile = arg
- elif opt in ('-n', '--non-digest-members-file'):
- nfile = arg
- # I don't think we need to use the warnings module here.
- print >> sys.stderr, 'option', opt, \
- 'is deprecated, use -r/--regular-members-file'
- elif opt in ('-w', '--welcome-msg'):
- if arg.lower()[0] == 'y':
- send_welcome_msg = 1
- elif arg.lower()[0] == 'n':
- send_welcome_msg = 0
- else:
- usage(1, _('Bad argument to -w/--welcome-msg: %(arg)s'))
- elif opt in ('-a', '--admin-notify'):
- if arg.lower()[0] == 'y':
- admin_notif = 1
- elif arg.lower()[0] == 'n':
- admin_notif = 0
- else:
- usage(1, _('Bad argument to -a/--admin-notify: %(arg)s'))
-
- if dfile is None and nfile is None:
- usage(1)
-
- if dfile == "-" and nfile == "-":
- usage(1, _('Cannot read both digest and normal members '
- 'from standard input.'))
-
- try:
- mlist = MailList.MailList(listname)
- except Errors.MMUnknownListError:
- usage(1, _('No such list: %(listname)s'))
-
- # Set up defaults
- if send_welcome_msg is None:
- send_welcome_msg = mlist.send_welcome_msg
- if admin_notif is None:
- admin_notif = mlist.admin_notify_mchanges
-
- otrans = i18n.get_translation()
- # Read the regular and digest member files
- try:
- dmembers = []
- if dfile:
- dmembers = readfile(dfile)
-
- nmembers = []
- if nfile:
- nmembers = readfile(nfile)
-
- if not dmembers and not nmembers:
- usage(0, _('Nothing to do.'))
-
- s = StringIO()
- i18n.set_language(mlist.preferred_language)
- if nmembers:
- addall(mlist, nmembers, 0, send_welcome_msg, s)
-
- if dmembers:
- addall(mlist, dmembers, 1, send_welcome_msg, s)
-
- if admin_notif:
- realname = mlist.real_name
- subject = _('%(realname)s subscription notification')
- msg = Message.UserNotification(
- mlist.owner, Utils.get_site_email(), subject, s.getvalue(),
- mlist.preferred_language)
- msg.send(mlist)
-
- mlist.Save()
- finally:
- mlist.Unlock()
- i18n.set_translation(otrans)
-
-
-if __name__ == '__main__':
- main()
diff --git a/configure b/configure
index 9cb07d227..208a971a1 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 7890 .
+# From configure.in Revision: 7891 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
@@ -721,13 +721,13 @@ echo X"$0" |
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
+ if test ! -r "$srcdir/$ac_unique_file"; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
-if test ! -r $srcdir/$ac_unique_file; then
+if test ! -r "$srcdir/$ac_unique_file"; then
if test "$ac_srcdir_defaulted" = yes; then
{ echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
{ (exit 1); exit 1; }; }
@@ -736,7 +736,7 @@ if test ! -r $srcdir/$ac_unique_file; then
{ (exit 1); exit 1; }; }
fi
fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+(cd $srcdir && test -r "./$ac_unique_file") 2>/dev/null ||
{ echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
{ (exit 1); exit 1; }; }
srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
@@ -4276,8 +4276,7 @@ done
-SCRIPTS="build/bin/add_members:bin/add_members \
-build/bin/check_db:bin/check_db \
+SCRIPTS="build/bin/check_db:bin/check_db \
build/bin/check_perms:bin/check_perms \
build/bin/cleanarch:bin/cleanarch \
build/bin/clone_member:bin/clone_member \
diff --git a/configure.in b/configure.in
index 68b33ffb9..78cc5e0a6 100644
--- a/configure.in
+++ b/configure.in
@@ -15,7 +15,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
dnl Process this file with autoconf to produce a configure script.
-AC_REVISION($Revision: 7891 $)
+AC_REVISION($Revision: 7892 $)
AC_PREREQ(2.0)
AC_INIT(src/common.h)
@@ -594,7 +594,6 @@ AC_CHECK_FUNCS(vsnprintf)
dnl Expand PYTHON path in the scripts, output into build/scriptname
AC_DEFUN(MM_SCRIPTS, [dnl
-bin/add_members \
bin/check_db \
bin/check_perms \
bin/cleanarch \