------------------------------------------------------------
revno: 6794
committer: Barry Warsaw <[email protected]>
branch nick: 3.0
timestamp: Sat 2009-09-19 16:51:15 -0400
message:
  Convert bin/inject to bin/mailman inject
  
  Expose the database store on .store instead of ._store
  
  A few other cleanups.
removed:
  src/mailman/bin/inject.py
added:
  src/mailman/commands/cli_inject.py
  src/mailman/commands/docs/inject.txt
modified:
  src/mailman/commands/docs/echo.txt
  src/mailman/commands/docs/end.txt
  src/mailman/commands/docs/join.txt
  src/mailman/commands/docs/lists.txt
  src/mailman/commands/docs/members.txt
  src/mailman/commands/docs/remove.txt
  src/mailman/database/__init__.py
  src/mailman/database/listmanager.py
  src/mailman/database/mailinglist.py
  src/mailman/docs/listmanager.txt
  src/mailman/queue/docs/incoming.txt


--
lp:mailman
https://code.launchpad.net/~mailman-coders/mailman/3.0

Your team Mailman Checkins is subscribed to branch lp:mailman.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+edit-subscription.
=== removed file 'src/mailman/bin/inject.py'
--- src/mailman/bin/inject.py	2009-08-26 06:27:37 +0000
+++ src/mailman/bin/inject.py	1970-01-01 00:00:00 +0000
@@ -1,91 +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 <http://www.gnu.org/licenses/>.
-
-import os
-import sys
-
-from email import message_from_string
-from zope.component import getUtility
-
-from mailman import Utils
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.inject import inject_text
-from mailman.interfaces.listmanager import IListManager
-from mailman.message import Message
-from mailman.options import SingleMailingListOptions
-
-
-
-class ScriptOptions(SingleMailingListOptions):
-    usage=_("""\
-%prog [options] [filename]
-
-Inject a message from a file into Mailman's incoming queue.  'filename' is the
-name of the plaintext message file to inject.  If omitted, or the string '-',
-standard input is used.
-""")
-
-    def add_options(self):
-        super(ScriptOptions, self).add_options()
-        self.parser.add_option(
-            '-q', '--queue',
-            type='string', help=_("""\
-The name of the queue to inject the message to.  The queuename must be one of
-the directories inside the qfiles directory.  If omitted, the incoming queue
-is used."""))
-
-    def sanity_check(self):
-        if not self.options.listname:
-            self.parser.error(_('Missing listname'))
-        if len(self.arguments) == 0:
-            self.filename = '-'
-        elif len(self.arguments) > 1:
-            self.parser.print_error(_('Unexpected arguments'))
-        else:
-            self.filename = self.arguments[0]
-
-
-
-def main():
-    options = ScriptOptions()
-    options.initialize()
-
-    if options.options.queue is None:
-        qdir = config.INQUEUE_DIR
-    else:
-        qdir = os.path.join(config.QUEUE_DIR, options.options.queue)
-        if not os.path.isdir(qdir):
-            options.parser.error(_('Bad queue directory: $qdir'))
-
-    fqdn_listname = options.options.listname
-    mlist = getUtility(IListManager).get(fqdn_listname)
-    if mlist is None:
-        options.parser.error(_('No such list: $fqdn_listname'))
-
-    if options.filename == '-':
-        message_text = sys.stdin.read()
-    else:
-        with open(options.filename) as fp:
-            message_text = fp.read()
-
-    inject_text(mlist, message_text, qdir=qdir)
-
-
-
-if __name__ == '__main__':
-    main()

=== added file 'src/mailman/commands/cli_inject.py'
--- src/mailman/commands/cli_inject.py	1970-01-01 00:00:00 +0000
+++ src/mailman/commands/cli_inject.py	2009-09-19 20:51:15 +0000
@@ -0,0 +1,104 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+"""Module stuff."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+    'Inject',
+    ]
+
+
+import sys
+
+from zope.component import getUtility
+from zope.interface import implements
+
+from mailman.config import config
+from mailman.i18n import _
+from mailman.inject import inject_text
+from mailman.interfaces.command import ICLISubCommand
+from mailman.interfaces.listmanager import IListManager
+
+
+
+class Inject:
+    """Inject a message from a file into a mailing list's queue."""
+
+    implements(ICLISubCommand)
+
+    name = 'inject'
+
+    def add(self, parser, command_parser):
+        """See `ICLISubCommand`."""
+        self.parser = parser
+        command_parser.add_argument(
+            '-q', '--queue',
+            type=unicode, help=_("""\
+            The name of the queue to inject the message to.  QUEUE must be one
+            of the directories inside the qfiles directory.  If omitted, the
+            incoming queue is used."""))
+        command_parser.add_argument(
+            '-s', '--show',
+            action='store_true', default=False,
+            help=_('Show a list of all available queue names and exit.'))
+        command_parser.add_argument(
+            '-f', '--filename',
+            type='string', help=_("""
+            Name of file containing the message to inject.  If not given, or
+            '-' (without the quotes) standard input is used.
+            """))
+        # Required positional argument.
+        command_parser.add_argument(
+            'listname', metavar='LISTNAME', nargs='?',
+            help=_("""\
+            The 'fully qualified list name', i.e. the posting address of the
+            mailing list to inject the message into."""))
+
+    def process(self, args):
+        """See `ICLISubCommand`."""
+        # Process --show first; if given, print output and exit, ignoring all
+        # other command line switches.
+        if args.show:
+            print 'Available queues:'
+            for switchboard in sorted(config.switchboards):
+                print '   ', switchboard
+            return
+        # Could be None or sequence of length 0.
+        if args.listname is None:
+            self.parser.error(_('List name is required'))
+            return
+        assert len(args.listname) == 1, (
+            'Unexpected positional arguments: %s' % args.listname)
+        fqdn_listname = args.listname[0]
+        mlist = getUtility(IListManager).get(fqdn_listname)
+        if mlist is None:
+            self.parser.error(_('No such list: $fqdn_listname'))
+            return
+        queue = ('in' if args.queue is None else args.queue)
+        switchboard = config.switchboards.get(queue)
+        if switchboard is None:
+            self.parser.error(_('No such queue: $queue'))
+            return
+        if args.filename in (None, '-'):
+            message_text = sys.stdin.read()
+        else:
+            with open(args.filename) as fp:
+                message_text = fp.read()
+        inject_text(mlist, message_text, switchboard=queue)

=== modified file 'src/mailman/commands/docs/echo.txt'
--- src/mailman/commands/docs/echo.txt	2009-07-17 05:16:27 +0000
+++ src/mailman/commands/docs/echo.txt	2009-09-19 20:51:15 +0000
@@ -14,7 +14,6 @@
 
 The original message is ignored, but the results receive the echoed command.
 
-    >>> from mailman.app.lifecycle import create_list
     >>> mlist = create_list('[email protected]')
 
     >>> from mailman.queue.command import Results

=== modified file 'src/mailman/commands/docs/end.txt'
--- src/mailman/commands/docs/end.txt	2009-07-17 05:16:27 +0000
+++ src/mailman/commands/docs/end.txt	2009-09-19 20:51:15 +0000
@@ -18,7 +18,6 @@
 The command itself is fairly simple; it just stops command processing, and the
 message isn't even looked at.
 
-    >>> from mailman.app.lifecycle import create_list
     >>> mlist = create_list('[email protected]')
     >>> from mailman.email.message import Message
     >>> print command.process(mlist, Message(), {}, (), None)

=== added file 'src/mailman/commands/docs/inject.txt'
--- src/mailman/commands/docs/inject.txt	1970-01-01 00:00:00 +0000
+++ src/mailman/commands/docs/inject.txt	2009-09-19 20:51:15 +0000
@@ -0,0 +1,193 @@
+==============================
+Command line message injection
+==============================
+
+You can inject a message directly into a queue directory via the command
+line.
+
+    >>> from mailman.commands.cli_inject import Inject
+    >>> command = Inject()
+
+    >>> class FakeArgs:
+    ...     queue = None
+    ...     show = False
+    ...     filename = None
+    ...     listname = None
+    >>> args = FakeArgs()
+
+    >>> class FakeParser:
+    ...     def error(self, message):
+    ...         print message
+    >>> command.parser = FakeParser()
+
+It's easy to find out which queues are available.
+
+    >>> args.show = True
+    >>> command.process(args)
+    Available queues:
+        archive
+        bad
+        bounces
+        command
+        digest
+        in
+        lmtp
+        maildir
+        news
+        out
+        pipeline
+        rest
+        retry
+        shunt
+        virgin
+
+    >>> args.show = False
+
+Usually, the text of the message to inject is in a file.
+
+    >>> import os, tempfile
+    >>> fd, filename = tempfile.mkstemp()
+    >>> with os.fdopen(fd, 'w') as fp:
+    ...     print >> fp, """\
+    ... From: [email protected]
+    ... To: [email protected]
+    ... Subject: testing
+    ...
+    ... This is a test message.
+    ... """
+
+However, the mailing list name is always required.
+
+    >>> args.filename = filename
+    >>> command.process(args)
+    List name is required
+
+Let's provide a list name and try again.
+
+    >>> mlist = create_list('[email protected]')
+    >>> transaction.commit()
+
+    >>> in_queue = config.switchboards['in']
+    >>> len(in_queue.files)
+    0
+    >>> args.listname = ['[email protected]']
+    >>> command.process(args)
+
+By default, the incoming queue is used.
+
+    >>> len(in_queue.files)
+    1
+
+    >>> from mailman.testing.helpers import get_queue_messages
+    >>> item = get_queue_messages('in')[0]
+    >>> print item.msg.as_string()
+    From: [email protected]
+    To: [email protected]
+    Subject: testing
+    Message-ID: ...
+    Date: ...
+    <BLANKLINE>
+    This is a test message.
+    <BLANKLINE>
+    <BLANKLINE>
+
+    >>> dump_msgdata(item.msgdata)
+    _parsemsg    : False
+    listname     : [email protected]
+    original_size: 90
+    version      : 3
+
+But a different queue can be specified on the command line.
+
+    >>> args.queue = 'virgin'
+    >>> command.process(args)
+
+    >>> len(in_queue.files)
+    0
+    >>> virgin_queue = config.switchboards['virgin']
+    >>> len(virgin_queue.files)
+    1
+    >>> item = get_queue_messages('virgin')[0]
+    >>> print item.msg.as_string()
+    From: [email protected]
+    To: [email protected]
+    Subject: testing
+    Message-ID: ...
+    Date: ...
+    <BLANKLINE>
+    This is a test message.
+    <BLANKLINE>
+    <BLANKLINE>
+
+    >>> dump_msgdata(item.msgdata)
+    _parsemsg    : False
+    listname     : [email protected]
+    original_size: 90
+    version      : 3
+
+    # Clean up the tempfile.
+    >>> os.remove(filename)
+
+
+Standard input
+==============
+
+The message text can also be provided on standard input.
+
+    >>> from StringIO import StringIO
+
+    # Remember: we've got unicode literals turned on.
+    >>> standard_in = StringIO(str("""\
+    ... From: [email protected]
+    ... To: [email protected]
+    ... Subject: another test
+    ...
+    ... This is another test message.
+    ... """))
+
+    >>> import sys
+    >>> sys.stdin = standard_in
+    >>> args.filename = '-'
+    >>> args.queue = None
+
+    >>> command.process(args)
+    >>> len(in_queue.files)
+    1
+    >>> item = get_queue_messages('in')[0]
+    >>> print item.msg.as_string()
+    From: [email protected]
+    To: [email protected]
+    Subject: another test
+    Message-ID: ...
+    Date: ...
+    <BLANKLINE>
+    This is another test message.
+    <BLANKLINE>
+    <BLANKLINE>
+
+    >>> dump_msgdata(item.msgdata)
+    _parsemsg    : False
+    listname     : [email protected]
+    original_size: 100
+    version      : 3
+    
+    # Clean up.
+    >>> sys.stdin = sys.__stdin__
+    >>> args.filename = filename
+
+
+Errors
+======
+
+It is an error to specify a queue that doesn't exist.
+
+    >>> args.queue = 'xxbogusxx'
+    >>> command.process(args)
+    No such queue: xxbogusxx
+
+It is also an error to specify a mailing list that doesn't exist.
+
+    >>> args.queue = None
+    >>> args.listname = ['bogus']
+    >>> command.process(args)
+    No such list: bogus

=== modified file 'src/mailman/commands/docs/join.txt'
--- src/mailman/commands/docs/join.txt	2009-08-26 14:51:52 +0000
+++ src/mailman/commands/docs/join.txt	2009-09-19 20:51:15 +0000
@@ -26,7 +26,6 @@
 ------------------
 
     >>> from mailman.email.message import Message
-    >>> from mailman.app.lifecycle import create_list
     >>> from mailman.queue.command import Results
     >>> mlist = create_list('[email protected]')
 

=== modified file 'src/mailman/commands/docs/lists.txt'
--- src/mailman/commands/docs/lists.txt	2009-08-09 15:01:16 +0000
+++ src/mailman/commands/docs/lists.txt	2009-09-19 20:51:15 +0000
@@ -25,7 +25,6 @@
     >>> domain_mgr.add('example.net')
     <Domain example.net...>
 
-    >>> from mailman.app.lifecycle import create_list
     >>> mlist_1 = create_list('[email protected]')
     >>> mlist_1.description = 'List One'
 

=== modified file 'src/mailman/commands/docs/members.txt'
--- src/mailman/commands/docs/members.txt	2009-08-17 02:44:01 +0000
+++ src/mailman/commands/docs/members.txt	2009-09-19 20:51:15 +0000
@@ -4,7 +4,6 @@
 
 You can add members to a mailing list from the command line.
 
-    >>> from mailman.app.lifecycle import create_list
     >>> mlist = create_list('[email protected]')
 
     >>> class FakeArgs:

=== modified file 'src/mailman/commands/docs/remove.txt'
--- src/mailman/commands/docs/remove.txt	2009-08-26 06:27:37 +0000
+++ src/mailman/commands/docs/remove.txt	2009-09-19 20:51:15 +0000
@@ -4,7 +4,6 @@
 
 A system administrator can remove mailing lists by the command line.
 
-    >>> from mailman.app.lifecycle import create_list
     >>> create_list('[email protected]')
     <mailing list "[email protected]" at ...>
 
@@ -31,7 +30,6 @@
 
 You can also remove lists quietly.
 
-    >>> from mailman.app.lifecycle import create_list
     >>> create_list('[email protected]')
     <mailing list "[email protected]" at ...>
 
@@ -47,7 +45,6 @@
 
 By default 'mailman remove' does not remove a mailing list's archives.
 
-    >>> from mailman.app.lifecycle import create_list
     >>> create_list('[email protected]')
     <mailing list "[email protected]" at ...>
 

=== modified file 'src/mailman/database/__init__.py'
--- src/mailman/database/__init__.py	2009-08-27 02:44:22 +0000
+++ src/mailman/database/__init__.py	2009-09-19 20:51:15 +0000
@@ -54,7 +54,7 @@
 
     def __init__(self):
         self.url = None
-        self._store = None
+        self.store = None
 
     def initialize(self, debug=None):
         """See `IDatabase`."""

=== modified file 'src/mailman/database/listmanager.py'
--- src/mailman/database/listmanager.py	2009-08-26 06:27:37 +0000
+++ src/mailman/database/listmanager.py	2009-09-19 20:51:15 +0000
@@ -30,6 +30,7 @@
 from zope.interface import implements
 
 from mailman.config import config
+from mailman.core.errors import InvalidEmailAddress
 from mailman.database.mailinglist import MailingList
 from mailman.interfaces.listmanager import IListManager, ListAlreadyExistsError
 from mailman.interfaces.rest import IResolvePathNames
@@ -44,7 +45,9 @@
     # pylint: disable-msg=R0201
     def create(self, fqdn_listname):
         """See `IListManager`."""
-        listname, hostname = fqdn_listname.split('@', 1)
+        listname, at, hostname = fqdn_listname.partition('@')
+        if len(hostname) == 0:
+            raise InvalidEmailAddress(fqdn_listname)
         mlist = config.db.store.find(
             MailingList,
             MailingList.list_name == listname,
@@ -58,7 +61,7 @@
 
     def get(self, fqdn_listname):
         """See `IListManager`."""
-        listname, hostname = fqdn_listname.split('@', 1)
+        listname, at, hostname = fqdn_listname.partition('@')
         mlist = config.db.store.find(MailingList,
                                      list_name=listname,
                                      host_name=hostname).one()

=== modified file 'src/mailman/database/mailinglist.py'
--- src/mailman/database/mailinglist.py	2009-07-17 02:36:06 +0000
+++ src/mailman/database/mailinglist.py	2009-09-19 20:51:15 +0000
@@ -178,7 +178,8 @@
 
     def __init__(self, fqdn_listname):
         super(MailingList, self).__init__()
-        listname, hostname = fqdn_listname.split('@', 1)
+        listname, at, hostname = fqdn_listname.partition('@')
+        assert hostname, 'Bad list name: {0}'.format(fqdn_listname)
         self.list_name = listname
         self.host_name = hostname
         # For the pending database

=== modified file 'src/mailman/docs/listmanager.txt'
--- src/mailman/docs/listmanager.txt	2009-08-26 06:27:37 +0000
+++ src/mailman/docs/listmanager.txt	2009-09-19 20:51:15 +0000
@@ -36,11 +36,19 @@
 If you try to create a mailing list with the same name as an existing list,
 you will get an exception.
 
-    >>> mlist_dup = list_manager.create('[email protected]')
+    >>> list_manager.create('[email protected]')
     Traceback (most recent call last):
     ...
     ListAlreadyExistsError: [email protected]
 
+It is an error to create a mailing list that isn't a fully qualified list name
+(i.e. posting address).
+
+    >>> list_manager.create('foo')
+    Traceback (most recent call last):
+    ...
+    InvalidEmailAddress: foo
+
 
 Deleting a mailing list
 =======================
@@ -73,6 +81,11 @@
     >>> print list_manager.get('[email protected]')
     None
 
+You also get None if the list name is invalid.
+
+    >>> print list_manager.get('foo')
+    None
+
 
 Iterating over all mailing lists
 ================================

=== modified file 'src/mailman/queue/docs/incoming.txt'
--- src/mailman/queue/docs/incoming.txt	2009-07-19 02:31:45 +0000
+++ src/mailman/queue/docs/incoming.txt	2009-09-19 20:51:15 +0000
@@ -12,7 +12,6 @@
 message eventually ending up in one of the four disposition states described
 above.
 
-    >>> from mailman.app.lifecycle import create_list
     >>> mlist = create_list('[email protected]')
     >>> print mlist.start_chain
     built-in

_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to