------------------------------------------------------------
revno: 6611
committer: Barry Warsaw <[EMAIL PROTECTED]>
branch nick: bin-fixes
timestamp: Sat 2008-03-22 21:43:38 -0400
message:
  Several fixes to command line scripts.
  
  - Add an options base class that groks unicode argument types
  - Rename newlist to create_list
  - Update list_lists, master, qrunner
renamed:
  mailman/bin/newlist.py => mailman/bin/create_list.py
modified:
  mailman/bin/__init__.py
  mailman/bin/list_lists.py
  mailman/bin/master.py
  mailman/bin/qrunner.py
  mailman/options.py
  mailman/bin/create_list.py

=== modified file 'mailman/bin/__init__.py'
--- a/mailman/bin/__init__.py   2008-02-25 05:24:03 +0000
+++ b/mailman/bin/__init__.py   2008-03-23 01:43:38 +0000
@@ -26,6 +26,7 @@
     'cleanarch',
     'config_list',
     'confirm',
+    'create_list',
     'disabled',
     'dumpdb',
     'export',
@@ -43,7 +44,6 @@
     'make_instance',
     'master',
     'mmsitepass',
-    'newlist',
     'nightly_gzip',
     'owner',
     'post',

=== renamed file 'mailman/bin/newlist.py' => 'mailman/bin/create_list.py'
--- a/mailman/bin/newlist.py    2008-02-27 06:26:18 +0000
+++ b/mailman/bin/create_list.py        2008-03-23 01:43:38 +0000
@@ -17,30 +17,24 @@
 
 from __future__ import with_statement
 
-import sha
 import sys
-import getpass
-import datetime
-import optparse
 
 from mailman import Errors
 from mailman import Message
 from mailman import Utils
-from mailman import Version
 from mailman import i18n
 from mailman.app.lifecycle import create_list
 from mailman.configuration import config
-from mailman.initialize import initialize
 from mailman.interfaces import ListAlreadyExistsError
+from mailman.options import SingleMailingListOptions
 
 
 _ = i18n._
 
 
 
-def parseargs():
-    parser = optparse.OptionParser(version=Version.MAILMAN_VERSION,
-                                   usage=_("""\
+class ScriptOptions(SingleMailingListOptions):
+    usage=_("""\
 %prog [options] fqdn_listname
 
 Create a new mailing list.
@@ -49,79 +43,78 @@
 address of the list.  It must be a valid email address and the domain must be
 registered with Mailman.
 
-Note that listnames are forced to lowercase."""))
-    parser.add_option('-l', '--language',
-                      type='string', action='store',
-                      help=_("""\
+Note that listnames are forced to lowercase.""")
+
+    def add_options(self):
+        super(ScriptOptions, self).add_options()
+        self.parser.add_option(
+            '--language',
+            type='unicode', action='store',
+            help=_("""\
 Make the list's preferred language LANGUAGE, which must be a two letter
 language code."""))
-    parser.add_option('-o', '--owner',
-                      type='string', action='append', default=[],
-                      dest='owners', help=_("""\
+        self.parser.add_option(
+            '-o', '--owner',
+            type='unicode', action='append', default=[],
+            dest='owners', help=_("""\
 Specific a listowner email address.  If the address is not currently
 registered with Mailman, the address is registered and linked to a user.
 Mailman will send a confirmation message to the address, but it will also send
 a list creation notice to the address.  More than one owner can be
 specified."""))
-    parser.add_option('-q', '--quiet',
-                      default=False, action='store_true',
-                      help=_("""\
+        self.parser.add_option(
+            '-q', '--quiet',
+            default=False, action='store_true',
+            help=_("""\
 Normally the administrator is notified by email (after a prompt) that their
 list has been created.  This option suppresses the prompt and
 notification."""))
-    parser.add_option('-a', '--automate',
-                      default=False, action='store_true',
-                      help=_("""\
+        self.parser.add_option(
+            '-a', '--automate',
+            default=False, action='store_true',
+            help=_("""\
 This option suppresses the prompt prior to administrator notification but
 still sends the notification.  It can be used to make newlist totally
 non-interactive but still send the notification, assuming at least one list
 owner is specified with the -o option.."""))
-    parser.add_option('-C', '--config',
-                      help=_('Alternative configuration file to use'))
-    opts, args = parser.parse_args()
-    # We can't verify opts.language here because the configuration isn't
-    # loaded yet.
-    return parser, opts, args
+
+    def sanity_check(self):
+        """Set up some defaults we couldn't set up earlier."""
+        if self.options.language is None:
+            self.options.language = config.DEFAULT_SERVER_LANGUAGE
+        # Is the language known?
+        if self.options.language not in config.languages.enabled_codes:
+            self.parser.error(_('Unknown language: $opts.language'))
+        # Handle variable number of positional arguments
+        if len(self.arguments) > 0:
+            parser.error(_('Unexpected arguments'))
 
 
 
 def main():
-    parser, opts, args = parseargs()
-    initialize(opts.config)
-
-    # Set up some defaults we couldn't set up in parseargs()
-    if opts.language is None:
-        opts.language = config.DEFAULT_SERVER_LANGUAGE
-    # Is the language known?
-    if opts.language not in config.languages.enabled_codes:
-        parser.error(_('Unknown language: $opts.language'))
-    # Handle variable number of positional arguments
-    if len(args) == 0:
-        parser.error(_('You must supply a mailing list name'))
-    elif len(args) == 1:
-        fqdn_listname = args[0].lower()
-    elif len(args) > 1:
-        parser.error(_('Unexpected arguments'))
+    options = ScriptOptions()
+    options.initialize()
 
     # Create the mailing list, applying styles as appropriate.
+    fqdn_listname = options.options.listname
     try:
-        mlist = create_list(fqdn_listname, opts.owners)
-        mlist.preferred_language = opts.language
+        mlist = create_list(fqdn_listname, options.options.owners)
+        mlist.preferred_language = options.options.language
     except Errors.InvalidEmailAddress:
-        parser.error(_('Illegal list name: $fqdn_listname'))
+        options.parser.error(_('Illegal list name: $fqdn_listname'))
     except ListAlreadyExistsError:
-        parser.error(_('List already exists: $fqdn_listname'))
+        options.parser.error(_('List already exists: $fqdn_listname'))
     except Errors.BadDomainSpecificationError, domain:
-        parser.error(_('Undefined domain: $domain'))
+        options.parser.error(_('Undefined domain: $domain'))
 
-    config.db.flush()
+    config.db.commit()
 
     # Send notices to the list owners.  XXX This should also be moved to the
     # Mailman.app.create module.
-    if not opts.quiet and not opts.automate:
+    if not options.options.quiet and not options.options.automate:
         print _('Hit enter to notify $fqdn_listname owners...'),
         sys.stdin.readline()
-    if not opts.quiet:
+    if not options.options.quiet:
         d = dict(
             listname        = mlist.fqdn_listname,
             admin_url       = mlist.script_url('admin'),
@@ -136,6 +129,6 @@
         with i18n.using_language(mlist.preferred_language):
             msg = Message.UserNotification(
                 owner_mail, mlist.no_reply_address,
-                _('Your new mailing list: $listname'),
+                _('Your new mailing list: $fqdn_listname'),
                 text, mlist.preferred_language)
             msg.send(mlist)

=== modified file 'mailman/bin/list_lists.py'
--- a/mailman/bin/list_lists.py 2008-02-27 06:26:18 +0000
+++ b/mailman/bin/list_lists.py 2008-03-23 01:43:38 +0000
@@ -15,53 +15,55 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 # USA.
 
-import optparse
-
 from mailman import Defaults
 from mailman import Version
 from mailman.configuration import config
 from mailman.i18n import _
 from mailman.initialize import initialize
+from mailman.options import Options
 
 
 
-def parseargs():
-    parser = optparse.OptionParser(version=Version.MAILMAN_VERSION,
-                                   usage=_("""\
+class ScriptOptions(Options):
+    usage=_("""\
 %prog [options]
 
-List all mailing lists."""))
-    parser.add_option('-a', '--advertised',
-                      default=False, action='store_true',
-                      help=_("""\
+List all mailing lists.""")
+
+    def add_options(self):
+        super(ScriptOptions, self).add_options()
+        self.parser.add_option(
+            '-a', '--advertised',
+            default=False, action='store_true',
+            help=_("""\
 List only those mailing lists that are publicly advertised"""))
-    parser.add_option('-b', '--bare',
-                      default=False, action='store_true',
-                      help=_("""\
+        self.parser.add_option(
+            '-b', '--bare',
+            default=False, action='store_true',
+            help=_("""\
 Displays only the list name, with no description."""))
-    parser.add_option('-d', '--domain',
-                      default=[], type='string', action='append',
-                      dest='domains', help=_("""\
+        self.parser.add_option(
+            '-d', '--domain',
+            default=[], type='string', action='append',
+            dest='domains', help=_("""\
 List only those mailing lists that match the given virtual domain, which may
 be either the email host or the url host name.  Multiple -d options may be
 given."""))
-    parser.add_option('-f', '--full',
-                      default=False, action='store_true',
-                      help=_("""\
+        self.parser.add_option(
+            '-f', '--full',
+            default=False, action='store_true',
+            help=_("""\
 Print the full list name, including the posting address."""))
-    parser.add_option('-C', '--config',
-                      help=_('Alternative configuration file to use'))
-    opts, args = parser.parse_args()
-    if args:
-        parser.print_help()
-        parser.error(_('Unexpected arguments'))
-    return parser, opts, args
+
+    def sanity_check(self):
+        if len(self.arguments) > 0:
+            self.parser.error(_('Unexpected arguments'))
 
 
 
 def main():
-    parser, opts, args = parseargs()
-    initialize(opts.config)
+    options = ScriptOptions()
+    options.initialize()
 
     mlists = []
     longest = 0
@@ -69,36 +71,36 @@
     listmgr = config.db.list_manager
     for fqdn_name in sorted(listmgr.names):
         mlist = listmgr.get(fqdn_name)
-        if opts.advertised and not mlist.advertised:
+        if options.options.advertised and not mlist.advertised:
             continue
-        if opts.domains:
-            for domain in opts.domains:
+        if options.options.domains:
+            for domain in options.options.domains:
                 if domain in mlist.web_page_url or domain == mlist.host_name:
                     mlists.append(mlist)
                     break
         else:
             mlists.append(mlist)
-        if opts.full:
+        if options.options.full:
             name = mlist.fqdn_listname
         else:
             name = mlist.real_name
         longest = max(len(name), longest)
 
-    if not mlists and not opts.bare:
+    if not mlists and not options.options.bare:
         print _('No matching mailing lists found')
         return
 
-    if not opts.bare:
+    if not options.options.bare:
         num_mlists = len(mlists)
         print _('$num_mlists matching mailing lists found:')
 
     format = '%%%ds - %%.%ds' % (longest, 77 - longest)
     for mlist in mlists:
-        if opts.full:
+        if options.options.full:
             name = mlist.fqdn_listname
         else:
             name = mlist.real_name
-        if opts.bare:
+        if options.options.bare:
             print name
         else:
             description = mlist.description or _('[no description available]')

=== modified file 'mailman/bin/master.py'
--- a/mailman/bin/master.py     2008-03-21 17:01:48 +0000
+++ b/mailman/bin/master.py     2008-03-23 01:43:38 +0000
@@ -38,11 +38,9 @@
 from munepy import Enum
 
 from mailman import Defaults
-from mailman import Version
 from mailman import loginit
 from mailman.configuration import config
 from mailman.i18n import _
-from mailman.initialize import initialize
 from mailman.options import Options
 
 
@@ -51,7 +49,7 @@
 
 
 
-class MasterOptions(Options):
+class ScriptOptions(Options):
     """Options for the master watcher."""
 
     usage = _("""\
@@ -405,8 +403,9 @@
 
 def main():
     """Main process."""
-    options = MasterOptions()
-    initialize(options.options.config)
+
+    options = ScriptOptions()
+    options.initialize()
 
     # Acquire the master lock, exiting if we can't acquire it.  We'll let the
     # caller handle any clean up or lock breaking.  No with statement here

=== modified file 'mailman/bin/qrunner.py'
--- a/mailman/bin/qrunner.py    2008-03-21 17:08:04 +0000
+++ b/mailman/bin/qrunner.py    2008-03-23 01:43:38 +0000
@@ -19,11 +19,9 @@
 import signal
 import logging
 
-from mailman import Version
 from mailman import loginit
 from mailman.configuration import config
 from mailman.i18n import _
-from mailman.initialize import initialize
 from mailman.options import Options
 
 
@@ -55,7 +53,7 @@
 
 
 
-class RunnerOptions(Options):
+class ScriptOptions(Options):
 
     usage=_("""\
 Run one or more qrunners, once or repeatedly.
@@ -114,6 +112,10 @@
 mailmanctl startup script.  It changes some of the exit-on-error behavior to
 work better with that framework."""))
 
+    def initialize(self):
+        """Override initialization to propagate logs correctly."""
+        super(ScriptOptions, self).initialize(not self.options.subproc)
+
     def sanity_check(self):
         if self.arguments:
             self.parser.error(_('Unexpected arguments'))
@@ -198,13 +200,8 @@
 def main():
     global log
 
-    options = RunnerOptions()
-    # If we're not running as a subprocess of mailmanctl, then we'll log to
-    # stderr in addition to logging to the log files.  We do this by passing a
-    # value of True to propagate, which allows the 'mailman' root logger to
-    # see the log messages.
-    initialize(options.options.config,
-               propagate_logs=not options.options.subproc)
+    options = ScriptOptions()
+    options.initialize()
 
     if options.options.list:
         prefixlen = max(len(shortname)

=== modified file 'mailman/options.py'
--- a/mailman/options.py        2008-03-21 17:01:48 +0000
+++ b/mailman/options.py        2008-03-23 01:43:38 +0000
@@ -18,14 +18,39 @@
 """Common argument parsing."""
 
 __metaclass__ = type
-__all__ = ['Options']
-
-
-from optparse import OptionParser
+__all__ = [
+    'Options',
+    'SingleMailingListOptions',
+    ]
+
+
+import sys
+
+from copy import copy
+from optparse import Option, OptionParser, OptionValueError
 
 from mailman.Version import MAILMAN_VERSION
 from mailman.configuration import config
 from mailman.i18n import _
+from mailman.initialize import initialize
+
+
+
+def check_unicode(option, opt, value):
+    if isinstance(value, unicode):
+        return value
+    try:
+        return value.decode(sys.getdefaultencoding())
+    except UnicodeDecodeError:
+        raise OptionValueError(
+            "option %s: Cannot decode: %r" % (opt, value))
+
+
+class MailmanOption(Option):
+    """Extension types for unicode options."""
+    TYPES = Option.TYPES + ('unicode',)
+    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
+    TYPE_CHECKER['unicode'] = check_unicode
 
 
 
@@ -36,7 +61,9 @@
     usage = None
 
     def __init__(self):
-        self.parser = OptionParser(version=MAILMAN_VERSION, usage=self.usage)
+        self.parser = OptionParser(version=MAILMAN_VERSION,
+                                   option_class=MailmanOption,
+                                   usage=self.usage)
         self.add_common_options()
         self.add_options()
         options, arguments = self.parser.parse_args()
@@ -45,7 +72,6 @@
         # Also, for convenience, place the options in the configuration file
         # because occasional global uses are necessary.
         config.options = self
-        self.sanity_check()
 
     def add_options(self):
         """Allow the subclass to add its own specific arguments."""
@@ -60,3 +86,28 @@
         self.parser.add_option(
             '-C', '--config',
             help=_('Alternative configuration file to use'))
+
+    def initialize(self, propagate_logs=False):
+        """Initialize the configuration system.
+
+        After initialization of the configuration system, perform sanity
+        checks.  We do it in this order because some sanity checks require the
+        configuration to be initialized.
+
+        :param propagate_logs: Flag specifying whether log messages in
+            sub-loggers should be propagated to the master logger (and hence
+            to the root logger).
+        """
+        initialize(self.options.config, propagate_logs=propagate_logs)
+        self.sanity_check()
+
+
+
+class SingleMailingListOptions(Options):
+    """A helper for specifying the mailing list on the command line."""
+
+    def add_options(self):
+        self.parser.add_option(
+            '-l', '--listname',
+            type='unicode', help=_('The mailing list name'))
+        super(SingleMailingListOptions, self).add_options()



--
Primary development focus
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to