diff --git a/weboob/tools/application/repl.py b/weboob/tools/application/repl.py index 1a8fb039..aa024b5d 100644 --- a/weboob/tools/application/repl.py +++ b/weboob/tools/application/repl.py @@ -20,7 +20,7 @@ import atexit from cmd import Cmd import getpass import logging -from optparse import OptionGroup +from optparse import OptionGroup, OptionParser, IndentedHelpFormatter import os import sys 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.value import Value, ValueBool, ValueFloat, ValueInt from weboob.tools.misc import to_unicode +from weboob.tools.ordereddict import OrderedDict from .base import BackendNotFound, BaseApplication from .formatters.load import FormattersLoader, FormatterLoadError @@ -46,6 +47,26 @@ __all__ = ['ReplApplication', 'NotEnoughArguments'] class NotEnoughArguments(Exception): 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): """ Base application class for CLI applications. @@ -93,24 +114,14 @@ class ReplApplication(Cmd, BaseApplication): self.commands_formatters = self.COMMANDS_FORMATTERS.copy() try: - BaseApplication.__init__(self) + BaseApplication.__init__(self, ReplOptionParser(self.SYNOPSIS, version=self._get_optparse_version())) except BackendsConfig.WrongPermissions, e: print e sys.exit(1) - self._parser.format_description = lambda x: self._parser.description - - if self._parser.description is None: - 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 + commands_help = self.get_commands_doc() + self._parser.commands = commands_help + self._parser.formatter = ReplOptionFormatter() results_options = OptionGroup(self._parser, 'Results Options') 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 return self.do_quit(arg) - def get_command_help(self, command, short=False): + def get_command_help(self, command): try: doc = getattr(self, 'do_' + command).__doc__ except AttributeError: return None if doc: 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 def get_commands_doc(self): names = set(name for name in self.get_names() if name.startswith('do_')) - application_cmds_doc = [] - weboob_cmds_doc = [] - cmds_undoc = [] + appname = self.APPNAME.capitalize() + d = OrderedDict(((appname, []), ('Weboob', []))) + for name in sorted(names): cmd = name[3:] if cmd in self.hidden_commands.union(self.weboob_commands).union(['help']): continue elif getattr(self, name).__doc__: - short_help = ' %s' % self.get_command_help(cmd, short=True) - application_cmds_doc.append(short_help) + d[appname].append(self.get_command_help(cmd)) else: - cmds_undoc.append(cmd) + d[appname].append(cmd) for cmd in self.weboob_commands: - short_help = ' %s' % self.get_command_help(cmd, short=True) - weboob_cmds_doc.append(short_help) - return application_cmds_doc, weboob_cmds_doc, cmds_undoc + d['Weboob'].append(self.get_command_help(cmd)) + + return d def do_help(self, arg=None): if arg: @@ -560,15 +566,8 @@ class ReplApplication(Cmd, BaseApplication): else: print 'Unknown command: "%s"' % arg else: - application_cmds_doc, weboob_cmds_doc, undoc_cmds_doc = self.get_commands_doc() - - 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) + cmds = self._parser.formatter.format_commands(self._parser.commands) + self.stdout.write('%s\n' % cmds) self.stdout.write('Type "help " for more info about a command.\n') def emptyline(self):