diff --git a/weboob/frontends/boobank/scripts/boobank b/weboob/frontends/boobank/scripts/boobank index 21e18446303cb74d4651078a65c8c955f96d0f57..70c7bd7b9067132625a7b0a889f2d70b21c4c322 100755 --- a/weboob/frontends/boobank/scripts/boobank +++ b/weboob/frontends/boobank/scripts/boobank @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +# vim: ft=python et softtabstop=4 cinoptions=4 shiftwidth=4 ts=4 ai """ Copyright(C) 2009-2010 Romain Bignon @@ -33,44 +34,9 @@ class Boobank(ConsoleApplication): def main(self, argv): self.weboob.load_backends(ICapBank) - if len(argv) == 1: - print >>sys.stderr, "Usage: %s [args ...]" % argv[0] - return -1 - - return self.command(argv[1], *argv[2:]) - - def getMethods(self, prefix): - services = {} - for attrname in dir(self): - if not attrname.startswith(prefix): - continue - attr = getattr(self, attrname) - if not isinstance(attr, MethodType): - continue - name = attrname[len(prefix):] - services[name] = attr - return services - - def command(self, command, *args): - commands = self.getMethods('command_') - if not command in commands: - print >>sys.stderr, "No such command: %s" % command - self.command_help() - return 1 - try: - return commands[command](*args) - except TypeError, e: - try: - print >>sys.stderr, "Command %s takes %s arguments" % (command, int(str(e).split(' ')[3]) - 1) - except: - print >>sys.stderr, '%s' % e - return 1 - - def command_help(self): - print 'Available commands are:' - print ' list List every available accounts' - print ' coming Display all future operations' + return self.process_command(*argv[1:]) + @ConsoleApplication.command('List every available accounts') def command_list(self): print ' ID Account Balance Coming ' print '+-----------------+---------------------+--------------+-------------+' @@ -82,6 +48,7 @@ class Boobank(ConsoleApplication): account.balance, account.coming) + @ConsoleApplication.command('Display all future operations') def command_coming(self, id): found = 0 for name, backend in self.weboob.iter_backends(): diff --git a/weboob/frontends/travel/application.py b/weboob/frontends/travel/application.py index 94efac5fce653032586b814f20f85732365d1829..77b1808360a50c6f2433c7bf40d0a1bc98836a74 100644 --- a/weboob/frontends/travel/application.py +++ b/weboob/frontends/travel/application.py @@ -30,44 +30,9 @@ class Travel(ConsoleApplication): def main(self, argv): self.weboob.load_modules(ICapTravel) - if len(argv) == 1: - print >>sys.stderr, "Usage: %s [args ...]" % argv[0] - return -1 - - return self.command(argv[1], *argv[2:]) - - def getMethods(self, prefix): - services = {} - for attrname in dir(self): - if not attrname.startswith(prefix): - continue - attr = getattr(self, attrname) - if not isinstance(attr, MethodType): - continue - name = attrname[len(prefix):] - services[name] = attr - return services - - def command(self, command, *args): - commands = self.getMethods('command_') - if not command in commands: - print >>sys.stderr, "No such command: %s" % command - self.command_help() - return 1 - try: - return commands[command](*args) - except TypeError, e: - try: - print >>sys.stderr, "Command %s takes %s arguments" % (command, int(str(e).split(' ')[3]) - 1) - except: - print >>sys.stderr, '%s' % e - return 1 - - def command_help(self): - print 'Available commands are:' - print ' stations Search stations' - print ' departures [arrival] List all departures on a special station' + return self.process_command(*argv[1:]) + @ConsoleApplication.command('Search stations') def command_stations(self, pattern): print ".--------------------------------.---------------------------------------------." print '| ID | Name |' @@ -81,13 +46,14 @@ def command_stations(self, pattern): print "| %3d stations listed |" % count print "'------------------------------------------------------------------------------'" - def command_departures(self, station, arrival_station=None): + @ConsoleApplication.command('List all departures on a special station') + def command_departures(self, station, arrival=None): print ".-----.-----------.-------.-----------------------.-------.--------------------." print "| ID | Type | Time | Arrival | Late | Info |" print "+-----+-----------+-------+-----------------------+-------+--------------------+" count = 0 for name, backend, in self.weboob.iter_backends(): - for departure in backend.iter_station_departures(station, arrival_station): + for departure in backend.iter_station_departures(station, arrival): print u"| %3d | %-9s | %5s | %-21s | %5s | %-18s |" % (departure.id, departure.type, departure.time.strftime("%H:%M"), diff --git a/weboob/tools/application.py b/weboob/tools/application.py index 459ca109741f946c05da22f8e763eeff264f90bf..38840e58a7ddad9a9f9e8041dca55f67b9d6b1b0 100644 --- a/weboob/tools/application.py +++ b/weboob/tools/application.py @@ -20,6 +20,8 @@ import sys, tty, termios, os import re +from functools import partial +from inspect import getargspec from weboob import Weboob @@ -102,3 +104,64 @@ def ask(self, question, default=None, masked=False, regexp=None): correct = not regexp or re.match(regexp, str(line)) return line + + def process_command(self, command='help', *args): + def f(x): + return x.startswith('command_' + command) + + matching_commands = filter(f, dir(self)) + + if len(matching_commands) == 0: + sys.stderr.write("No such command: %s.\n" % command) + elif len(matching_commands) == 1: + try: + getattr(self, matching_commands[0])(*args) + except TypeError, e: + try: + sys.stderr.write("Command '%s' takes %s arguments.\n" % \ + (command, int(str(e).split(' ')[3]) - 1)) + except: + sys.stderr.write('%s\n' % e) + else: + sys.stderr.write("Ambiguious command %s: %s.\n" % + (command, + ', '.join([s.replace('command_', '', 1) + for s in matching_commands]))) + + + _command_help = [] + def register_command(f, doc_string, register_to=_command_help): + def getArguments(func, skip=0): + """ + Get arguments of a function as a string. + skip is the number of skipped arguments. + """ + skip += 1 + args, varargs, varkw, defaults = getargspec(func) + cut = len(args) + if defaults: + cut -= len(defaults) + args = ["<%s>" % a for a in args[skip:cut]] + \ + ["[%s]" % a for a in args[cut:]] + if varargs: + args.append("[*%s]" % varargs) + if varkw: + args.append("[**%s]" % varkw) + return " ".join(args) + + command = '%s %s' % (f.func_name.replace('command_', ''), + getArguments(f)) + register_to.append('%-30s %s' % (command, doc_string)) + return f + + def command(doc_string, f=register_command): + return partial(f, doc_string=doc_string) + + @command("display this notice") + def command_help(self): + sys.stdout.write("Available commands:\n") + for f in self._command_help: + sys.stdout.write(' %s\n' % f) + + register_command = staticmethod(register_command) + command = staticmethod(command)