From 7b2295cf6c035b29ce702bc60726b01ea1ffbd10 Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Tue, 6 Apr 2010 22:53:07 +0200 Subject: [PATCH] new frontend 'weboobcfg' --- weboob/frontends/boobank/__init__.py | 0 weboob/frontends/monboob/__init__.py | 0 weboob/frontends/travel/application.py | 4 +- weboob/frontends/weboobcfg/__init__.py | 21 ++++ weboob/frontends/weboobcfg/application.py | 108 +++++++++++++++++++ weboob/frontends/weboobcfg/scripts/weboobcfg | 26 +++++ weboob/modules.py | 15 +-- weboob/tools/application.py | 2 +- weboob/tools/misc.py | 40 ------- 9 files changed, 167 insertions(+), 49 deletions(-) create mode 100644 weboob/frontends/boobank/__init__.py create mode 100644 weboob/frontends/monboob/__init__.py create mode 100644 weboob/frontends/weboobcfg/__init__.py create mode 100644 weboob/frontends/weboobcfg/application.py create mode 100755 weboob/frontends/weboobcfg/scripts/weboobcfg diff --git a/weboob/frontends/boobank/__init__.py b/weboob/frontends/boobank/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/weboob/frontends/monboob/__init__.py b/weboob/frontends/monboob/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/weboob/frontends/travel/application.py b/weboob/frontends/travel/application.py index 77b1808360..abaa019eee 100644 --- a/weboob/frontends/travel/application.py +++ b/weboob/frontends/travel/application.py @@ -40,7 +40,7 @@ def command_stations(self, pattern): count = 0 for name, backend, in self.weboob.iter_backends(): for station in backend.iter_station_search(pattern): - print '| %-30s | %-43s |' % (station.id, station.name) + print '| %-31s| %-44s|' % (station.id, station.name) count += 1 print "+--------------------------------'---------------------------------------------+" print "| %3d stations listed |" % count @@ -54,7 +54,7 @@ def command_departures(self, station, arrival=None): count = 0 for name, backend, in self.weboob.iter_backends(): for departure in backend.iter_station_departures(station, arrival): - print u"| %3d | %-9s | %5s | %-21s | %5s | %-18s |" % (departure.id, + print u"|%4d | %-10s|%6s | %-22s|%6s | %-19s|" % (departure.id, departure.type, departure.time.strftime("%H:%M"), departure.arrival_station, diff --git a/weboob/frontends/weboobcfg/__init__.py b/weboob/frontends/weboobcfg/__init__.py new file mode 100644 index 0000000000..d5c1fdcede --- /dev/null +++ b/weboob/frontends/weboobcfg/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2010 Romain Bignon + +This program 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, version 3 of the License. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from .application import WeboobCfg diff --git a/weboob/frontends/weboobcfg/application.py b/weboob/frontends/weboobcfg/application.py new file mode 100644 index 0000000000..ab91e44840 --- /dev/null +++ b/weboob/frontends/weboobcfg/application.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2010 Romain Bignon + +This program 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, version 3 of the License. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import sys +from types import MethodType + +from weboob.tools.application import ConsoleApplication + +class WeboobCfg(ConsoleApplication): + APPNAME = 'weboobcfg' + + def main(self, argv): + return self.process_command(*argv[1:]) + + @ConsoleApplication.command('List modules') + def command_modules(self): + print ' Name Capabilities Description ' + print '+--------------+----------------------+----------------------------------------+' + for name, module in self.weboob.modules_loader.modules.iteritems(): + first_line = True + for cap in module.iter_caps(): + if first_line: + print ' %-14s %-21s %s' % (name, + cap.__name__, + module.get_description()) + first_line = False + else: + print ' %s' % cap.__name__ + + @ConsoleApplication.command('Display a module') + def command_modinfo(self, name): + try: + module = self.weboob.modules_loader.modules[name] + except KeyError: + print >>sys.stderr, 'No such module: %s' % name + return 1 + + print '.------------------------------------------------------------------------------.' + print '| Module %-69s |' % module.get_name() + print "+-----------------.------------------------------------------------------------'" + print '| Version | %s' % module.get_version() + print '| Maintainer | %s' % module.get_maintainer() + print '| License | %s' % module.get_license() + print '| Description | %s' % module.get_description() + print '| Capabilities | %s' % ', '.join([cap.__name__ for cap in module.iter_caps()]) + first = True + for key, field in module.get_config().iteritems(): + value = field.description + if not field.default is None: + value += ' (default: %s)' % field.default + if first: + print '| | ' + print '| Configuration | %s: %s' % (key, value) + first = False + else: + print '| | %s: %s' % (key, value) + print "'-----------------' " + + + @ConsoleApplication.command('Add a backend') + def command_add(self, type, name=None, *options): + if not name: + return self.command_modinfo(type) + + params = {} + for param in options: + try: + key, value = param.split('=', 1) + except ValueError: + print >>sys.stderr, "Parameters have to be in form 'key=value'" + return 1 + + params[key] = value + self.weboob.backends_config.add_backend(name, type, params) + + @ConsoleApplication.command('List backends') + def command_list(self): + print ' Name Type Params ' + print '+--------------+--------------+------------------------------------------------+' + for name, _type, params in self.weboob.backends_config.iter_backends(): + print ' %-14s %-14s %-47s' % (name, + _type, + ', '.join(['%s=%s' % (key, value) for key, value in params.iteritems()])) + + @ConsoleApplication.command('Remove a backend') + def command_remove(self, name): + if not name in self.weboob.backends_config.iter_backends(): + print >>sys.stderr, "Backend '%s' does not exist" % name + return 1 + + self.weboob.backends_config.remove_backend(name) diff --git a/weboob/frontends/weboobcfg/scripts/weboobcfg b/weboob/frontends/weboobcfg/scripts/weboobcfg new file mode 100755 index 0000000000..64aa518c9f --- /dev/null +++ b/weboob/frontends/weboobcfg/scripts/weboobcfg @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# vim: ft=python et softtabstop=4 cinoptions=4 shiftwidth=4 ts=4 ai + +""" +Copyright(C) 2010 Romain Bignon + +This program 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, version 3 of the License. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.frontends.weboobcfg import WeboobCfg + +if __name__ == '__main__': + WeboobCfg.run() diff --git a/weboob/modules.py b/weboob/modules.py index a2669627bc..eaae1ef62b 100644 --- a/weboob/modules.py +++ b/weboob/modules.py @@ -18,6 +18,8 @@ """ +from __future__ import with_statement + import re import os from ConfigParser import SafeConfigParser @@ -26,7 +28,6 @@ import weboob.backends as backends from weboob.backend import Backend from weboob.capabilities.cap import ICap -from weboob.tools.misc import itersubclasses class Module: def __init__(self, name, module): @@ -60,9 +61,9 @@ def get_config(self): return self.klass.CONFIG def iter_caps(self): - for subclass in itersubclasses(self.klass): - if issubclass(subclass, ICap): - yield subclass + for cap in self.klass.__bases__: + if issubclass(cap, ICap) and cap != ICap: + yield cap def has_caps(self, *caps): for c in caps: @@ -95,13 +96,15 @@ def add_backend(self, name, _type, params): config.set(name, '_type', _type) for key, value in params.iteritems(): config.set(name, key, value) - config.save(self.confpath) + with open(self.confpath, 'wb') as f: + config.write(f) def remove_backend(self, name): config = SafeConfigParser() config.read(self.confpath) config.remove_section(name) - config.save(self.confpath) + with open(self.confpath, 'wb') as f: + config.write(f) class ModulesLoader: def __init__(self): diff --git a/weboob/tools/application.py b/weboob/tools/application.py index 38840e58a7..3b04432b8b 100644 --- a/weboob/tools/application.py +++ b/weboob/tools/application.py @@ -115,7 +115,7 @@ def f(x): sys.stderr.write("No such command: %s.\n" % command) elif len(matching_commands) == 1: try: - getattr(self, matching_commands[0])(*args) + return getattr(self, matching_commands[0])(*args) except TypeError, e: try: sys.stderr.write("Command '%s' takes %s arguments.\n" % \ diff --git a/weboob/tools/misc.py b/weboob/tools/misc.py index a8172d6816..eb115fd0c9 100644 --- a/weboob/tools/misc.py +++ b/weboob/tools/misc.py @@ -43,43 +43,3 @@ def local2utc(d): d = d.replace(tzinfo=tz.tzlocal()) d = d.astimezone(tz.tzutc()) return d - -def itersubclasses(cls, _seen=None): - """ - itersubclasses(cls) - - Generator over all subclasses of a given class, in depth first order. - - >>> list(itersubclasses(int)) == [bool] - True - >>> class A(object): pass - >>> class B(A): pass - >>> class C(A): pass - >>> class D(B,C): pass - >>> class E(D): pass - >>> - >>> for cls in itersubclasses(A): - ... print(cls.__name__) - B - D - E - C - >>> # get ALL (new-style) classes currently defined - >>> [cls.__name__ for cls in itersubclasses(object)] #doctest: +ELLIPSIS - ['type', ...'tuple', ...] - """ - - if not isinstance(cls, type): - raise TypeError('itersubclasses must be called with ' - 'new-style classes, not %.100r' % cls) - if _seen is None: _seen = set() - try: - subs = cls.__subclasses__() - except TypeError: # fails only when cls is type - subs = cls.__subclasses__(cls) - for sub in subs: - if sub not in _seen: - _seen.add(sub) - yield sub - for sub in itersubclasses(sub, _seen): - yield sub -- GitLab