summaryrefslogtreecommitdiff
path: root/src/mailman/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/commands')
-rw-r--r--src/mailman/commands/cli_aliases.py76
-rw-r--r--src/mailman/commands/docs/aliases.rst (renamed from src/mailman/commands/docs/aliases.txt)74
2 files changed, 135 insertions, 15 deletions
diff --git a/src/mailman/commands/cli_aliases.py b/src/mailman/commands/cli_aliases.py
index dcb494ebb..b13919121 100644
--- a/src/mailman/commands/cli_aliases.py
+++ b/src/mailman/commands/cli_aliases.py
@@ -27,11 +27,16 @@ __all__ = [
import sys
+from operator import attrgetter
+from zope.component import getUtility
from zope.interface import implements
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.command import ICLISubCommand
+from mailman.interfaces.listmanager import IListManager
+from mailman.interfaces.mta import (
+ IMailTransportAgentAliases, IMailTransportAgentLifecycle)
from mailman.utilities.modules import call_name
@@ -45,14 +50,29 @@ class Aliases:
def add(self, parser, command_parser):
"""See `ICLISubCommand`."""
+ self.parser = parser
command_parser.add_argument(
'-o', '--output',
action='store', help=_("""\
File to send the output to. If not given, a file in $VAR/data is
used. The argument can be '-' to use standard output.."""))
+ command_parser.add_argument(
+ '-f', '--format',
+ action='store', help=_("""\
+ Alternative output format to use. This is the Python object path
+ to an implementation of the `IMailTransportAgentLifecycle`
+ interface."""))
+ command_parser.add_argument(
+ '-s', '--simple',
+ action='store_true', default=False, help=_("""\
+ Simply output the list of aliases.
+ """))
def process(self, args):
"""See `ICLISubCommand`."""
+ if args.format is not None and args.simple:
+ self.parser.error(_('Cannot use both -s and -f'))
+ # Does not return.
output = None
if args.output == '-':
output = sys.stdout
@@ -60,5 +80,57 @@ class Aliases:
output = None
else:
output = args.output
- # Call the MTA-specific regeneration method.
- call_name(config.mta.incoming).regenerate(output)
+ if args.simple:
+ Dummy().regenerate(output)
+ else:
+ format_arg = (config.mta.incoming
+ if args.format is None
+ else args.format)
+ # Call the MTA-specific regeneration method.
+ call_name(format_arg).regenerate(output)
+
+
+
+class Dummy:
+ """Dummy aliases implementation for simpler output format."""
+
+ implements(IMailTransportAgentLifecycle)
+
+ def create(self, mlist):
+ """See `IMailTransportAgentLifecycle`."""
+ raise NotImplementedError
+
+ def delete(self, mlist):
+ """See `IMailTransportAgentLifecycle`."""
+ raise NotImplementedError
+
+ def regenerate(self, output=None):
+ """See `IMailTransportAgentLifecycle`."""
+ fp = None
+ close = False
+ try:
+ if output is None:
+ # There's really no place to print the output.
+ return
+ elif isinstance(output, basestring):
+ fp = open(output, 'w')
+ close = True
+ else:
+ fp = output
+ self._do_write_file(fp)
+ finally:
+ if fp is not None and close:
+ fp.close()
+
+ def _do_write_file(self, fp):
+ # First, sort mailing lists by domain.
+ by_domain = {}
+ for mlist in getUtility(IListManager).mailing_lists:
+ by_domain.setdefault(mlist.host_name, []).append(mlist)
+ sort_key = attrgetter('list_name')
+ for domain in sorted(by_domain):
+ for mlist in sorted(by_domain[domain], key=sort_key):
+ utility = getUtility(IMailTransportAgentAliases)
+ for alias in utility.aliases(mlist):
+ print >> fp, alias
+ print >> fp
diff --git a/src/mailman/commands/docs/aliases.txt b/src/mailman/commands/docs/aliases.rst
index 0822ad973..c0d4c10c9 100644
--- a/src/mailman/commands/docs/aliases.txt
+++ b/src/mailman/commands/docs/aliases.rst
@@ -6,11 +6,12 @@ For some mail servers, Mailman must generate a data file that is used to hook
Mailman up to the mail server. The details of this differ for each mail
server. Generally these files are automatically kept up-to-date when mailing
lists are created or removed, but you might occasionally need to manually
-regenerate the file. The 'bin/mailman aliases' command does this.
+regenerate the file. The ``bin/mailman aliases`` command does this.
>>> class FakeArgs:
... output = None
-
+ ... format = None
+ ... simple = None
>>> from mailman.commands.cli_aliases import Aliases
>>> command = Aliases()
@@ -32,19 +33,13 @@ generation.
Let's create a mailing list and then display the transport map for it. We'll
send the output to stdout.
+::
>>> FakeArgs.output = '-'
>>> mlist = create_list('test@example.com')
>>> command.process(FakeArgs)
# AUTOMATICALLY GENERATED BY MAILMAN ON ...
- #
- # This file is generated by Mailman, and is kept in sync with the ...
- # file. YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you know what you're
- # doing, and can keep the two files properly in sync. If you screw it up,
- # you're on your own.
- <BLANKLINE>
- # Aliases which are visible only in the @example.com domain.
- <BLANKLINE>
+ ...
test@example.com lmtp:[lmtp.example.com]:24
test-bounces@example.com lmtp:[lmtp.example.com]:24
test-confirm@example.com lmtp:[lmtp.example.com]:24
@@ -56,8 +51,61 @@ send the output to stdout.
test-unsubscribe@example.com lmtp:[lmtp.example.com]:24
<BLANKLINE>
+ >>> config.pop('postfix')
-Clean up
-========
- >>> config.pop('postfix')
+Alternative output
+==================
+
+By using a command line switch, we can select a different output format. The
+option must point to an alternative implementation of the
+``IMailTransportAgentAliases`` interface.
+
+Mailman comes with an alternative implementation that just prints the aliases,
+with no adornment.
+
+ >>> FakeArgs.format = 'mailman.commands.cli_aliases.Dummy'
+ >>> command.process(FakeArgs)
+ test@example.com
+ test-bounces@example.com
+ test-confirm@example.com
+ test-join@example.com
+ test-leave@example.com
+ test-owner@example.com
+ test-request@example.com
+ test-subscribe@example.com
+ test-unsubscribe@example.com
+ <BLANKLINE>
+
+A simpler way of getting the same output is with the ``--simple`` flag.
+
+ >>> FakeArgs.format = None
+ >>> FakeArgs.simple = True
+ >>> command.process(FakeArgs)
+ test@example.com
+ test-bounces@example.com
+ test-confirm@example.com
+ test-join@example.com
+ test-leave@example.com
+ test-owner@example.com
+ test-request@example.com
+ test-subscribe@example.com
+ test-unsubscribe@example.com
+ <BLANKLINE>
+
+
+Mutually exclusive arguments
+============================
+
+You cannot use both ``--simple`` and ``--format``.
+
+ >>> FakeArgs.format = 'mailman.commands.cli_aliases.Dummy'
+ >>> FakeArgs.simple = True
+ >>> class Parser:
+ ... def error(self, message):
+ ... raise RuntimeError(message)
+ >>> command.parser = Parser()
+ >>> command.process(FakeArgs)
+ Traceback (most recent call last):
+ ...
+ RuntimeError: Cannot use both -s and -f