diff options
Diffstat (limited to 'src/mailman/commands')
| -rw-r--r-- | src/mailman/commands/cli_aliases.py | 76 | ||||
| -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 |
