From df000679f72bfbf1d40e7d1553b376cda524be95 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Sun, 9 Aug 2009 11:01:16 -0400 Subject: Rename files inside src/mailman/commands to indicate whether it's an email command (eml_ prefix) or a command line interface (cli_ prefix). Fix a test breakage. --- src/mailman/commands/cli_lists.py | 102 +++++++++++++++++++++++++++++ src/mailman/commands/docs/lists.txt | 2 +- src/mailman/commands/echo.py | 48 -------------- src/mailman/commands/eml_echo.py | 48 ++++++++++++++ src/mailman/commands/eml_end.py | 51 +++++++++++++++ src/mailman/commands/eml_join.py | 127 ++++++++++++++++++++++++++++++++++++ src/mailman/commands/end.py | 51 --------------- src/mailman/commands/join.py | 127 ------------------------------------ src/mailman/commands/lists.py | 102 ----------------------------- src/mailman/docs/hooks.txt | 9 +-- 10 files changed, 332 insertions(+), 335 deletions(-) create mode 100644 src/mailman/commands/cli_lists.py delete mode 100644 src/mailman/commands/echo.py create mode 100644 src/mailman/commands/eml_echo.py create mode 100644 src/mailman/commands/eml_end.py create mode 100644 src/mailman/commands/eml_join.py delete mode 100644 src/mailman/commands/end.py delete mode 100644 src/mailman/commands/join.py delete mode 100644 src/mailman/commands/lists.py (limited to 'src') diff --git a/src/mailman/commands/cli_lists.py b/src/mailman/commands/cli_lists.py new file mode 100644 index 000000000..6757099d9 --- /dev/null +++ b/src/mailman/commands/cli_lists.py @@ -0,0 +1,102 @@ +# Copyright (C) 2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see . + +"""The 'lists' subcommand.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'Lists', + ] + + +from zope.interface import implements + +from mailman.config import config +from mailman.i18n import _ +from mailman.interfaces.command import ICLISubCommand + + + +class Lists: + """The `lists` subcommand.""" + + implements(ICLISubCommand) + + def add(self, subparser): + """See `ICLISubCommand`.""" + lists_parser = subparser.add_parser( + 'lists', help=_('List all mailing lists')) + lists_parser.add_argument( + '-a', '--advertised', + default=False, action='store_true', + help=_( + 'List only those mailing lists that are publicly advertised')) + lists_parser.add_argument( + '-b', '--bare', + default=False, action='store_true', + help=_('Show only the list name, with no description')) + lists_parser.add_argument( + '-d', '--domain', + action='append', help=_("""\ + List only those mailing lists hosted on the given domain, which + must be the email host name. Multiple -d options may be given. + """)) + lists_parser.add_argument( + '-f', '--full', + default=False, action='store_true', + help=_( + 'Show the full mailing list name (i.e. the posting address')) + lists_parser.set_defaults(func=self.process) + + def process(self, args): + """See `ICLISubCommand`.""" + mailing_lists = [] + list_manager = config.db.list_manager + # Gather the matching mailing lists. + for fqdn_name in sorted(list_manager.names): + mlist = list_manager.get(fqdn_name) + if args.advertised and not mlist.advertised: + continue + if args.domains and mlist.host_name not in args.domains: + continue + mailing_lists.append(mlist) + # Maybe no mailing lists matched. + if len(mailing_lists) == 0: + if not args.bare: + print _('No matching mailing lists found') + return + if not args.bare: + count = len(mailing_lists) + print _('$count matching mailing lists found:') + # Calculate the longest mailing list name. + longest = len( + max(mlist.fqdn_listname for mlist in mailing_lists) + if args.full else + max(mlist.real_name for mlist in mailing_lists)) + # Print it out. + for mlist in mailing_lists: + name = (mlist.fqdn_listname if args.full else mlist.real_name) + if args.bare: + print name + else: + description = (mlist.description + if mlist.description is not None + else _('[no description available]')) + print '{0:{2}} - {1:{3}}'.format( + name, description, longest, 77 - longest) diff --git a/src/mailman/commands/docs/lists.txt b/src/mailman/commands/docs/lists.txt index 85fe7edc2..6a9bee665 100644 --- a/src/mailman/commands/docs/lists.txt +++ b/src/mailman/commands/docs/lists.txt @@ -11,7 +11,7 @@ line. When there are no mailing lists, a helpful message is displayed. ... domains = None ... full = False - >>> from mailman.commands.lists import Lists + >>> from mailman.commands.cli_lists import Lists >>> command = Lists() >>> command.process(FakeArgs) No matching mailing lists found diff --git a/src/mailman/commands/echo.py b/src/mailman/commands/echo.py deleted file mode 100644 index 30590acf8..000000000 --- a/src/mailman/commands/echo.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (C) 2002-2009 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman 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 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman 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 -# GNU Mailman. If not, see . - -"""The email command 'echo'.""" - -__metaclass__ = type -__all__ = [ - 'Echo', - ] - - -from zope.interface import implements - -from mailman.i18n import _ -from mailman.interfaces.command import ContinueProcessing, IEmailCommand - - -SPACE = ' ' - - - -class Echo: - """The email 'echo' command.""" - implements(IEmailCommand) - - name = 'echo' - argument_description = '[args]' - description = _( - 'Echo an acknowledgement. Arguments are return unchanged.') - - def process(self, mlist, msg, msgdata, arguments, results): - """See `IEmailCommand`.""" - print >> results, 'echo', SPACE.join(arguments) - return ContinueProcessing.yes diff --git a/src/mailman/commands/eml_echo.py b/src/mailman/commands/eml_echo.py new file mode 100644 index 000000000..30590acf8 --- /dev/null +++ b/src/mailman/commands/eml_echo.py @@ -0,0 +1,48 @@ +# Copyright (C) 2002-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see . + +"""The email command 'echo'.""" + +__metaclass__ = type +__all__ = [ + 'Echo', + ] + + +from zope.interface import implements + +from mailman.i18n import _ +from mailman.interfaces.command import ContinueProcessing, IEmailCommand + + +SPACE = ' ' + + + +class Echo: + """The email 'echo' command.""" + implements(IEmailCommand) + + name = 'echo' + argument_description = '[args]' + description = _( + 'Echo an acknowledgement. Arguments are return unchanged.') + + def process(self, mlist, msg, msgdata, arguments, results): + """See `IEmailCommand`.""" + print >> results, 'echo', SPACE.join(arguments) + return ContinueProcessing.yes diff --git a/src/mailman/commands/eml_end.py b/src/mailman/commands/eml_end.py new file mode 100644 index 000000000..a9298bc92 --- /dev/null +++ b/src/mailman/commands/eml_end.py @@ -0,0 +1,51 @@ +# Copyright (C) 2002-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see . + +"""The email commands 'end' and 'stop'.""" + +__metaclass__ = type +__all__ = [ + 'End', + 'Stop', + ] + + +from zope.interface import implements + +from mailman.i18n import _ +from mailman.interfaces.command import ContinueProcessing, IEmailCommand + + + +class End: + """The email 'end' command.""" + implements(IEmailCommand) + + name = 'end' + argument_description = '' + description = _('Stop processing commands.') + + def process(self, mlist, msg, msgdata, arguments, results): + """See `IEmailCommand`.""" + # Ignore all arguments. + return ContinueProcessing.no + + +class Stop(End): + """The email 'stop' command (an alias for 'end').""" + + name = 'stop' diff --git a/src/mailman/commands/eml_join.py b/src/mailman/commands/eml_join.py new file mode 100644 index 000000000..d1f9dd816 --- /dev/null +++ b/src/mailman/commands/eml_join.py @@ -0,0 +1,127 @@ +# Copyright (C) 2002-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see . + +"""The email commands 'join' and 'subscribe'.""" + +__metaclass__ = type +__all__ = [ + 'Join', + 'Subscribe', + ] + + +from email.utils import formataddr, parseaddr +from zope.interface import implements + +from mailman.config import config +from mailman.i18n import _ +from mailman.interfaces.command import ContinueProcessing, IEmailCommand +from mailman.interfaces.domain import IDomainManager +from mailman.interfaces.member import DeliveryMode +from mailman.interfaces.registrar import IRegistrar + + + +class Join: + """The email 'join' command.""" + implements(IEmailCommand) + + name = 'join' + argument_description = '[digest=] [address=
]' + description = _("""\ +Join this mailing list. You will be asked to confirm your subscription +request and you may be issued a provisional password. + +By using the 'digest' option, you can specify whether you want digest delivery +or not. If not specified, the mailing list's default will be used. You can +also subscribe an alternative address by using the 'address' option. For +example: + + join address=myotheraddress@example.com +""") + + def process(self, mlist, msg, msgdata, arguments, results): + """See `IEmailCommand`.""" + # Parse the arguments. + address, delivery_mode = self._parse_arguments(arguments) + if address is None: + real_name, address = parseaddr(msg['from']) + # Address could be None or the empty string. + if not address: + address = msg.sender + if not address: + print >> results, _( + '$self.name: No valid address found to subscribe') + return ContinueProcessing.no + domain = IDomainManager(config)[mlist.host_name] + registrar = IRegistrar(domain) + registrar.register(address, real_name, mlist) + person = formataddr((real_name, address)) + print >> results, _('Confirmation email sent to $person') + return ContinueProcessing.yes + + def _parse_arguments(self, arguments): + """Parse command arguments. + + :param arguments: The sequences of arguments as given to the + `process()` method. + :return: address, delivery_mode + """ + address = None + delivery_mode = None + for argument in arguments: + parts = argument.split('=', 1) + if parts[0].lower() == 'digest': + if digest is not None: + print >> results, self.name, \ + _('duplicate argument: $argument') + return ContinueProcessing.no + if len(parts) == 0: + # We treat just plain 'digest' as 'digest=yes'. We don't + # yet support the other types of digest delivery. + delivery_mode = DeliveryMode.mime_digests + else: + if parts[1].lower() == 'yes': + delivery_mode = DeliveryMode.mime_digests + elif parts[1].lower() == 'no': + delivery_mode = DeliveryMode.regular + else: + print >> results, self.name, \ + _('bad argument: $argument') + return ContinueProcessing.no + elif parts[0].lower() == 'address': + if address is not None: + print >> results, self.name, \ + _('duplicate argument $argument') + return ContinueProcessing.no + if len(parts) == 0: + print >> results, self.name, \ + _('missing argument value: $argument') + return ContinueProcessing.no + if len(parts) > 1: + print >> results, self.name, \ + _('too many argument values: $argument') + return ContinueProcessing.no + address = parts[1] + return address, delivery_mode + + + +class Subscribe(Join): + """The email 'subscribe' command (an alias for 'join').""" + + name = 'subscribe' diff --git a/src/mailman/commands/end.py b/src/mailman/commands/end.py deleted file mode 100644 index a9298bc92..000000000 --- a/src/mailman/commands/end.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (C) 2002-2009 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman 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 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman 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 -# GNU Mailman. If not, see . - -"""The email commands 'end' and 'stop'.""" - -__metaclass__ = type -__all__ = [ - 'End', - 'Stop', - ] - - -from zope.interface import implements - -from mailman.i18n import _ -from mailman.interfaces.command import ContinueProcessing, IEmailCommand - - - -class End: - """The email 'end' command.""" - implements(IEmailCommand) - - name = 'end' - argument_description = '' - description = _('Stop processing commands.') - - def process(self, mlist, msg, msgdata, arguments, results): - """See `IEmailCommand`.""" - # Ignore all arguments. - return ContinueProcessing.no - - -class Stop(End): - """The email 'stop' command (an alias for 'end').""" - - name = 'stop' diff --git a/src/mailman/commands/join.py b/src/mailman/commands/join.py deleted file mode 100644 index d1f9dd816..000000000 --- a/src/mailman/commands/join.py +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright (C) 2002-2009 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman 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 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman 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 -# GNU Mailman. If not, see . - -"""The email commands 'join' and 'subscribe'.""" - -__metaclass__ = type -__all__ = [ - 'Join', - 'Subscribe', - ] - - -from email.utils import formataddr, parseaddr -from zope.interface import implements - -from mailman.config import config -from mailman.i18n import _ -from mailman.interfaces.command import ContinueProcessing, IEmailCommand -from mailman.interfaces.domain import IDomainManager -from mailman.interfaces.member import DeliveryMode -from mailman.interfaces.registrar import IRegistrar - - - -class Join: - """The email 'join' command.""" - implements(IEmailCommand) - - name = 'join' - argument_description = '[digest=] [address=
]' - description = _("""\ -Join this mailing list. You will be asked to confirm your subscription -request and you may be issued a provisional password. - -By using the 'digest' option, you can specify whether you want digest delivery -or not. If not specified, the mailing list's default will be used. You can -also subscribe an alternative address by using the 'address' option. For -example: - - join address=myotheraddress@example.com -""") - - def process(self, mlist, msg, msgdata, arguments, results): - """See `IEmailCommand`.""" - # Parse the arguments. - address, delivery_mode = self._parse_arguments(arguments) - if address is None: - real_name, address = parseaddr(msg['from']) - # Address could be None or the empty string. - if not address: - address = msg.sender - if not address: - print >> results, _( - '$self.name: No valid address found to subscribe') - return ContinueProcessing.no - domain = IDomainManager(config)[mlist.host_name] - registrar = IRegistrar(domain) - registrar.register(address, real_name, mlist) - person = formataddr((real_name, address)) - print >> results, _('Confirmation email sent to $person') - return ContinueProcessing.yes - - def _parse_arguments(self, arguments): - """Parse command arguments. - - :param arguments: The sequences of arguments as given to the - `process()` method. - :return: address, delivery_mode - """ - address = None - delivery_mode = None - for argument in arguments: - parts = argument.split('=', 1) - if parts[0].lower() == 'digest': - if digest is not None: - print >> results, self.name, \ - _('duplicate argument: $argument') - return ContinueProcessing.no - if len(parts) == 0: - # We treat just plain 'digest' as 'digest=yes'. We don't - # yet support the other types of digest delivery. - delivery_mode = DeliveryMode.mime_digests - else: - if parts[1].lower() == 'yes': - delivery_mode = DeliveryMode.mime_digests - elif parts[1].lower() == 'no': - delivery_mode = DeliveryMode.regular - else: - print >> results, self.name, \ - _('bad argument: $argument') - return ContinueProcessing.no - elif parts[0].lower() == 'address': - if address is not None: - print >> results, self.name, \ - _('duplicate argument $argument') - return ContinueProcessing.no - if len(parts) == 0: - print >> results, self.name, \ - _('missing argument value: $argument') - return ContinueProcessing.no - if len(parts) > 1: - print >> results, self.name, \ - _('too many argument values: $argument') - return ContinueProcessing.no - address = parts[1] - return address, delivery_mode - - - -class Subscribe(Join): - """The email 'subscribe' command (an alias for 'join').""" - - name = 'subscribe' diff --git a/src/mailman/commands/lists.py b/src/mailman/commands/lists.py deleted file mode 100644 index 6757099d9..000000000 --- a/src/mailman/commands/lists.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (C) 2009 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman 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 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman 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 -# GNU Mailman. If not, see . - -"""The 'lists' subcommand.""" - -from __future__ import absolute_import, unicode_literals - -__metaclass__ = type -__all__ = [ - 'Lists', - ] - - -from zope.interface import implements - -from mailman.config import config -from mailman.i18n import _ -from mailman.interfaces.command import ICLISubCommand - - - -class Lists: - """The `lists` subcommand.""" - - implements(ICLISubCommand) - - def add(self, subparser): - """See `ICLISubCommand`.""" - lists_parser = subparser.add_parser( - 'lists', help=_('List all mailing lists')) - lists_parser.add_argument( - '-a', '--advertised', - default=False, action='store_true', - help=_( - 'List only those mailing lists that are publicly advertised')) - lists_parser.add_argument( - '-b', '--bare', - default=False, action='store_true', - help=_('Show only the list name, with no description')) - lists_parser.add_argument( - '-d', '--domain', - action='append', help=_("""\ - List only those mailing lists hosted on the given domain, which - must be the email host name. Multiple -d options may be given. - """)) - lists_parser.add_argument( - '-f', '--full', - default=False, action='store_true', - help=_( - 'Show the full mailing list name (i.e. the posting address')) - lists_parser.set_defaults(func=self.process) - - def process(self, args): - """See `ICLISubCommand`.""" - mailing_lists = [] - list_manager = config.db.list_manager - # Gather the matching mailing lists. - for fqdn_name in sorted(list_manager.names): - mlist = list_manager.get(fqdn_name) - if args.advertised and not mlist.advertised: - continue - if args.domains and mlist.host_name not in args.domains: - continue - mailing_lists.append(mlist) - # Maybe no mailing lists matched. - if len(mailing_lists) == 0: - if not args.bare: - print _('No matching mailing lists found') - return - if not args.bare: - count = len(mailing_lists) - print _('$count matching mailing lists found:') - # Calculate the longest mailing list name. - longest = len( - max(mlist.fqdn_listname for mlist in mailing_lists) - if args.full else - max(mlist.real_name for mlist in mailing_lists)) - # Print it out. - for mlist in mailing_lists: - name = (mlist.fqdn_listname if args.full else mlist.real_name) - if args.bare: - print name - else: - description = (mlist.description - if mlist.description is not None - else _('[no description available]')) - print '{0:{2}} - {1:{3}}'.format( - name, description, longest, 77 - longest) diff --git a/src/mailman/docs/hooks.txt b/src/mailman/docs/hooks.txt index ddc4fe5fa..381caf6ed 100644 --- a/src/mailman/docs/hooks.txt +++ b/src/mailman/docs/hooks.txt @@ -44,13 +44,13 @@ We can set the pre-hook in the configuration file. ... """ The hooks are run in the second and third steps of initialization. However, -we can't run those initialization steps in process, so call `bin/version` to -force the hooks to run. +we can't run those initialization steps in process, so call a command line +script that will produce no output to force the hooks to run. >>> import subprocess >>> def call(): ... proc = subprocess.Popen( - ... 'bin/version', + ... 'bin/mailman lists -d ignore -b'.split(), ... cwd='../..', # testrunner runs from ./parts/test ... env=dict(MAILMAN_CONFIG_FILE=config_path, ... PYTHONPATH=config_directory), @@ -61,7 +61,6 @@ force the hooks to run. >>> call() pre-hook: 1 - Using GNU Mailman 3... >>> os.remove(config_path) @@ -83,7 +82,6 @@ We can set the post-hook in the configuration file. >>> call() post-hook: 1 - Using GNU Mailman 3... >>> os.remove(config_path) @@ -107,5 +105,4 @@ We can set the pre- and post-hooks in the configuration file. >>> call() pre-hook: 1 post-hook: 2 - Using GNU Mailman 3... -- cgit v1.3.1