summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2009-08-16 22:44:01 -0400
committerBarry Warsaw2009-08-16 22:44:01 -0400
commitab198312517568387ecd474683821dda520ee9e0 (patch)
tree6e37829d518420dda3d421cc1fdc54a2620cb8c0
parent82affb2668ec6fa2d04fe7965a4c317eb13d8fce (diff)
downloadmailman-ab198312517568387ecd474683821dda520ee9e0.tar.gz
mailman-ab198312517568387ecd474683821dda520ee9e0.tar.zst
mailman-ab198312517568387ecd474683821dda520ee9e0.zip
-rw-r--r--src/mailman/app/membership.py2
-rw-r--r--src/mailman/commands/cli_members.py44
-rw-r--r--src/mailman/commands/docs/members.txt60
3 files changed, 105 insertions, 1 deletions
diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py
index 4022d5727..411083694 100644
--- a/src/mailman/app/membership.py
+++ b/src/mailman/app/membership.py
@@ -89,7 +89,7 @@ def add_member(mlist, address, realname, password, delivery_mode, language):
user = config.db.user_manager.create_user()
user.real_name = (realname if realname else address_obj.real_name)
user.link(address_obj)
- # Since created the user, then the member, and set preferences on the
+ # Since created the user, then the member, and set preferences on the
# appropriate object.
user.password = password
user.preferences.preferred_language = language
diff --git a/src/mailman/commands/cli_members.py b/src/mailman/commands/cli_members.py
index 9d9a892d5..7e22166ed 100644
--- a/src/mailman/commands/cli_members.py
+++ b/src/mailman/commands/cli_members.py
@@ -25,10 +25,17 @@ __all__ = [
]
+import sys
+import codecs
+
+from email.utils import parseaddr
from zope.interface import implements
+from mailman.app.membership import add_member
+from mailman.config import config
from mailman.i18n import _
from mailman.interfaces.command import ICLISubCommand
+from mailman.interfaces.member import DeliveryMode
@@ -41,6 +48,43 @@ class Members:
def add(self, parser, command_parser):
"""See `ICLISubCommand`."""
+ command_parser.add_argument(
+ '-a', '--add',
+ dest='filename',
+ help=_('Add all member addresses in FILENAME. FILENAME can be '
+ "'-' to indicate standard input."))
+ # Required positional argument.
+ command_parser.add_argument(
+ 'listname', metavar='LISTNAME', nargs=1,
+ help=_("""\
+ The 'fully qualified list name', i.e. the posting address of the
+ mailing list. It must be a valid email address and the domain
+ must be registered with Mailman. List names are forced to lower
+ case."""))
def process(self, args):
"""See `ICLISubCommand`."""
+ assert len(args.listname) == 1, (
+ 'Unexpected positional arguments: %s' % args.listname)
+ fqdn_listname = args.listname[0]
+ mlist = config.db.list_manager.get(fqdn_listname)
+ if mlist is None:
+ self.parser.error(_('No such list: $fqdn_listname'))
+ if args.filename == '-':
+ fp = sys.stdin
+ else:
+ fp = codecs.open(args.filename, 'r', 'utf-8')
+ try:
+ for line in fp:
+ real_name, email = parseaddr(line)
+ # If not given in the input data, parseaddr() will return the
+ # empty string, as opposed to the empty unicode. We need a
+ # unicode real name here.
+ if real_name == '':
+ real_name = u''
+ add_member(mlist, email, real_name, None,
+ DeliveryMode.regular, mlist.preferred_language.code)
+ finally:
+ if fp is not sys.stdin:
+ fp.close()
+ config.db.commit()
diff --git a/src/mailman/commands/docs/members.txt b/src/mailman/commands/docs/members.txt
new file mode 100644
index 000000000..c1374277a
--- /dev/null
+++ b/src/mailman/commands/docs/members.txt
@@ -0,0 +1,60 @@
+==============
+Adding members
+==============
+
+You can add members to a mailing list from the command line.
+
+ >>> from mailman.app.lifecycle import create_list
+ >>> mlist = create_list('test@example.com')
+
+ >>> class FakeArgs:
+ ... filename = None
+ ... listname = None
+ >>> args = FakeArgs()
+
+ >>> from mailman.commands.cli_members import Members
+ >>> command = Members()
+
+To do so, you need a file containing email addresses and full names that can
+be parsed by email.utils.parseaddr().
+
+ >>> addresses = [
+ ... ]
+
+ >>> import os
+ >>> path = os.path.join(config.VAR_DIR, 'addresses.txt')
+ >>> with open(path, 'w') as fp:
+ ... for address in ('aperson@example.com',
+ ... 'Bart Person <bperson@example.com>',
+ ... 'cperson@example.com (Cate Person)',
+ ... ):
+ ... print >> fp, address
+
+ >>> args.filename = path
+ >>> args.listname = [mlist.fqdn_listname]
+ >>> command.process(args)
+
+ >>> sorted(address.address for address in mlist.members.addresses)
+ [u'aperson@example.com', u'bperson@example.com', u'cperson@example.com']
+
+You can also specify '-' as the filename, in which case the addresses are
+taken from standard input.
+
+ >>> from StringIO import StringIO
+ >>> fp = StringIO()
+ >>> for address in ('dperson@example.com',
+ ... 'Elly Person <eperson@example.com>',
+ ... 'fperson@example.com (Fred Person)',
+ ... ):
+ ... print >> fp, address
+ >>> fp.seek(0)
+ >>> import sys
+ >>> sys.stdin = fp
+
+ >>> args.filename = '-'
+ >>> command.process(args)
+ >>> sys.stdin = sys.__stdin__
+
+ >>> sorted(address.address for address in mlist.members.addresses)
+ [u'aperson@example.com', u'bperson@example.com', u'cperson@example.com',
+ u'dperson@example.com', u'eperson@example.com', u'fperson@example.com']