new frontend 'weboobcfg'

This commit is contained in:
Romain Bignon 2010-04-06 22:53:07 +02:00
commit 7b2295cf6c
9 changed files with 167 additions and 49 deletions

View file

View file

View file

@ -40,7 +40,7 @@ class Travel(ConsoleApplication):
count = 0 count = 0
for name, backend, in self.weboob.iter_backends(): for name, backend, in self.weboob.iter_backends():
for station in backend.iter_station_search(pattern): for station in backend.iter_station_search(pattern):
print '| %-30s | %-43s |' % (station.id, station.name) print '| %-31s| %-44s|' % (station.id, station.name)
count += 1 count += 1
print "+--------------------------------'---------------------------------------------+" print "+--------------------------------'---------------------------------------------+"
print "| %3d stations listed |" % count print "| %3d stations listed |" % count
@ -54,7 +54,7 @@ class Travel(ConsoleApplication):
count = 0 count = 0
for name, backend, in self.weboob.iter_backends(): for name, backend, in self.weboob.iter_backends():
for departure in backend.iter_station_departures(station, arrival): 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.type,
departure.time.strftime("%H:%M"), departure.time.strftime("%H:%M"),
departure.arrival_station, departure.arrival_station,

View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
""" """
from __future__ import with_statement
import re import re
import os import os
from ConfigParser import SafeConfigParser from ConfigParser import SafeConfigParser
@ -26,7 +28,6 @@ from logging import warning, debug
import weboob.backends as backends import weboob.backends as backends
from weboob.backend import Backend from weboob.backend import Backend
from weboob.capabilities.cap import ICap from weboob.capabilities.cap import ICap
from weboob.tools.misc import itersubclasses
class Module: class Module:
def __init__(self, name, module): def __init__(self, name, module):
@ -60,9 +61,9 @@ class Module:
return self.klass.CONFIG return self.klass.CONFIG
def iter_caps(self): def iter_caps(self):
for subclass in itersubclasses(self.klass): for cap in self.klass.__bases__:
if issubclass(subclass, ICap): if issubclass(cap, ICap) and cap != ICap:
yield subclass yield cap
def has_caps(self, *caps): def has_caps(self, *caps):
for c in caps: for c in caps:
@ -95,13 +96,15 @@ class BackendsConfig:
config.set(name, '_type', _type) config.set(name, '_type', _type)
for key, value in params.iteritems(): for key, value in params.iteritems():
config.set(name, key, value) config.set(name, key, value)
config.save(self.confpath) with open(self.confpath, 'wb') as f:
config.write(f)
def remove_backend(self, name): def remove_backend(self, name):
config = SafeConfigParser() config = SafeConfigParser()
config.read(self.confpath) config.read(self.confpath)
config.remove_section(name) config.remove_section(name)
config.save(self.confpath) with open(self.confpath, 'wb') as f:
config.write(f)
class ModulesLoader: class ModulesLoader:
def __init__(self): def __init__(self):

View file

@ -115,7 +115,7 @@ class ConsoleApplication(BaseApplication):
sys.stderr.write("No such command: %s.\n" % command) sys.stderr.write("No such command: %s.\n" % command)
elif len(matching_commands) == 1: elif len(matching_commands) == 1:
try: try:
getattr(self, matching_commands[0])(*args) return getattr(self, matching_commands[0])(*args)
except TypeError, e: except TypeError, e:
try: try:
sys.stderr.write("Command '%s' takes %s arguments.\n" % \ sys.stderr.write("Command '%s' takes %s arguments.\n" % \

View file

@ -43,43 +43,3 @@ def local2utc(d):
d = d.replace(tzinfo=tz.tzlocal()) d = d.replace(tzinfo=tz.tzlocal())
d = d.astimezone(tz.tzutc()) d = d.astimezone(tz.tzutc())
return d 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