use specifics OptionParser and OptionFormatter to display commands list

This commit is contained in:
Romain Bignon 2010-12-08 17:53:05 +01:00
commit 5dae3e3c92

View file

@ -20,7 +20,7 @@ import atexit
from cmd import Cmd from cmd import Cmd
import getpass import getpass
import logging import logging
from optparse import OptionGroup from optparse import OptionGroup, OptionParser, IndentedHelpFormatter
import os import os
import sys import sys
from copy import deepcopy from copy import deepcopy
@ -34,6 +34,7 @@ from weboob.tools.application.formatters.iformatter import MandatoryFieldsNotFou
from weboob.tools.browser import BrowserUnavailable, BrowserIncorrectPassword from weboob.tools.browser import BrowserUnavailable, BrowserIncorrectPassword
from weboob.tools.value import Value, ValueBool, ValueFloat, ValueInt from weboob.tools.value import Value, ValueBool, ValueFloat, ValueInt
from weboob.tools.misc import to_unicode from weboob.tools.misc import to_unicode
from weboob.tools.ordereddict import OrderedDict
from .base import BackendNotFound, BaseApplication from .base import BackendNotFound, BaseApplication
from .formatters.load import FormattersLoader, FormatterLoadError from .formatters.load import FormattersLoader, FormatterLoadError
@ -46,6 +47,26 @@ __all__ = ['ReplApplication', 'NotEnoughArguments']
class NotEnoughArguments(Exception): class NotEnoughArguments(Exception):
pass pass
class ReplOptionParser(OptionParser):
def format_option_help(self, formatter=None):
if not formatter:
formatter = self.formatter
return '%s\n%s' % (formatter.format_commands(self.commands),
OptionParser.format_option_help(self, formatter))
class ReplOptionFormatter(IndentedHelpFormatter):
def format_commands(self, commands):
s = u''
for section, cmds in commands.iteritems():
if len(s) > 0:
s += '\n'
s += '%s Commands:\n' % section
for c in cmds:
c = c.split('\n')[0]
s += ' %s\n' % c
return s
class ReplApplication(Cmd, BaseApplication): class ReplApplication(Cmd, BaseApplication):
""" """
Base application class for CLI applications. Base application class for CLI applications.
@ -93,24 +114,14 @@ class ReplApplication(Cmd, BaseApplication):
self.commands_formatters = self.COMMANDS_FORMATTERS.copy() self.commands_formatters = self.COMMANDS_FORMATTERS.copy()
try: try:
BaseApplication.__init__(self) BaseApplication.__init__(self, ReplOptionParser(self.SYNOPSIS, version=self._get_optparse_version()))
except BackendsConfig.WrongPermissions, e: except BackendsConfig.WrongPermissions, e:
print e print e
sys.exit(1) sys.exit(1)
self._parser.format_description = lambda x: self._parser.description commands_help = self.get_commands_doc()
self._parser.commands = commands_help
if self._parser.description is None: self._parser.formatter = ReplOptionFormatter()
self._parser.description = ''
help_str = u''
app_cmds, weboob_cmds, undoc_cmds = self.get_commands_doc()
if len(app_cmds) > 0 or len(undoc_cmds) > 0:
help_str += '%s Commands:\n%s\n\n' % (self.APPNAME.capitalize(), '\n'.join(' %s' % cmd for cmd in sorted(app_cmds + undoc_cmds)))
if not self.DISABLE_REPL:
help_str +='Weboob Commands:\n%s\n' % '\n'.join(' %s' % cmd for cmd in weboob_cmds)
self._parser.description += help_str
results_options = OptionGroup(self._parser, 'Results Options') results_options = OptionGroup(self._parser, 'Results Options')
results_options.add_option('-c', '--condition', help='filter result items to display given a boolean expression') results_options.add_option('-c', '--condition', help='filter result items to display given a boolean expression')
@ -516,37 +527,32 @@ class ReplApplication(Cmd, BaseApplication):
print print
return self.do_quit(arg) return self.do_quit(arg)
def get_command_help(self, command, short=False): def get_command_help(self, command):
try: try:
doc = getattr(self, 'do_' + command).__doc__ doc = getattr(self, 'do_' + command).__doc__
except AttributeError: except AttributeError:
return None return None
if doc: if doc:
doc = '\n'.join(line.strip() for line in doc.strip().split('\n')) doc = '\n'.join(line.strip() for line in doc.strip().split('\n'))
if short:
doc = doc.split('\n')[0]
if not doc.startswith(command):
doc = command
return doc return doc
def get_commands_doc(self): def get_commands_doc(self):
names = set(name for name in self.get_names() if name.startswith('do_')) names = set(name for name in self.get_names() if name.startswith('do_'))
application_cmds_doc = [] appname = self.APPNAME.capitalize()
weboob_cmds_doc = [] d = OrderedDict(((appname, []), ('Weboob', [])))
cmds_undoc = []
for name in sorted(names): for name in sorted(names):
cmd = name[3:] cmd = name[3:]
if cmd in self.hidden_commands.union(self.weboob_commands).union(['help']): if cmd in self.hidden_commands.union(self.weboob_commands).union(['help']):
continue continue
elif getattr(self, name).__doc__: elif getattr(self, name).__doc__:
short_help = ' %s' % self.get_command_help(cmd, short=True) d[appname].append(self.get_command_help(cmd))
application_cmds_doc.append(short_help)
else: else:
cmds_undoc.append(cmd) d[appname].append(cmd)
for cmd in self.weboob_commands: for cmd in self.weboob_commands:
short_help = ' %s' % self.get_command_help(cmd, short=True) d['Weboob'].append(self.get_command_help(cmd))
weboob_cmds_doc.append(short_help)
return application_cmds_doc, weboob_cmds_doc, cmds_undoc return d
def do_help(self, arg=None): def do_help(self, arg=None):
if arg: if arg:
@ -560,15 +566,8 @@ class ReplApplication(Cmd, BaseApplication):
else: else:
print 'Unknown command: "%s"' % arg print 'Unknown command: "%s"' % arg
else: else:
application_cmds_doc, weboob_cmds_doc, undoc_cmds_doc = self.get_commands_doc() cmds = self._parser.formatter.format_commands(self._parser.commands)
self.stdout.write('%s\n' % cmds)
application_cmds_header = '%s commands' % self.APPNAME.capitalize()
self.stdout.write('%s\n%s\n' % (application_cmds_header, '-' * len(application_cmds_header)))
self.stdout.write('\n'.join(application_cmds_doc) + '\n\n')
weboob_cmds_header = 'Generic Weboob commands'
self.stdout.write('%s\n%s\n' % (weboob_cmds_header, '-' * len(weboob_cmds_header)))
self.stdout.write('\n'.join(weboob_cmds_doc) + '\n\n')
self.print_topics(self.undoc_header, undoc_cmds_doc, 15,80)
self.stdout.write('Type "help <command>" for more info about a command.\n') self.stdout.write('Type "help <command>" for more info about a command.\n')
def emptyline(self): def emptyline(self):