aboutsummaryrefslogtreecommitdiffstats
path: root/Mailman/Commands
diff options
context:
space:
mode:
author <>2003-01-02 05:25:50 +0000
committer <>2003-01-02 05:25:50 +0000
commitb132a73f15e432eaf43310fce9196ca0c0651465 (patch)
treec15f816ba7c4de99fef510e3bd75af0890d47441 /Mailman/Commands
downloadmailman2-b132a73f15e432eaf43310fce9196ca0c0651465.tar.gz
mailman2-b132a73f15e432eaf43310fce9196ca0c0651465.tar.xz
mailman2-b132a73f15e432eaf43310fce9196ca0c0651465.zip
This commit was manufactured by cvs2svn to create branch
'Release_2_1-maint'.
Diffstat (limited to 'Mailman/Commands')
-rw-r--r--Mailman/Commands/.cvsignore1
-rw-r--r--Mailman/Commands/Makefile.in69
-rw-r--r--Mailman/Commands/__init__.py15
-rw-r--r--Mailman/Commands/cmd_confirm.py84
-rw-r--r--Mailman/Commands/cmd_echo.py26
-rw-r--r--Mailman/Commands/cmd_end.py33
-rw-r--r--Mailman/Commands/cmd_help.py92
-rw-r--r--Mailman/Commands/cmd_info.py49
-rw-r--r--Mailman/Commands/cmd_join.py20
-rw-r--r--Mailman/Commands/cmd_leave.py20
-rw-r--r--Mailman/Commands/cmd_lists.py69
-rw-r--r--Mailman/Commands/cmd_password.py118
-rw-r--r--Mailman/Commands/cmd_remove.py20
-rw-r--r--Mailman/Commands/cmd_set.py353
-rw-r--r--Mailman/Commands/cmd_stop.py20
-rw-r--r--Mailman/Commands/cmd_subscribe.py136
-rw-r--r--Mailman/Commands/cmd_unsubscribe.py87
-rw-r--r--Mailman/Commands/cmd_who.py133
18 files changed, 1345 insertions, 0 deletions
diff --git a/Mailman/Commands/.cvsignore b/Mailman/Commands/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/Mailman/Commands/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/Mailman/Commands/Makefile.in b/Mailman/Commands/Makefile.in
new file mode 100644
index 00000000..bacd9629
--- /dev/null
+++ b/Mailman/Commands/Makefile.in
@@ -0,0 +1,69 @@
+# Copyright (C) 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.
+
+# NOTE: Makefile.in is converted into Makefile by the configure script
+# in the parent directory. Once configure has run, you can recreate
+# the Makefile by running just config.status.
+
+# Variables set by configure
+
+VPATH= @srcdir@
+srcdir= @srcdir@
+bindir= @bindir@
+prefix= @prefix@
+exec_prefix= @exec_prefix@
+
+CC= @CC@
+CHMOD= @CHMOD@
+INSTALL= @INSTALL@
+
+DEFS= @DEFS@
+
+# Customizable but not set by configure
+
+OPT= @OPT@
+CFLAGS= $(OPT) $(DEFS)
+PACKAGEDIR= $(prefix)/Mailman/Commands
+SHELL= /bin/sh
+
+MODULES= *.py
+
+# Modes for directories and executables created by the install
+# process. Default to group-writable directories but
+# user-only-writable for executables.
+DIRMODE= 775
+EXEMODE= 755
+FILEMODE= 644
+INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
+
+
+# Rules
+
+all:
+
+install:
+ for f in $(MODULES); \
+ do \
+ $(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(PACKAGEDIR); \
+ done
+
+finish:
+
+clean:
+
+distclean:
+ -rm *.pyc
+ -rm Makefile
diff --git a/Mailman/Commands/__init__.py b/Mailman/Commands/__init__.py
new file mode 100644
index 00000000..ac6d2391
--- /dev/null
+++ b/Mailman/Commands/__init__.py
@@ -0,0 +1,15 @@
+# Copyright (C) 2001 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.
diff --git a/Mailman/Commands/cmd_confirm.py b/Mailman/Commands/cmd_confirm.py
new file mode 100644
index 00000000..5e4fc701
--- /dev/null
+++ b/Mailman/Commands/cmd_confirm.py
@@ -0,0 +1,84 @@
+# Copyright (C) 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.
+
+"""
+ confirm <confirmation-string>
+ Confirm an action. The confirmation-string is required and should be
+ supplied with in mailback confirmation notice.
+"""
+
+from Mailman import mm_cfg
+from Mailman import Errors
+from Mailman import Pending
+from Mailman.i18n import _
+
+STOP = 1
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ res.results.append(_('Usage:'))
+ res.results.append(gethelp(mlist))
+ return STOP
+ cookie = args[0]
+ try:
+ results = mlist.ProcessConfirmation(cookie, res.msg)
+ except Errors.MMBadConfirmation, e:
+ # Express in approximate days
+ days = int(mm_cfg.PENDING_REQUEST_LIFE / mm_cfg.days(1) + 0.5)
+ res.results.append(_("""\
+Invalid confirmation string. Note that confirmation strings expire
+approximately %(days)s days after the initial subscription request. If your
+confirmation has expired, please try to re-submit your original request or
+message."""))
+ except Errors.MMNeedApproval:
+ res.results.append(_("""\
+Your request has been forwarded to the list moderator for approval."""))
+ except Errors.MMAlreadyAMember:
+ # Some other subscription request for this address has
+ # already succeeded.
+ res.results.append(_('You are already subscribed.'))
+ except Errors.NotAMemberError:
+ # They've already been unsubscribed
+ res.results.append(_("""\
+You are not current a member. Have you already unsubscribed or changed
+your email address?"""))
+ else:
+ if ((results[0] == Pending.SUBSCRIPTION and mlist.send_welcome_msg)
+ or
+ (results[0] == Pending.UNSUBSCRIPTION and mlist.send_goodbye_msg)):
+ # We don't also need to send a confirmation succeeded message
+ res.respond = 0
+ else:
+ res.results.append(_('Confirmation succeeded'))
+ # Consume any other confirmation strings with the same cookie so
+ # the user doesn't get a misleading "unprocessed" message.
+ match = 'confirm ' + cookie
+ unprocessed = []
+ for line in res.commands:
+ if line.lstrip() == match:
+ continue
+ unprocessed.append(line)
+ res.commands = unprocessed
+ # Process just one confirmation string per message
+ return STOP
diff --git a/Mailman/Commands/cmd_echo.py b/Mailman/Commands/cmd_echo.py
new file mode 100644
index 00000000..1f8b5979
--- /dev/null
+++ b/Mailman/Commands/cmd_echo.py
@@ -0,0 +1,26 @@
+# Copyright (C) 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.
+
+"""
+ echo [args]
+ Simply echo an acknowledgement. Args are echoed back unchanged.
+"""
+
+SPACE = ' '
+
+def process(res, args):
+ res.results.append('echo %s' % SPACE.join(args))
+ return 1
diff --git a/Mailman/Commands/cmd_end.py b/Mailman/Commands/cmd_end.py
new file mode 100644
index 00000000..aeec7936
--- /dev/null
+++ b/Mailman/Commands/cmd_end.py
@@ -0,0 +1,33 @@
+# Copyright (C) 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.
+
+"""
+ end
+ Stop processing commands. Use this if your mail program automatically
+ adds a signature file.
+"""
+
+from Mailman.i18n import _
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ return 1 # STOP
diff --git a/Mailman/Commands/cmd_help.py b/Mailman/Commands/cmd_help.py
new file mode 100644
index 00000000..e2d865e8
--- /dev/null
+++ b/Mailman/Commands/cmd_help.py
@@ -0,0 +1,92 @@
+# Copyright (C) 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.
+
+"""
+ help
+ Print this help message.
+"""
+
+import sys
+import os
+
+from Mailman import mm_cfg
+from Mailman import Utils
+from Mailman.i18n import _
+
+EMPTYSTRING = ''
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ # Get the help text introduction
+ mlist = res.mlist
+ # Since this message is personalized, add some useful information if the
+ # address requesting help is a member of the list.
+ msg = res.msg
+ for sender in msg.get_senders():
+ if mlist.isMember(sender):
+ memberurl = mlist.GetOptionsURL(sender, absolute=1)
+ urlhelp = _(
+ 'You can access your personal options via the following url:')
+ res.results.append(urlhelp)
+ res.results.append(memberurl)
+ # Get a blank line in the output.
+ res.results.append('')
+ break
+ # build the specific command helps from the module docstrings
+ modhelps = {}
+ import Mailman.Commands
+ path = os.path.dirname(os.path.abspath(Mailman.Commands.__file__))
+ for file in os.listdir(path):
+ if not file.startswith('cmd_') or not file.endswith('.py'):
+ continue
+ module = os.path.splitext(file)[0]
+ modname = 'Mailman.Commands.' + module
+ try:
+ __import__(modname)
+ except ImportError:
+ continue
+ cmdname = module[4:]
+ help = None
+ if hasattr(sys.modules[modname], 'gethelp'):
+ help = sys.modules[modname].gethelp(mlist)
+ if help:
+ modhelps[cmdname] = help
+ # Now sort the command helps
+ helptext = []
+ keys = modhelps.keys()
+ keys.sort()
+ for cmd in keys:
+ helptext.append(modhelps[cmd])
+ commands = EMPTYSTRING.join(helptext)
+ # Now craft the response
+ helptext = Utils.maketext(
+ 'help.txt',
+ {'listname' : mlist.real_name,
+ 'version' : mm_cfg.VERSION,
+ 'listinfo_url': mlist.GetScriptURL('listinfo', absolute=1),
+ 'requestaddr' : mlist.GetRequestEmail(),
+ 'adminaddr' : mlist.GetOwnerEmail(),
+ 'commands' : commands,
+ }, mlist=mlist, lang=res.msgdata['lang'], raw=1)
+ # Now add to the response
+ res.results.append('help')
+ res.results.append(helptext)
diff --git a/Mailman/Commands/cmd_info.py b/Mailman/Commands/cmd_info.py
new file mode 100644
index 00000000..1c28da70
--- /dev/null
+++ b/Mailman/Commands/cmd_info.py
@@ -0,0 +1,49 @@
+# Copyright (C) 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.
+
+"""
+ info
+ Get information about this mailing list.
+"""
+
+from Mailman.i18n import _
+
+STOP = 1
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ mlist = res.mlist
+ if args:
+ res.results.append(gethelp(mlist))
+ return STOP
+ listname = mlist.real_name
+ description = mlist.description or _('n/a')
+ postaddr = mlist.GetListEmail()
+ requestaddr = mlist.GetRequestEmail()
+ owneraddr = mlist.GetOwnerEmail()
+ listurl = mlist.GetScriptURL('listinfo', absolute=1)
+ res.results.append(_('List name: %(listname)s'))
+ res.results.append(_('Description: %(description)s'))
+ res.results.append(_('Postings to: %(postaddr)s'))
+ res.results.append(_('List Helpbot: %(requestaddr)s'))
+ res.results.append(_('List Owners: %(owneraddr)s'))
+ res.results.append(_('More information: %(listurl)s'))
diff --git a/Mailman/Commands/cmd_join.py b/Mailman/Commands/cmd_join.py
new file mode 100644
index 00000000..4daccc1a
--- /dev/null
+++ b/Mailman/Commands/cmd_join.py
@@ -0,0 +1,20 @@
+# Copyright (C) 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.
+
+"""The `join' command is synonymous with `subscribe'.
+"""
+
+from Mailman.Commands.cmd_subscribe import process
diff --git a/Mailman/Commands/cmd_leave.py b/Mailman/Commands/cmd_leave.py
new file mode 100644
index 00000000..ed5ccc7b
--- /dev/null
+++ b/Mailman/Commands/cmd_leave.py
@@ -0,0 +1,20 @@
+# Copyright (C) 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.
+
+"""The `leave' command is synonymous with `unsubscribe'.
+"""
+
+from Mailman.Commands.cmd_unsubscribe import process
diff --git a/Mailman/Commands/cmd_lists.py b/Mailman/Commands/cmd_lists.py
new file mode 100644
index 00000000..81b60e60
--- /dev/null
+++ b/Mailman/Commands/cmd_lists.py
@@ -0,0 +1,69 @@
+# Copyright (C) 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.
+
+"""
+ lists
+ See a list of the public mailing lists on this GNU Mailman server.
+"""
+
+from Mailman import mm_cfg
+from Mailman import Utils
+from Mailman.MailList import MailList
+from Mailman.i18n import _
+
+
+STOP = 1
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ mlist = res.mlist
+ if args:
+ res.results.append(_('Usage:'))
+ res.results.append(gethelp(mlist))
+ return STOP
+ hostname = mlist.host_name
+ res.results.append(_('Public mailing lists at %(hostname)s:'))
+ lists = Utils.list_names()
+ lists.sort()
+ i = 1
+ for listname in lists:
+ if listname == mlist.internal_name():
+ xlist = mlist
+ else:
+ xlist = MailList(listname, lock=0)
+ # We can mention this list if you already know about it
+ if not xlist.advertised and xlist is not mlist:
+ continue
+ # Skip the list if it isn't in the same virtual domain. BAW: should a
+ # message to the site list include everything regardless of domain?
+ if mm_cfg.VIRTUAL_HOST_OVERVIEW and \
+ xlist.host_name <> mlist.host_name:
+ continue
+ realname = xlist.real_name
+ description = xlist.description or _('n/a')
+ requestaddr = xlist.GetRequestEmail()
+ if i > 1:
+ res.results.append('')
+ res.results.append(_('%(i)3d. List name: %(realname)s'))
+ res.results.append(_(' Description: %(description)s'))
+ res.results.append(_(' Requests to: %(requestaddr)s'))
+ i += 1
diff --git a/Mailman/Commands/cmd_password.py b/Mailman/Commands/cmd_password.py
new file mode 100644
index 00000000..c2347be9
--- /dev/null
+++ b/Mailman/Commands/cmd_password.py
@@ -0,0 +1,118 @@
+# Copyright (C) 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.
+
+"""
+ password [<oldpassword> <newpassword>] [address=<address>]
+ Retrieve or change your password. With no arguments, this returns
+ your current password. With arguments <oldpassword> and <newpassword>
+ you can change your password.
+
+ If you're posting from an address other than your membership address,
+ specify your membership address with `address=<address>' (no brackets
+ around the email address, and no quotes!). Note that in this case the
+ response is always sent to the subscribed address.
+"""
+
+from email.Utils import parseaddr
+
+from Mailman import mm_cfg
+from Mailman.i18n import _
+
+STOP = 1
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ mlist = res.mlist
+ address = None
+ if not args:
+ # They just want to get their existing password
+ realname, address = parseaddr(res.msg['from'])
+ if mlist.isMember(address):
+ password = mlist.getMemberPassword(address)
+ res.results.append(_('Your password is: %(password)s'))
+ else:
+ listname = mlist.real_name
+ res.results.append(
+ _('You are not a member of the %(listname)s mailing list'))
+ return STOP
+ elif len(args) == 1 and args[0].startswith('address='):
+ # They want their password, but they're posting from a different
+ # address. We /must/ return the password to the subscribed address.
+ address = args[0][8:]
+ res.returnaddr = address
+ if mlist.isMember(address):
+ password = mlist.getMemberPassword(address)
+ res.results.append(_('Your password is: %(password)s'))
+ else:
+ listname = mlist.real_name
+ res.results.append(
+ _('You are not a member of the %(listname)s mailing list'))
+ return STOP
+ elif len(args) == 2:
+ # They are changing their password
+ oldpasswd = args[0]
+ newpasswd = args[1]
+ realname, address = parseaddr(res.msg['from'])
+ if mlist.isMember(address):
+ if mlist.Authenticate((mm_cfg.AuthUser, mm_cfg.AuthListAdmin),
+ oldpasswd, address):
+ mlist.setMemberPassword(address, newpasswd)
+ res.results.append(_('Password successfully changed.'))
+ else:
+ res.results.append(_("""\
+You did not give the correct old password, so your password has not been
+changed. Use the no argument version of the password command to retrieve your
+current password, then try again."""))
+ res.results.append(_('\nUsage:'))
+ res.results.append(gethelp(mlist))
+ return STOP
+ else:
+ listname = mlist.real_name
+ res.results.append(
+ _('You are not a member of the %(listname)s mailing list'))
+ return STOP
+ elif len(args) == 3 and args[2].startswith('address='):
+ # They want to change their password, and they're sending this from a
+ # different address than what they're subscribed with. Be sure the
+ # response goes to the subscribed address.
+ oldpasswd = args[0]
+ newpasswd = args[1]
+ address = args[2][8:]
+ res.returnaddr = address
+ if mlist.isMember(address):
+ if mlist.Authenticate((mm_cfg.AuthUser, mm_cfg.AuthListAdmin),
+ oldpasswd, address):
+ mlist.setMemberPassword(address, newpasswd)
+ res.results.append(_('Password successfully changed.'))
+ else:
+ res.results.append(_("""\
+You did not give the correct old password, so your password has not been
+changed. Use the no argument version of the password command to retrieve your
+current password, then try again."""))
+ res.results.append(_('\nUsage:'))
+ res.results.append(gethelp(mlist))
+ return STOP
+ else:
+ listname = mlist.real_name
+ res.results.append(
+ _('You are not a member of the %(listname)s mailing list'))
+ return STOP
diff --git a/Mailman/Commands/cmd_remove.py b/Mailman/Commands/cmd_remove.py
new file mode 100644
index 00000000..55be1f3e
--- /dev/null
+++ b/Mailman/Commands/cmd_remove.py
@@ -0,0 +1,20 @@
+# Copyright (C) 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.
+
+"""The `remove' command is synonymous with `unsubscribe'.
+"""
+
+from Mailman.Commands.cmd_unsubscribe import process
diff --git a/Mailman/Commands/cmd_set.py b/Mailman/Commands/cmd_set.py
new file mode 100644
index 00000000..c3eaa9a6
--- /dev/null
+++ b/Mailman/Commands/cmd_set.py
@@ -0,0 +1,353 @@
+# Copyright (C) 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.
+
+from email.Utils import parseaddr, formatdate
+
+from Mailman import mm_cfg
+from Mailman import Errors
+from Mailman import MemberAdaptor
+from Mailman import i18n
+
+def _(s): return s
+
+OVERVIEW = _("""
+ set ...
+ Set or view your membership options.
+
+ Use `set help' (without the quotes) to get a more detailed list of the
+ options you can change.
+
+ Use `set show' (without the quotes) to view your current option
+ settings.
+""")
+
+DETAILS = _("""
+ set help
+ Show this detailed help.
+
+ set show [address=<address>]
+ View your current option settings. If you're posting from an address
+ other than your membership address, specify your membership address
+ with `address=<address>' (no brackets around the email address, and no
+ quotes!).
+
+ set authenticate <password> [address=<address>]
+ To set any of your options, you must include this command first, along
+ with your membership password. If you're posting from an address
+ other than your membership address, specify your membership address
+ with `address=<address>' (no brackets around the email address, and no
+ quotes!).
+
+ set ack on
+ set ack off
+ When the `ack' option is turned on, you will receive an
+ acknowledgement message whenever you post a message to the list.
+
+ set digest plain
+ set digest mime
+ set digest off
+ When the `digest' option is turned off, you will receive postings
+ immediately when they are posted. Use `set digest plain' if instead
+ you want to receive postings bundled into a plain text digest
+ (i.e. RFC 1153 digest). Use `set digest mime' if instead you want to
+ receive postings bundled together into a MIME digest.
+
+ set delivery on
+ set delivery off
+ Turn delivery on or off. This does not unsubscribe you, but instead
+ tells Mailman not to deliver messages to you for now. This is useful
+ if you're going on vacation. Be sure to use `set delivery on' when
+ you return from vacation!
+
+ set myposts on
+ set myposts off
+ Use `set myposts off' to not receive copies of messages you post to
+ the list. This has no effect if you're receiving digests.
+
+ set hide on
+ set hide off
+ Use `set hide on' to conceal your email address when people request
+ the membership list.
+
+ set duplicates on
+ set duplicates off
+ Use `set duplicates off' if you want Mailman to not send you messages
+ if your address is explicitly mentioned in the To: or Cc: fields of
+ the message. This can reduce the number of duplicate postings you
+ will receive.
+
+ set reminders on
+ set reminders off
+ Use `set reminders off' if you want to disable the monthly password
+ reminder for this mailing list.
+""")
+
+_ = i18n._
+
+STOP = 1
+
+
+
+def gethelp(mlist):
+ return _(OVERVIEW)
+
+
+
+class SetCommands:
+ def __init__(self):
+ self.__address = None
+ self.__authok = 0
+
+ def process(self, res, args):
+ if not args:
+ res.results.append(_(DETAILS))
+ return STOP
+ subcmd = args.pop(0)
+ methname = 'set_' + subcmd
+ method = getattr(self, methname, None)
+ if method is None:
+ res.results.append(_('Bad set command: %(subcmd)s'))
+ res.results.append(_(DETAILS))
+ return STOP
+ return method(res, args)
+
+ def set_help(self, res, args=1):
+ res.results.append(_(DETAILS))
+ if args:
+ return STOP
+
+ def _usage(self, res):
+ res.results.append(_('Usage:'))
+ return self.set_help(res)
+
+ def set_show(self, res, args):
+ mlist = res.mlist
+ if not args:
+ realname, address = parseaddr(res.msg['from'])
+ elif len(args) == 1 and args[0].startswith('address='):
+ # Send the results to the address, not the From: dude
+ address = args[0][8:]
+ res.returnaddr = address
+ else:
+ return self._usage(res)
+ if not mlist.isMember(address):
+ listname = mlist.real_name
+ res.results.append(
+ _('You are not a member of the %(listname)s mailing list'))
+ return STOP
+ res.results.append(_('Your current option settings:'))
+ opt = mlist.getMemberOption(address, mm_cfg.AcknowledgePosts)
+ onoff = opt and _('on') or _('off')
+ res.results.append(_(' ack %(onoff)s'))
+ # Digests are a special ternary value
+ digestsp = mlist.getMemberOption(address, mm_cfg.Digests)
+ if digestsp:
+ plainp = mlist.getMemberOption(address, mm_cfg.DisableMime)
+ if plainp:
+ res.results.append(_(' digest plain'))
+ else:
+ res.results.append(_(' digest mime'))
+ else:
+ res.results.append(_(' digest off'))
+ # If their membership is disabled, let them know why
+ status = mlist.getDeliveryStatus(address)
+ how = None
+ if status == MemberAdaptor.ENABLED:
+ status = _('delivery on')
+ elif status == MemberAdaptor.BYUSER:
+ status = _('delivery off')
+ how = _('by you')
+ elif status == MemberAdaptor.BYADMIN:
+ status = _('delivery off')
+ how = _('by the admin')
+ elif status == MemberAdaptor.BYBOUNCE:
+ status = _('delivery off')
+ how = _('due to bounces')
+ else:
+ assert status == MemberAdaptor.UNKNOWN
+ status = _('delivery off')
+ how = _('for unknown reasons')
+ changetime = mlist.getDeliveryStatusChangeTime(address)
+ if how and changetime > 0:
+ date = formatdate(changetime)
+ res.results.append(_(' %(status)s (%(how)s on %(date)s)'))
+ else:
+ res.results.append(' ' + status)
+ opt = mlist.getMemberOption(address, mm_cfg.DontReceiveOwnPosts)
+ # sense is reversed
+ onoff = (not opt) and _('on') or _('off')
+ res.results.append(_(' myposts %(onoff)s'))
+ opt = mlist.getMemberOption(address, mm_cfg.ConcealSubscription)
+ onoff = opt and _('on') or _('off')
+ res.results.append(_(' hide %(onoff)s'))
+ opt = mlist.getMemberOption(address, mm_cfg.DontReceiveDuplicates)
+ # sense is reversed
+ onoff = (not opt) and _('on') or _('off')
+ res.results.append(_(' duplicates %(onoff)s'))
+ opt = mlist.getMemberOption(address, mm_cfg.SuppressPasswordReminder)
+ # sense is reversed
+ onoff = (not opt) and _('on') or _('off')
+ res.results.append(_(' reminders %(onoff)s'))
+
+ def set_authenticate(self, res, args):
+ mlist = res.mlist
+ if len(args) == 1:
+ realname, address = parseaddr(res.msg['from'])
+ password = args[0]
+ elif len(args) == 2 and args[1].startswith('address='):
+ password = args[0]
+ address = args[1][8:]
+ else:
+ return self._usage(res)
+ # See if the password matches
+ if not mlist.isMember(address):
+ listname = mlist.real_name
+ res.results.append(
+ _('You are not a member of the %(listname)s mailing list'))
+ return STOP
+ if not mlist.Authenticate((mm_cfg.AuthUser,
+ mm_cfg.AuthListAdmin),
+ password, address):
+ res.results.append(_('You did not give the correct password'))
+ return STOP
+ self.__authok = 1
+ self.__address = address
+
+ def _status(self, res, arg):
+ status = arg.lower()
+ if status == 'on':
+ flag = 1
+ elif status == 'off':
+ flag = 0
+ else:
+ res.results.append(_('Bad argument: %(arg)s'))
+ self._usage(res)
+ return -1
+ # See if we're authenticated
+ if not self.__authok:
+ res.results.append(_('Not authenticated'))
+ self._usage(res)
+ return -1
+ return flag
+
+ def set_ack(self, res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ return self._usage(res)
+ status = self._status(res, args[0])
+ if status < 0:
+ return STOP
+ mlist.setMemberOption(self.__address, mm_cfg.AcknowledgePosts, status)
+ res.results.append(_('ack option set'))
+
+ def set_digest(self, res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ return self._usage(res)
+ if not self.__authok:
+ res.results.append(_('Not authenticated'))
+ self._usage(res)
+ return STOP
+ arg = args[0].lower()
+ if arg == 'off':
+ try:
+ mlist.setMemberOption(self.__address, mm_cfg.Digests, 0)
+ except Errors.AlreadyReceivingRegularDeliveries:
+ pass
+ elif arg == 'plain':
+ try:
+ mlist.setMemberOption(self.__address, mm_cfg.Digests, 1)
+ except Errors.AlreadyReceivingDigests:
+ pass
+ mlist.setMemberOption(self.__address, mm_cfg.DisableMime, 1)
+ elif arg == 'mime':
+ try:
+ mlist.setMemberOption(self.__address, mm_cfg.Digests, 1)
+ except Errors.AlreadyReceivingDigests:
+ pass
+ mlist.setMemberOption(self.__address, mm_cfg.DisableMime, 0)
+ else:
+ res.results.append(_('Bad argument: %(arg)s'))
+ self._usage(res)
+ return STOP
+ res.results.append(_('digest option set'))
+
+ def set_delivery(self, res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ return self._usage(res)
+ status = self._status(res, args[0])
+ if status < 0:
+ return STOP
+ # sense is reversed
+ mlist.setMemberOption(self.__address, mm_cfg.DisableDelivery,
+ not status)
+ res.results.append(_('delivery option set'))
+
+ def set_myposts(self, res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ return self._usage(res)
+ status = self._status(res, args[0])
+ if status < 0:
+ return STOP
+ # sense is reversed
+ mlist.setMemberOption(self.__address, mm_cfg.DontReceiveOwnPosts,
+ not status)
+ res.results.append(_('myposts option set'))
+
+ def set_hide(self, res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ return self._usage(res)
+ status = self._status(res, args[0])
+ if status < 0:
+ return STOP
+ mlist.setMemberOption(self.__address, mm_cfg.ConcealSubscription,
+ status)
+ res.results.append(_('hide option set'))
+
+ def set_duplicates(self, res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ return self._usage(res)
+ status = self._status(res, args[0])
+ if status < 0:
+ return STOP
+ # sense is reversed
+ mlist.setMemberOption(self.__address, mm_cfg.DontReceiveDuplicates,
+ not status)
+ res.results.append(_('duplicates option set'))
+
+ def set_reminders(self, res, args):
+ mlist = res.mlist
+ if len(args) <> 1:
+ return self._usage(res)
+ status = self._status(res, args[0])
+ if status < 0:
+ return STOP
+ # sense is reversed
+ mlist.setMemberOption(self.__address, mm_cfg.SuppressPasswordReminder,
+ not status)
+ res.results.append(_('reminder option set'))
+
+
+
+def process(res, args):
+ # We need to keep some state between set commands
+ if not getattr(res, 'setstate', None):
+ res.setstate = SetCommands()
+ res.setstate.process(res, args)
diff --git a/Mailman/Commands/cmd_stop.py b/Mailman/Commands/cmd_stop.py
new file mode 100644
index 00000000..defcf64d
--- /dev/null
+++ b/Mailman/Commands/cmd_stop.py
@@ -0,0 +1,20 @@
+# Copyright (C) 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.
+
+"""stop is synonymous with the end command.
+"""
+
+from Mailman.Commands.cmd_end import process
diff --git a/Mailman/Commands/cmd_subscribe.py b/Mailman/Commands/cmd_subscribe.py
new file mode 100644
index 00000000..1a5048d6
--- /dev/null
+++ b/Mailman/Commands/cmd_subscribe.py
@@ -0,0 +1,136 @@
+# Copyright (C) 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.
+
+"""
+ subscribe [password] [digest|nodigest] [address=<address>]
+ Subscribe to this mailing list. Your password must be given to
+ unsubscribe or change your options, but if you omit the password, one
+ will be generated for you. You may be periodically reminded of your
+ password.
+
+ The next argument may be either: `nodigest' or `digest' (no quotes!).
+ If you wish to subscribe an address other than the address you sent
+ this request from, you may specify `address=<address>' (no brackets
+ around the email address, and no quotes!)
+"""
+
+from email.Utils import parseaddr
+from email.Header import decode_header, make_header
+
+from Mailman import Utils
+from Mailman import Errors
+from Mailman.UserDesc import UserDesc
+from Mailman.i18n import _
+
+STOP = 1
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ mlist = res.mlist
+ digest = None
+ password = None
+ address = None
+ realname = None
+ # Parse the args
+ argnum = 0
+ for arg in args:
+ if arg.startswith('address='):
+ address = arg[8:]
+ elif argnum == 0:
+ password = arg
+ elif argnum == 1:
+ if arg.lower() not in ('digest', 'nodigest'):
+ res.results.append(_('Bad digest specifier: %(arg)s'))
+ return STOP
+ if arg.lower() == 'digest':
+ digest = 1
+ else:
+ digest = 0
+ else:
+ res.results.append(_('Usage:'))
+ res.results.append(gethelp(mlist))
+ return STOP
+ argnum += 1
+ # Fill in empty defaults
+ if digest is None:
+ digest = mlist.digest_is_default
+ if password is None:
+ password = Utils.MakeRandomPassword()
+ if address is None:
+ realname, address = parseaddr(res.msg['from'])
+ if not address:
+ # Fall back to the sender address
+ address = res.msg.get_sender()
+ if not address:
+ res.results.append(_('No valid address found to subscribe'))
+ return STOP
+ # Watch for encoded names
+ h = make_header(decode_header(realname))
+ # BAW: in Python 2.2, use just unicode(h)
+ realname = h.__unicode__()
+ # Coerce to byte string if uh contains only ascii
+ try:
+ realname = realname.encode('us-ascii')
+ except UnicodeError:
+ pass
+ # Create the UserDesc record and do a non-approved subscription
+ listowner = mlist.GetOwnerEmail()
+ userdesc = UserDesc(address, realname, password, digest)
+ remote = res.msg.get_sender()
+ try:
+ mlist.AddMember(userdesc, remote)
+ except Errors.MembershipIsBanned:
+ res.results.append(_("""\
+The email address you supplied is banned from this mailing list.
+If you think this restriction is erroneous, please contact the list
+owners at %(listowner)s."""))
+ return STOP
+ except Errors.MMBadEmailError:
+ res.results.append(_("""\
+Mailman won't accept the given email address as a valid address.
+(E.g. it must have an @ in it.)"""))
+ return STOP
+ except Errors.MMHostileAddress:
+ res.results.append(_("""\
+Your subscription is not allowed because
+the email address you gave is insecure."""))
+ return STOP
+ except Errors.MMAlreadyAMember:
+ res.results.append(_('You are already subscribed!'))
+ return STOP
+ except Errors.MMCantDigestError:
+ res.results.append(
+ _('No one can subscribe to the digest of this list!'))
+ return STOP
+ except Errors.MMMustDigestError:
+ res.results.append(_('This list only supports digest subscriptions!'))
+ return STOP
+ except Errors.MMSubscribeNeedsConfirmation:
+ # We don't need to respond /and/ send a confirmation message.
+ res.respond = 0
+ except Errors.MMNeedApproval:
+ res.results.append(_("""\
+Your subscription request has been forwarded to the list administrator
+at %(listowner)s for review."""))
+ else:
+ # Everything is a-ok
+ res.results.append(_('Subscription request succeeded.'))
diff --git a/Mailman/Commands/cmd_unsubscribe.py b/Mailman/Commands/cmd_unsubscribe.py
new file mode 100644
index 00000000..c574a80f
--- /dev/null
+++ b/Mailman/Commands/cmd_unsubscribe.py
@@ -0,0 +1,87 @@
+# Copyright (C) 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.
+
+"""
+ unsubscribe [password] [address=<address>]
+ Unsubscribe from the mailing list. If given, your password must match
+ your current password. If omitted, a confirmation email will be sent
+ to the unsubscribing address. If you wish to unsubscribe an address
+ other than the address you sent this request from, you may specify
+ `address=<address>' (no brackets around the email address, and no
+ quotes!)
+"""
+
+from email.Utils import parseaddr
+
+from Mailman import Errors
+from Mailman.i18n import _
+
+STOP = 1
+
+
+
+def gethelp(mlist):
+ return _(__doc__)
+
+
+
+def process(res, args):
+ mlist = res.mlist
+ password = None
+ address = None
+ argnum = 0
+ for arg in args:
+ if arg.startswith('address='):
+ address = arg[8:]
+ elif argnum == 0:
+ password = arg
+ else:
+ res.results.append(_('Usage:'))
+ res.results.append(gethelp(mlist))
+ return STOP
+ argnum += 1
+ # Fill in empty defaults
+ if address is None:
+ realname, address = parseaddr(res.msg['from'])
+ if not mlist.isMember(address):
+ listname = mlist.real_name
+ res.results.append(
+ _('%(address)s is not a member of the %(listname)s mailing list'))
+ return STOP
+ # If we're doing admin-approved unsubs, don't worry about the password
+ if mlist.unsubscribe_policy:
+ try:
+ mlist.DeleteMember(address, 'mailcmd')
+ except Errors.MMNeedApproval:
+ res.results.append(_("""\
+Your unsubscription request has been forwarded to the list administrator for
+approval."""))
+ elif password is None:
+ # No password was given, so we need to do a mailback confirmation
+ # instead of unsubscribing them here.
+ cpaddr = mlist.getMemberCPAddress(address)
+ mlist.ConfirmUnsubscription(cpaddr)
+ # We don't also need to send a confirmation to this command
+ res.respond = 0
+ else:
+ # No admin approval is necessary, so we can just delete them if the
+ # passwords match.
+ oldpw = mlist.getMemberPassword(address)
+ if oldpw <> password:
+ res.results.append(_('You gave the wrong password'))
+ return STOP
+ mlist.ApprovedDeleteMember(address, 'mailcmd')
+ res.results.append(_('Unsubscription request succeeded.'))
diff --git a/Mailman/Commands/cmd_who.py b/Mailman/Commands/cmd_who.py
new file mode 100644
index 00000000..62505b3d
--- /dev/null
+++ b/Mailman/Commands/cmd_who.py
@@ -0,0 +1,133 @@
+# Copyright (C) 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.
+
+# Remove this when base minimal compatibility is Python 2.2
+from __future__ import nested_scopes
+
+from email.Utils import parseaddr
+
+from Mailman import mm_cfg
+from Mailman import i18n
+
+STOP = 1
+
+def _(s): return s
+
+PUBLICHELP = _("""
+ who
+ See everyone who is on this mailing list.
+""")
+
+MEMBERSONLYHELP = _("""
+ who password [address=<address>]
+ See everyone who is on this mailing list. The roster is limited to
+ list members only, and you must supply your membership password to
+ retrieve it. If you're posting from an address other than your
+ membership address, specify your membership address with
+ `address=<address>' (no brackets around the email address, and no
+ quotes!)
+""")
+
+ADMINONLYHELP = _("""
+ who password
+ See everyone who is on this mailing list. The roster is limited to
+ list administrators and moderators only; you must supply the list
+ admin or moderator password to retrieve the roster.
+""")
+
+_ = i18n._
+
+
+
+def gethelp(mlist):
+ if mlist.private_roster == 0:
+ return _(PUBLICHELP)
+ elif mlist.private_roster == 1:
+ return _(MEMBERSONLYHELP)
+ elif mlist.private_roster == 2:
+ return _(ADMINONLYHELP)
+
+
+def usage(res):
+ res.results.append(_('Usage:'))
+ res.results.append(gethelp(res.mlist))
+
+
+
+def process(res, args):
+ mlist = res.mlist
+ address = None
+ password = None
+ ok = 0
+ if mlist.private_roster == 0:
+ # Public rosters
+ if args:
+ usage(res)
+ return STOP
+ ok = 1
+ elif mlist.private_roster == 1:
+ # List members only
+ if len(args) == 1:
+ password = args[0]
+ realname, address = parseaddr(res.msg['from'])
+ elif len(args) == 2 and args[1].startswith('address='):
+ password = args[0]
+ address = args[1][8:]
+ else:
+ usage(res)
+ return STOP
+ if mlist.isMember(address) and mlist.Authenticate(
+ (mm_cfg.AuthUser,
+ mm_cfg.AuthListModerator,
+ mm_cfg.AuthListAdmin),
+ password, address):
+ # Then
+ ok = 1
+ else:
+ # Admin only
+ if len(args) <> 1:
+ usage(res)
+ return STOP
+ if mlist.Authenticate((mm_cfg.AuthListModerator,
+ mm_cfg.AuthListAdmin),
+ args[0]):
+ ok = 1
+ if not ok:
+ res.results.append(
+ _('You are not allowed to retrieve the list membership.'))
+ return STOP
+ # It's okay for this person to see the list membership
+ dmembers = mlist.getDigestMemberKeys()
+ rmembers = mlist.getRegularMemberKeys()
+ if not dmembers and not rmembers:
+ res.results.append(_('This list has no members.'))
+ return
+ # Convenience function
+ def addmembers(members):
+ for member in members:
+ if mlist.getMemberOption(member, mm_cfg.ConcealSubscription):
+ continue
+ realname = mlist.getMemberName(member)
+ if realname:
+ res.results.append(' %s (%s)' % (member, realname))
+ else:
+ res.results.append(' %s' % member)
+ if rmembers:
+ res.results.append(_('Non-digest (regular) members:'))
+ addmembers(rmembers)
+ if dmembers:
+ res.results.append(_('Digest members:'))
+ addmembers(dmembers)