change vocabulary
s/module/backend s/backend/configured_backend s/frontend/application
This commit is contained in:
parent
29d28ba175
commit
5c2ab81e16
27 changed files with 347 additions and 347 deletions
|
|
@ -35,7 +35,7 @@ class Boobank(ConsoleApplication):
|
||||||
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_backends(ICapBank)
|
self.load_configured_backends(ICapBank)
|
||||||
return self.process_command(*argv[1:])
|
return self.process_command(*argv[1:])
|
||||||
|
|
||||||
@ConsoleApplication.command('List every available accounts')
|
@ConsoleApplication.command('List every available accounts')
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class Chatoob(ConsoleApplication):
|
||||||
COPYRIGHT = 'Copyright(C) 2010 Christophe Benz'
|
COPYRIGHT = 'Copyright(C) 2010 Christophe Benz'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_backends(ICapChat)
|
self.load_configured_backends(ICapChat)
|
||||||
#for backend, result in self.weboob.do('start_chat_polling', self.on_new_chat_message):
|
#for backend, result in self.weboob.do('start_chat_polling', self.on_new_chat_message):
|
||||||
#logging.info(u'Polling chat messages for backend %s' % backend)
|
#logging.info(u'Polling chat messages for backend %s' % backend)
|
||||||
return self.process_command(*argv[1:])
|
return self.process_command(*argv[1:])
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class HaveSex(PromptApplication):
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_config()
|
self.load_config()
|
||||||
self.load_backends(ICapDating, storage=self.create_storage(self.STORAGE_FILENAME))
|
self.load_configured_backends(ICapDating, storage=self.create_storage(self.STORAGE_FILENAME))
|
||||||
|
|
||||||
self.weboob.do('init_optimizations').wait()
|
self.weboob.do('init_optimizations').wait()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,6 @@ class Masstransit(BaseApplication):
|
||||||
COPYRIGHT = 'Copyright(C) 2010 Julien Hébert'
|
COPYRIGHT = 'Copyright(C) 2010 Julien Hébert'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
"main fonction"
|
self.load_backends(ICapTravel)
|
||||||
self.load_modules(ICapTravel)
|
|
||||||
MasstransitHildon(self.weboob)
|
MasstransitHildon(self.weboob)
|
||||||
gtk.main()
|
gtk.main()
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ class Monboob(ConsoleApplication):
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_config()
|
self.load_config()
|
||||||
self.load_backends(ICapMessages, storage=self.create_storage())
|
self.load_configured_backends(ICapMessages, storage=self.create_storage())
|
||||||
|
|
||||||
return self.process_command(*argv[1:])
|
return self.process_command(*argv[1:])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ class MainWindow(QtMainWindow):
|
||||||
|
|
||||||
self.setCentralWidget(self.manager)
|
self.setCentralWidget(self.manager)
|
||||||
|
|
||||||
self.connect(self.ui.actionModules, SIGNAL("triggered()"), self.modulesConfig)
|
self.connect(self.ui.actionBackends, SIGNAL("triggered()"), self.backendsConfig)
|
||||||
self.connect(self.ui.actionRefresh, SIGNAL("triggered()"), self.refresh)
|
self.connect(self.ui.actionRefresh, SIGNAL("triggered()"), self.refresh)
|
||||||
|
|
||||||
def modulesConfig(self):
|
def backendsConfig(self):
|
||||||
bckndcfg = BackendCfg(self.weboob, (ICapMessages,), self)
|
bckndcfg = BackendCfg(self.weboob, (ICapMessages,), self)
|
||||||
bckndcfg.show()
|
bckndcfg.show()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class QBoobMsg(QtApplication):
|
||||||
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_backends(ICapMessages, storage=self.create_storage())
|
self.load_configured_backends(ICapMessages, storage=self.create_storage())
|
||||||
|
|
||||||
self.main_window = MainWindow(self.config, self.weboob)
|
self.main_window = MainWindow(self.config, self.weboob)
|
||||||
self.main_window.show()
|
self.main_window.show()
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>File</string>
|
<string>File</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionModules"/>
|
<addaction name="actionBackends"/>
|
||||||
<addaction name="actionRefresh"/>
|
<addaction name="actionRefresh"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionQuit"/>
|
<addaction name="actionQuit"/>
|
||||||
|
|
@ -47,12 +47,12 @@
|
||||||
<attribute name="toolBarBreak">
|
<attribute name="toolBarBreak">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
<addaction name="actionModules"/>
|
<addaction name="actionBackends"/>
|
||||||
<addaction name="actionRefresh"/>
|
<addaction name="actionRefresh"/>
|
||||||
</widget>
|
</widget>
|
||||||
<action name="actionModules">
|
<action name="actionBackends">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Modules</string>
|
<string>Backends</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionQuit">
|
<action name="actionQuit">
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,10 @@ class MainWindow(QtMainWindow):
|
||||||
self.ui.tabWidget.addTab(ContactsWidget(self.weboob), self.tr('Contacts'))
|
self.ui.tabWidget.addTab(ContactsWidget(self.weboob), self.tr('Contacts'))
|
||||||
self.ui.tabWidget.addTab(QWidget(), self.tr('Calendar'))
|
self.ui.tabWidget.addTab(QWidget(), self.tr('Calendar'))
|
||||||
|
|
||||||
self.connect(self.ui.actionModules, SIGNAL("triggered()"), self.modulesConfig)
|
self.connect(self.ui.actionBackends, SIGNAL("triggered()"), self.backendsConfig)
|
||||||
self.connect(self.ui.tabWidget, SIGNAL('currentChanged(int)'), self.tabChanged)
|
self.connect(self.ui.tabWidget, SIGNAL('currentChanged(int)'), self.tabChanged)
|
||||||
|
|
||||||
def modulesConfig(self):
|
def backendsConfig(self):
|
||||||
bckndcfg = BackendCfg(self.weboob, (ICapDating,), self)
|
bckndcfg = BackendCfg(self.weboob, (ICapDating,), self)
|
||||||
bckndcfg.show()
|
bckndcfg.show()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class QHaveSex(QtApplication):
|
||||||
STORAGE_FILENAME = 'dating.storage'
|
STORAGE_FILENAME = 'dating.storage'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_backends(ICapDating, storage=self.create_storage())
|
self.load_configured_backends(ICapDating, storage=self.create_storage())
|
||||||
|
|
||||||
self.main_window = MainWindow(self.config, self.weboob)
|
self.main_window = MainWindow(self.config, self.weboob)
|
||||||
self.main_window.show()
|
self.main_window.show()
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>File</string>
|
<string>File</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionModules"/>
|
<addaction name="actionBackends"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionQuit"/>
|
<addaction name="actionQuit"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
@ -54,11 +54,11 @@
|
||||||
<attribute name="toolBarBreak">
|
<attribute name="toolBarBreak">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
<addaction name="actionModules"/>
|
<addaction name="actionBackends"/>
|
||||||
</widget>
|
</widget>
|
||||||
<action name="actionModules">
|
<action name="actionBackends">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Modules</string>
|
<string>Backends</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionQuit">
|
<action name="actionQuit">
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class QVideoob(QtApplication):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_modules(ICapVideo)
|
self.load_backends(ICapVideo)
|
||||||
self.load_config()
|
self.load_config()
|
||||||
|
|
||||||
self.main_window = MainWindow(self.config, self.weboob)
|
self.main_window = MainWindow(self.config, self.weboob)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class QWeboobCfg(QtApplication):
|
||||||
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_backends()
|
self.load_configured_backends()
|
||||||
|
|
||||||
self.dlg = BackendCfg(self.weboob)
|
self.dlg = BackendCfg(self.weboob)
|
||||||
self.dlg.show()
|
self.dlg.show()
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ class Travel(ConsoleApplication):
|
||||||
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_modules(ICapTravel)
|
self.load_backends(ICapTravel)
|
||||||
|
|
||||||
return self.process_command(*argv[1:])
|
return self.process_command(*argv[1:])
|
||||||
|
|
||||||
@ConsoleApplication.command('Search stations')
|
@ConsoleApplication.command('Search stations')
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class Videoob(ConsoleApplication):
|
||||||
def command_info(self, _id):
|
def command_info(self, _id):
|
||||||
_id, backend_name = self.parse_id(_id)
|
_id, backend_name = self.parse_id(_id)
|
||||||
names = (backend_name,) if backend_name is not None else None
|
names = (backend_name,) if backend_name is not None else None
|
||||||
self.load_modules(ICapVideo, names=names)
|
self.load_backends(ICapVideo, names=names)
|
||||||
for backend, video in self.weboob.do('get_video', _id):
|
for backend, video in self.weboob.do('get_video', _id):
|
||||||
if video is None:
|
if video is None:
|
||||||
continue
|
continue
|
||||||
|
|
@ -49,7 +49,7 @@ class Videoob(ConsoleApplication):
|
||||||
|
|
||||||
@ConsoleApplication.command('Search for videos')
|
@ConsoleApplication.command('Search for videos')
|
||||||
def command_search(self, pattern=None):
|
def command_search(self, pattern=None):
|
||||||
self.load_modules(ICapVideo)
|
self.load_backends(ICapVideo)
|
||||||
self.set_formatter_header(u'Search pattern: %s' % pattern if pattern else u'Last videos')
|
self.set_formatter_header(u'Search pattern: %s' % pattern if pattern else u'Last videos')
|
||||||
for backend, video in self.do('iter_search_results', pattern=pattern, nsfw=self.options.nsfw):
|
for backend, video in self.do('iter_search_results', pattern=pattern, nsfw=self.options.nsfw):
|
||||||
self.format(video, backend.name)
|
self.format(video, backend.name)
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class VideoobWeb(BaseApplication):
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_config()
|
self.load_config()
|
||||||
self.weboob.load_modules(ICapVideo)
|
self.weboob.load_backends(ICapVideo)
|
||||||
print 'Web server created. Listening on http://%s:%s' % (
|
print 'Web server created. Listening on http://%s:%s' % (
|
||||||
self.config.get('host'), int(self.config.get('port')))
|
self.config.get('host'), int(self.config.get('port')))
|
||||||
srv = make_server(self.config.get('host'), int(self.config.get('port')), self.make_app)
|
srv = make_server(self.config.get('host'), int(self.config.get('port')), self.make_app)
|
||||||
|
|
|
||||||
|
|
@ -44,65 +44,10 @@ class WeboobCfg(ConsoleApplication):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ConsoleApplication.command('List backends')
|
|
||||||
def command_backends(self, *caps):
|
|
||||||
self.set_default_formatter('table')
|
|
||||||
self.weboob.modules_loader.load()
|
|
||||||
for name, backend in self.weboob.modules_loader.modules.iteritems():
|
|
||||||
if caps and not self.caps_included(backend.iter_caps(), caps):
|
|
||||||
continue
|
|
||||||
row = OrderedDict([('Name', name),
|
|
||||||
('Capabilities', ', '.join(cap.__name__ for cap in backend.iter_caps())),
|
|
||||||
('Description', backend.get_description()),
|
|
||||||
])
|
|
||||||
self.format(row)
|
|
||||||
|
|
||||||
@ConsoleApplication.command('List applications')
|
|
||||||
def command_applications(self, *caps):
|
|
||||||
applications = set()
|
|
||||||
import weboob.applications
|
|
||||||
for path in weboob.applications.__path__:
|
|
||||||
regexp = re.compile('^%s/([\w\d_]+)$' % path)
|
|
||||||
for root, dirs, files in os.walk(path):
|
|
||||||
m = regexp.match(root)
|
|
||||||
if m and '__init__.py' in files:
|
|
||||||
applications.add(m.group(1))
|
|
||||||
print ' '.join(sorted(applications)).encode('utf-8')
|
|
||||||
|
|
||||||
@ConsoleApplication.command('Display information about a backend')
|
|
||||||
def command_info(self, name):
|
|
||||||
try:
|
|
||||||
backend = self.weboob.modules_loader.get_or_load_module(name)
|
|
||||||
except KeyError:
|
|
||||||
logging.error('No such backend: "%s"' % name)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
print '.------------------------------------------------------------------------------.'
|
|
||||||
print '| Backend %-68s |' % backend.get_name()
|
|
||||||
print "+-----------------.------------------------------------------------------------'"
|
|
||||||
print '| Version | %s' % backend.get_version()
|
|
||||||
print '| Maintainer | %s' % backend.get_maintainer()
|
|
||||||
print '| License | %s' % backend.get_license()
|
|
||||||
print '| Description | %s' % backend.get_description()
|
|
||||||
print '| Capabilities | %s' % ', '.join([cap.__name__ for cap in backend.iter_caps()])
|
|
||||||
first = True
|
|
||||||
for key, field in backend.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 configured backend')
|
@ConsoleApplication.command('Add a configured backend')
|
||||||
def command_add(self, name, *options):
|
def command_add(self, name, *options):
|
||||||
self.weboob.modules_loader.load()
|
self.weboob.backends_loader.load_all()
|
||||||
if name not in [module_name for module_name, module in self.weboob.modules_loader.modules.iteritems()]:
|
if name not in [name for name, backend in self.weboob.backends_loader.loaded.iteritems()]:
|
||||||
logging.error(u'Backend "%s" does not exist.' % name)
|
logging.error(u'Backend "%s" does not exist.' % name)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
@ -116,9 +61,9 @@ class WeboobCfg(ConsoleApplication):
|
||||||
return 1
|
return 1
|
||||||
params[key] = value
|
params[key] = value
|
||||||
# ask for params non-specified on command-line arguments
|
# ask for params non-specified on command-line arguments
|
||||||
module = self.weboob.modules_loader.get_or_load_module(name)
|
backend = self.weboob.backends_loader.get_or_load_backend(name)
|
||||||
asked_config = False
|
asked_config = False
|
||||||
for key, value in module.get_config().iteritems():
|
for key, value in backend.config.iteritems():
|
||||||
if not asked_config:
|
if not asked_config:
|
||||||
asked_config = True
|
asked_config = True
|
||||||
print u'Configuration of backend'
|
print u'Configuration of backend'
|
||||||
|
|
@ -155,16 +100,74 @@ class WeboobCfg(ConsoleApplication):
|
||||||
except ConfigParser.DuplicateSectionError:
|
except ConfigParser.DuplicateSectionError:
|
||||||
print u'Instance "%s" already exists for backend "%s".' % (new_name, name)
|
print u'Instance "%s" already exists for backend "%s".' % (new_name, name)
|
||||||
|
|
||||||
@ConsoleApplication.command('List configured backends')
|
@ConsoleApplication.command('Show applications')
|
||||||
|
def command_applications(self, *caps):
|
||||||
|
applications = set()
|
||||||
|
import weboob.applications
|
||||||
|
for path in weboob.applications.__path__:
|
||||||
|
regexp = re.compile('^%s/([\w\d_]+)$' % path)
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
m = regexp.match(root)
|
||||||
|
if m and '__init__.py' in files:
|
||||||
|
applications.add(m.group(1))
|
||||||
|
print ' '.join(sorted(applications)).encode('utf-8')
|
||||||
|
|
||||||
|
@ConsoleApplication.command('Show available backends')
|
||||||
|
def command_backends(self, *caps):
|
||||||
|
self.set_default_formatter('table')
|
||||||
|
self.weboob.backends_loader.load_all()
|
||||||
|
for name, backend in sorted(self.weboob.backends_loader.loaded.iteritems()):
|
||||||
|
if caps and not self.caps_included(backend.iter_caps(), caps):
|
||||||
|
continue
|
||||||
|
row = OrderedDict([('Name', name),
|
||||||
|
('Capabilities', ', '.join(cap.__name__ for cap in backend.iter_caps())),
|
||||||
|
('Description', backend.description),
|
||||||
|
])
|
||||||
|
self.format(row)
|
||||||
|
|
||||||
|
@ConsoleApplication.command('Show configured backends')
|
||||||
def command_configured(self):
|
def command_configured(self):
|
||||||
self.set_default_formatter('table')
|
self.set_default_formatter('table')
|
||||||
for instance_name, name, params in self.weboob.backends_config.iter_backends():
|
for instance_name, name, params in sorted(self.weboob.backends_config.iter_backends()):
|
||||||
row = OrderedDict([('Instance name', instance_name),
|
row = OrderedDict([('Instance name', instance_name),
|
||||||
('Backend name', name),
|
('Backend name', name),
|
||||||
('Configuration', ', '.join('%s=%s' % (key, value) for key, value in params.iteritems())),
|
('Configuration', ', '.join('%s=%s' % (key, value) for key, value in params.iteritems())),
|
||||||
])
|
])
|
||||||
self.format(row)
|
self.format(row)
|
||||||
|
|
||||||
|
@ConsoleApplication.command('Edit configuration file')
|
||||||
|
def command_edit(self):
|
||||||
|
subprocess.call([os.environ.get('EDITOR', 'vi'), self.weboob.backends_config.confpath])
|
||||||
|
|
||||||
|
@ConsoleApplication.command('Display information about a backend')
|
||||||
|
def command_info(self, name):
|
||||||
|
try:
|
||||||
|
backend = self.weboob.backends_loader.get_or_load_backend(name)
|
||||||
|
except KeyError:
|
||||||
|
logging.error('No such backend: "%s"' % name)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print '.------------------------------------------------------------------------------.'
|
||||||
|
print '| Backend %-68s |' % backend.name
|
||||||
|
print "+-----------------.------------------------------------------------------------'"
|
||||||
|
print '| Version | %s' % backend.version
|
||||||
|
print '| Maintainer | %s' % backend.maintainer
|
||||||
|
print '| License | %s' % backend.license
|
||||||
|
print '| Description | %s' % backend.description
|
||||||
|
print '| Capabilities | %s' % ', '.join([cap.__name__ for cap in backend.iter_caps()])
|
||||||
|
first = True
|
||||||
|
for key, field in backend.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('Remove a configured backend')
|
@ConsoleApplication.command('Remove a configured backend')
|
||||||
def command_remove(self, instance_name):
|
def command_remove(self, instance_name):
|
||||||
try:
|
try:
|
||||||
|
|
@ -172,7 +175,3 @@ class WeboobCfg(ConsoleApplication):
|
||||||
except ConfigParser.NoSectionError:
|
except ConfigParser.NoSectionError:
|
||||||
logging.error('Backend instance "%s" does not exist' % instance_name)
|
logging.error('Backend instance "%s" does not exist' % instance_name)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@ConsoleApplication.command('Edit configuration file')
|
|
||||||
def command_edit(self):
|
|
||||||
subprocess.call([os.environ.get('EDITOR', 'vi'), self.weboob.backends_config.confpath])
|
|
||||||
|
|
|
||||||
|
|
@ -32,14 +32,14 @@ class WeboobDebug(ConsoleApplication):
|
||||||
@ConsoleApplication.command('Debug backend')
|
@ConsoleApplication.command('Debug backend')
|
||||||
def command_shell(self, backend_name):
|
def command_shell(self, backend_name):
|
||||||
try:
|
try:
|
||||||
backend = self.weboob.load_modules(names=[backend_name])[backend_name]
|
backend = self.weboob.load_backends(names=[backend_name])[backend_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.error(u'Unable to load backend "%s"' % backend_name)
|
logging.error(u'Unable to load backend "%s"' % backend_name)
|
||||||
return 1
|
return 1
|
||||||
browser = backend.browser
|
browser = backend.browser
|
||||||
from IPython.Shell import IPShellEmbed
|
from IPython.Shell import IPShellEmbed
|
||||||
shell = IPShellEmbed(argv=[])
|
shell = IPShellEmbed(argv=[])
|
||||||
locs = dict(backend=backend, browser=browser, frontend=self, weboob=self.weboob)
|
locs = dict(backend=backend, browser=browser, application=self, weboob=self.weboob)
|
||||||
banner = 'Weboob debug shell\nBackend "%s" loaded.\nAvailable variables: %s' % (backend_name, locs)
|
banner = 'Weboob debug shell\nBackend "%s" loaded.\nAvailable variables: %s' % (backend_name, locs)
|
||||||
shell.set_banner(shell.IP.BANNER + '\n\n' + banner)
|
shell.set_banner(shell.IP.BANNER + '\n\n' + banner)
|
||||||
shell(local_ns=locs, global_ns={})
|
shell(local_ns=locs, global_ns={})
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
|
||||||
from nose import run
|
from nose import run
|
||||||
|
|
||||||
from weboob.tools.application.console import ConsoleApplication
|
from weboob.tools.application.console import ConsoleApplication
|
||||||
|
|
@ -32,13 +33,13 @@ class WeboobTests(ConsoleApplication):
|
||||||
|
|
||||||
@ConsoleApplication.command('Run tests')
|
@ConsoleApplication.command('Run tests')
|
||||||
def command_run(self):
|
def command_run(self):
|
||||||
self.load_modules()
|
|
||||||
self.load_backends()
|
self.load_backends()
|
||||||
|
self.load_configured_backends()
|
||||||
|
|
||||||
suite = []
|
suite = []
|
||||||
for backend in self.weboob.iter_backends():
|
for backend in self.weboob.iter_backends():
|
||||||
t = backend.get_test()
|
test = backend.get_test()
|
||||||
if t:
|
if test:
|
||||||
suite.append(t)
|
suite.append(test)
|
||||||
|
|
||||||
return run(suite=suite)
|
return run(suite=suite)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class Weboorrents(ConsoleApplication):
|
||||||
CONFIG = {}
|
CONFIG = {}
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_backends(ICapTorrent)
|
self.load_configured_backends(ICapTorrent)
|
||||||
return self.process_command(*argv[1:])
|
return self.process_command(*argv[1:])
|
||||||
|
|
||||||
@ConsoleApplication.command('Get information about a torrent')
|
@ConsoleApplication.command('Get information about a torrent')
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class WetBoobs(ConsoleApplication):
|
||||||
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
|
||||||
|
|
||||||
def main(self, argv):
|
def main(self, argv):
|
||||||
self.load_modules(ICapWeather)
|
self.load_backends(ICapWeather)
|
||||||
|
|
||||||
return self.process_command(*argv[1:])
|
return self.process_command(*argv[1:])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,45 +26,50 @@ import re
|
||||||
import stat
|
import stat
|
||||||
|
|
||||||
import weboob.backends
|
import weboob.backends
|
||||||
from weboob.core.backend import BaseBackend
|
|
||||||
from weboob.capabilities.cap import ICap
|
from weboob.capabilities.cap import ICap
|
||||||
|
from weboob.tools.backend import BaseBackend
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['Module']
|
__all__ = ['Backend', 'BackendsConfig', 'BackendsLoader']
|
||||||
|
|
||||||
|
|
||||||
class Module(object):
|
class Backend(object):
|
||||||
def __init__(self, name, module):
|
def __init__(self, package):
|
||||||
self.name = name
|
self.package = package
|
||||||
self.module = module
|
|
||||||
self.klass = None
|
self.klass = None
|
||||||
for attrname in dir(self.module):
|
for attrname in dir(self.package):
|
||||||
attr = getattr(self.module, attrname)
|
attr = getattr(self.package, attrname)
|
||||||
if isinstance(attr, type) and issubclass(attr, BaseBackend) and attr != BaseBackend:
|
if isinstance(attr, type) and issubclass(attr, BaseBackend) and attr != BaseBackend:
|
||||||
self.klass = attr
|
self.klass = attr
|
||||||
|
|
||||||
if not self.klass:
|
if not self.klass:
|
||||||
raise ImportError("This is not a backend module (no BaseBackend class found)")
|
raise ImportError('%s is not a backend (no BaseBackend class found)' % package)
|
||||||
|
|
||||||
def get_name(self):
|
@property
|
||||||
|
def name(self):
|
||||||
return self.klass.NAME
|
return self.klass.NAME
|
||||||
|
|
||||||
def get_maintainer(self):
|
@property
|
||||||
|
def maintainer(self):
|
||||||
return '%s <%s>' % (self.klass.MAINTAINER, self.klass.EMAIL)
|
return '%s <%s>' % (self.klass.MAINTAINER, self.klass.EMAIL)
|
||||||
|
|
||||||
def get_version(self):
|
@property
|
||||||
|
def version(self):
|
||||||
return self.klass.VERSION
|
return self.klass.VERSION
|
||||||
|
|
||||||
def get_description(self):
|
@property
|
||||||
|
def description(self):
|
||||||
return self.klass.DESCRIPTION
|
return self.klass.DESCRIPTION
|
||||||
|
|
||||||
def get_license(self):
|
@property
|
||||||
|
def license(self):
|
||||||
return self.klass.LICENSE
|
return self.klass.LICENSE
|
||||||
|
|
||||||
def get_config(self):
|
@property
|
||||||
|
def config(self):
|
||||||
return self.klass.CONFIG
|
return self.klass.CONFIG
|
||||||
|
|
||||||
def get_icon_path(self):
|
@property
|
||||||
|
def icon_path(self):
|
||||||
return self.klass.ICON
|
return self.klass.ICON
|
||||||
|
|
||||||
def iter_caps(self):
|
def iter_caps(self):
|
||||||
|
|
@ -78,9 +83,11 @@ class Module(object):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def create_backend(self, weboob, name, config, storage):
|
def create_instance(self, weboob, name, config, storage):
|
||||||
debug('Created backend "%s"' % name)
|
backend_instance = self.klass(weboob, name, config, storage)
|
||||||
return self.klass(weboob, name, config, storage)
|
debug('Created backend instance "%s"' % name)
|
||||||
|
return backend_instance
|
||||||
|
|
||||||
|
|
||||||
class BackendsConfig(object):
|
class BackendsConfig(object):
|
||||||
class WrongPermissions(Exception):
|
class WrongPermissions(Exception):
|
||||||
|
|
@ -128,7 +135,7 @@ class BackendsConfig(object):
|
||||||
config = SafeConfigParser()
|
config = SafeConfigParser()
|
||||||
config.read(self.confpath)
|
config.read(self.confpath)
|
||||||
if not config.has_section(name):
|
if not config.has_section(name):
|
||||||
raise KeyError(u'Backend "%s" not found' % name)
|
raise KeyError(u'Backend instance "%s" not found' % name)
|
||||||
|
|
||||||
items = dict(config.items(name, raw=True))
|
items = dict(config.items(name, raw=True))
|
||||||
try:
|
try:
|
||||||
|
|
@ -141,19 +148,20 @@ class BackendsConfig(object):
|
||||||
config = SafeConfigParser()
|
config = SafeConfigParser()
|
||||||
config.read(self.confpath)
|
config.read(self.confpath)
|
||||||
config.remove_section(name)
|
config.remove_section(name)
|
||||||
with open(self.confpath, 'wb') as f:
|
with open(self.confpath, 'w') as f:
|
||||||
config.write(f)
|
config.write(f)
|
||||||
|
|
||||||
class ModulesLoader(object):
|
|
||||||
|
class BackendsLoader(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.modules = {}
|
self.loaded = {}
|
||||||
|
|
||||||
def get_or_load_module(self, name):
|
def get_or_load_backend(self, name):
|
||||||
if name not in self.modules:
|
if name not in self.loaded:
|
||||||
self.load_module('weboob.backends.%s' % name)
|
self.load_backend(name)
|
||||||
return self.modules[name]
|
return self.loaded[name]
|
||||||
|
|
||||||
def iter_existing_module_names(self):
|
def iter_existing_backend_names(self):
|
||||||
for path in weboob.backends.__path__:
|
for path in weboob.backends.__path__:
|
||||||
regexp = re.compile('^%s/([\w\d_]+)$' % path)
|
regexp = re.compile('^%s/([\w\d_]+)$' % path)
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
|
|
@ -161,23 +169,24 @@ class ModulesLoader(object):
|
||||||
if m and '__init__.py' in files:
|
if m and '__init__.py' in files:
|
||||||
yield m.group(1)
|
yield m.group(1)
|
||||||
|
|
||||||
def load(self):
|
def load_all(self):
|
||||||
for existing_module_name in self.iter_existing_module_names():
|
for existing_backend_name in self.iter_existing_backend_names():
|
||||||
self.load_module('weboob.backends.%s' % existing_module_name)
|
self.load_backend(existing_backend_name)
|
||||||
|
|
||||||
def load_module(self, name):
|
def load_backend(self, name):
|
||||||
try:
|
try:
|
||||||
module = Module(name, __import__(name, fromlist=[str(name)]))
|
package_name = 'weboob.backends.%s' % name
|
||||||
|
backend = Backend(__import__(package_name, fromlist=[str(package_name)]))
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
msg = 'Unable to load module "%s": %s' % (name, e)
|
msg = u'Unable to load backend "%s": %s' % (name, e)
|
||||||
if logging.root.level == logging.DEBUG:
|
if logging.root.level == logging.DEBUG:
|
||||||
exception(msg)
|
exception(msg)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
error(msg)
|
error(msg)
|
||||||
return
|
return
|
||||||
if module.get_name() in self.modules:
|
if backend.name in self.loaded:
|
||||||
warning('Module "%s" is already loaded (%s)' % (self.modules[module.get_name()].module, name))
|
debug('Backend "%s" is already loaded from %s' % (name, backend.package.__path__[0]))
|
||||||
return
|
return
|
||||||
self.modules[module.get_name()] = module
|
self.loaded[backend.name] = backend
|
||||||
debug('Loaded module "%s" from %s' % (name, module.module.__path__))
|
debug('Loaded backend "%s" from %s' % (name, backend.package.__path__[0]))
|
||||||
|
|
@ -23,9 +23,9 @@ import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from weboob.core.bcall import BackendsCall
|
from weboob.core.bcall import BackendsCall
|
||||||
from weboob.core.modules import ModulesLoader, BackendsConfig
|
from weboob.core.backends import BackendsConfig, BackendsLoader
|
||||||
from weboob.core.backend import BaseBackend
|
|
||||||
from weboob.core.scheduler import Scheduler
|
from weboob.core.scheduler import Scheduler
|
||||||
|
from weboob.tools.backend import BaseBackend
|
||||||
|
|
||||||
if sys.version_info[:2] <= (2, 5):
|
if sys.version_info[:2] <= (2, 5):
|
||||||
import weboob.tools.property
|
import weboob.tools.property
|
||||||
|
|
@ -40,7 +40,7 @@ class Weboob(object):
|
||||||
|
|
||||||
def __init__(self, workdir=WORKDIR, backends_filename=None, scheduler=None):
|
def __init__(self, workdir=WORKDIR, backends_filename=None, scheduler=None):
|
||||||
self.workdir = workdir
|
self.workdir = workdir
|
||||||
self.backends = {}
|
self.backend_instances = {}
|
||||||
|
|
||||||
# Scheduler
|
# Scheduler
|
||||||
if scheduler is None:
|
if scheduler is None:
|
||||||
|
|
@ -53,10 +53,10 @@ class Weboob(object):
|
||||||
elif not os.path.isdir(self.workdir):
|
elif not os.path.isdir(self.workdir):
|
||||||
warning('"%s" is not a directory' % self.workdir)
|
warning('"%s" is not a directory' % self.workdir)
|
||||||
|
|
||||||
# Modules loader
|
# Backends loader
|
||||||
self.modules_loader = ModulesLoader()
|
self.backends_loader = BackendsLoader()
|
||||||
|
|
||||||
# Backends config
|
# Backend instances config
|
||||||
if not backends_filename:
|
if not backends_filename:
|
||||||
backends_filename = os.path.join(self.workdir, self.BACKENDS_FILENAME)
|
backends_filename = os.path.join(self.workdir, self.BACKENDS_FILENAME)
|
||||||
elif not backends_filename.startswith('/'):
|
elif not backends_filename.startswith('/'):
|
||||||
|
|
@ -64,41 +64,26 @@ class Weboob(object):
|
||||||
self.backends_config = BackendsConfig(backends_filename)
|
self.backends_config = BackendsConfig(backends_filename)
|
||||||
|
|
||||||
def load_backends(self, caps=None, names=None, storage=None):
|
def load_backends(self, caps=None, names=None, storage=None):
|
||||||
loaded_backends = {}
|
loaded = {}
|
||||||
for name, _type, params in self.backends_config.iter_backends():
|
self.backends_loader.load_all()
|
||||||
try:
|
for backend_name, backend in self.backends_loader.loaded.iteritems():
|
||||||
module = self.modules_loader.get_or_load_module(_type)
|
if caps is not None and not backend.has_caps(caps) or \
|
||||||
except KeyError:
|
names is not None and backend_name not in names:
|
||||||
warning(u'Unable to find module "%s" for backend "%s"' % (_type, name))
|
|
||||||
continue
|
continue
|
||||||
|
backend_instance = backend.create_instance(self, backend_name, {}, storage)
|
||||||
|
self.backend_instances[backend_name] = loaded[backend_name] = backend_instance
|
||||||
|
return loaded
|
||||||
|
|
||||||
# Check conditions
|
def load_configured_backends(self, caps=None, names=None, storage=None):
|
||||||
if caps is not None and not module.has_caps(caps) or \
|
loaded = {}
|
||||||
names is not None and name not in names:
|
for instance_name, backend_name, params in self.backends_config.iter_backends():
|
||||||
|
backend = self.backends_loader.get_or_load_backend(backend_name)
|
||||||
|
if caps is not None and not backend.has_caps(caps) or \
|
||||||
|
names is not None and instance_name not in names:
|
||||||
continue
|
continue
|
||||||
|
backend_instance = backend.create_instance(self, instance_name, params, storage)
|
||||||
try:
|
self.backend_instances[instance_name] = loaded[instance_name] = backend_instance
|
||||||
self.backends[name] = module.create_backend(self, name, params, storage)
|
return loaded
|
||||||
loaded_backends[name] = self.backends[name]
|
|
||||||
except Exception, e:
|
|
||||||
warning(u'Unable to load "%s" backend: %s. filename=%s' % (name, e, self.backends_config.confpath))
|
|
||||||
|
|
||||||
return loaded_backends
|
|
||||||
|
|
||||||
def load_modules(self, caps=None, names=None, storage=None):
|
|
||||||
loaded_backends = {}
|
|
||||||
self.modules_loader.load()
|
|
||||||
for name, module in self.modules_loader.modules.iteritems():
|
|
||||||
if caps is not None and not module.has_caps(caps) or \
|
|
||||||
names is not None and name not in names:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
name = module.get_name()
|
|
||||||
self.backends[name] = module.create_backend(self, name, {}, storage)
|
|
||||||
loaded_backends[name] = self.backends[name]
|
|
||||||
except Exception, e:
|
|
||||||
warning(u'Unable to load "%s" module as backend with no config: %s' % (name, e))
|
|
||||||
return loaded_backends
|
|
||||||
|
|
||||||
def iter_backends(self, caps=None):
|
def iter_backends(self, caps=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -109,7 +94,7 @@ class Weboob(object):
|
||||||
@param caps Optional list of capabilities to select backends
|
@param caps Optional list of capabilities to select backends
|
||||||
@return iterator on selected backends.
|
@return iterator on selected backends.
|
||||||
"""
|
"""
|
||||||
for name, backend in sorted(self.backends.iteritems()):
|
for name, backend in sorted(self.backend_instances.iteritems()):
|
||||||
if caps is None or backend.has_caps(caps):
|
if caps is None or backend.has_caps(caps):
|
||||||
with backend:
|
with backend:
|
||||||
yield backend
|
yield backend
|
||||||
|
|
@ -134,7 +119,7 @@ class Weboob(object):
|
||||||
|
|
||||||
def do_caps(self, caps, function, *args, **kwargs):
|
def do_caps(self, caps, function, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Do calls on loaded modules with the specified capabilities, in
|
Do calls on loaded backends with the specified capabilities, in
|
||||||
separated threads.
|
separated threads.
|
||||||
|
|
||||||
See also documentation of the 'do' method.
|
See also documentation of the 'do' method.
|
||||||
|
|
@ -156,14 +141,14 @@ class Weboob(object):
|
||||||
elif isinstance(backends, (list,tuple)):
|
elif isinstance(backends, (list,tuple)):
|
||||||
old_backends = backends
|
old_backends = backends
|
||||||
backends = []
|
backends = []
|
||||||
for b in old_backends:
|
for backend in old_backends:
|
||||||
if isinstance(b, (str,unicode)):
|
if isinstance(backend, (str,unicode)):
|
||||||
try:
|
try:
|
||||||
backends.append(self.backends[self.backends.index(b)])
|
backends.append(self.backends[self.backends.index(backend)])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
backends.append(b)
|
backends.append(backend)
|
||||||
return BackendsCall(backends, function, *args, **kwargs)
|
return BackendsCall(backends, function, *args, **kwargs)
|
||||||
|
|
||||||
def schedule(self, interval, function, *args):
|
def schedule(self, interval, function, *args):
|
||||||
|
|
|
||||||
|
|
@ -32,28 +32,28 @@ class BackendNotFound(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FrontendStorage(object):
|
class ApplicationStorage(object):
|
||||||
def __init__(self, name, storage):
|
def __init__(self, name, storage):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
|
|
||||||
def set(self, *args):
|
def set(self, *args):
|
||||||
if self.storage:
|
if self.storage:
|
||||||
return self.storage.set('frontends', self.name, *args)
|
return self.storage.set('applications', self.name, *args)
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
if self.storage:
|
if self.storage:
|
||||||
return self.storage.get('frontends', self.name, *args, **kwargs)
|
return self.storage.get('applications', self.name, *args, **kwargs)
|
||||||
else:
|
else:
|
||||||
return kwargs.get('default', None)
|
return kwargs.get('default', None)
|
||||||
|
|
||||||
def load(self, default):
|
def load(self, default):
|
||||||
if self.storage:
|
if self.storage:
|
||||||
return self.storage.load('frontends', self.name, default)
|
return self.storage.load('applications', self.name, default)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
if self.storage:
|
if self.storage:
|
||||||
return self.storage.save('frontends', self.name)
|
return self.storage.save('applications', self.name)
|
||||||
|
|
||||||
class BaseApplication(object):
|
class BaseApplication(object):
|
||||||
# Application name
|
# Application name
|
||||||
|
|
@ -107,7 +107,7 @@ class BaseApplication(object):
|
||||||
path = os.path.join(self.CONFDIR, path)
|
path = os.path.join(self.CONFDIR, path)
|
||||||
|
|
||||||
storage = klass(path)
|
storage = klass(path)
|
||||||
self.storage = FrontendStorage(self.APPNAME, storage)
|
self.storage = ApplicationStorage(self.APPNAME, storage)
|
||||||
self.storage.load(self.STORAGE)
|
self.storage.load(self.STORAGE)
|
||||||
return storage
|
return storage
|
||||||
|
|
||||||
|
|
@ -138,18 +138,18 @@ class BaseApplication(object):
|
||||||
def load_backends(self, caps=None, names=None, *args, **kwargs):
|
def load_backends(self, caps=None, names=None, *args, **kwargs):
|
||||||
if names is None:
|
if names is None:
|
||||||
names = self.requested_backends
|
names = self.requested_backends
|
||||||
loaded_backends = self.weboob.load_backends(caps, names, *args, **kwargs)
|
loaded = self.weboob.load_backends(caps, names, *args, **kwargs)
|
||||||
if not loaded_backends:
|
if not loaded:
|
||||||
logging.warning(u'No backend loaded')
|
logging.warning(u'No backend loaded')
|
||||||
return loaded_backends
|
return loaded
|
||||||
|
|
||||||
def load_modules(self, caps=None, names=None, *args, **kwargs):
|
def load_configured_backends(self, caps=None, names=None, *args, **kwargs):
|
||||||
if names is None:
|
if names is None:
|
||||||
names = self.requested_backends
|
names = self.requested_backends
|
||||||
loaded_modules = self.weboob.load_modules(caps, names, *args, **kwargs)
|
loaded = self.weboob.load_configured_backends(caps, names, *args, **kwargs)
|
||||||
if not loaded_modules:
|
if not loaded:
|
||||||
logging.warning(u'No module loaded')
|
logging.warning(u'No configured backend loaded')
|
||||||
return loaded_modules
|
return loaded
|
||||||
|
|
||||||
def _get_completions(self):
|
def _get_completions(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -201,9 +201,9 @@ class BaseApplication(object):
|
||||||
logging.basicConfig(stream=sys.stdout, level=level, format=log_format)
|
logging.basicConfig(stream=sys.stdout, level=level, format=log_format)
|
||||||
app.requested_backends = app.options.backends.split(',') if app.options.backends else None
|
app.requested_backends = app.options.backends.split(',') if app.options.backends else None
|
||||||
if app.requested_backends:
|
if app.requested_backends:
|
||||||
existing_module_names = list(app.weboob.modules_loader.iter_existing_module_names())
|
existing_backend_names = list(app.weboob.backends_loader.iter_existing_backend_names())
|
||||||
for requested_backend in app.requested_backends:
|
for requested_backend in app.requested_backends:
|
||||||
if requested_backend not in existing_module_names:
|
if requested_backend not in existing_backend_names:
|
||||||
raise BackendNotFound(u'Unknown backend: "%s"' % requested_backend)
|
raise BackendNotFound(u'Unknown backend: "%s"' % requested_backend)
|
||||||
|
|
||||||
app._handle_app_options()
|
app._handle_app_options()
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from weboob.core import CallErrors
|
from weboob.core import CallErrors
|
||||||
from weboob.core.modules import BackendsConfig
|
from weboob.core.backends import BackendsConfig
|
||||||
|
|
||||||
from .base import BackendNotFound, BaseApplication
|
from .base import BackendNotFound, BaseApplication
|
||||||
from .formatters.load import formatters, load_formatter
|
from .formatters.load import formatters, load_formatter
|
||||||
|
|
|
||||||
|
|
@ -35,50 +35,50 @@ class BackendCfg(QDialog):
|
||||||
self.caps = caps
|
self.caps = caps
|
||||||
self.config_widgets = {}
|
self.config_widgets = {}
|
||||||
|
|
||||||
self.weboob.modules_loader.load()
|
self.weboob.backends_loader.load_all()
|
||||||
|
|
||||||
self.ui.backendsList.header().setResizeMode(QHeaderView.ResizeToContents)
|
self.ui.configuredBackendsList.header().setResizeMode(QHeaderView.ResizeToContents)
|
||||||
self.ui.configFrame.hide()
|
self.ui.configFrame.hide()
|
||||||
|
|
||||||
for name, module in self.weboob.modules_loader.modules.iteritems():
|
for name, backend in self.weboob.backends_loader.loaded.iteritems():
|
||||||
if not self.caps or module.has_caps(*self.caps):
|
if not self.caps or backend.has_caps(*self.caps):
|
||||||
item = QListWidgetItem(name.capitalize())
|
item = QListWidgetItem(name.capitalize())
|
||||||
|
|
||||||
if module.get_icon_path():
|
if backend.icon_path:
|
||||||
img = QImage(module.get_icon_path())
|
img = QImage(backend.icon_path)
|
||||||
item.setIcon(QIcon(QPixmap.fromImage(img)))
|
item.setIcon(QIcon(QPixmap.fromImage(img)))
|
||||||
|
|
||||||
self.ui.modulesList.addItem(item)
|
self.ui.backendsList.addItem(item)
|
||||||
|
|
||||||
self.loadBackendsList()
|
self.loadConfiguredBackendsList()
|
||||||
|
|
||||||
self.connect(self.ui.backendsList, SIGNAL('itemClicked(QTreeWidgetItem *, int)'), self.backendClicked)
|
self.connect(self.ui.configuredBackendsList, SIGNAL('itemClicked(QTreeWidgetItem *, int)'), self.configuredBackendClicked)
|
||||||
self.connect(self.ui.modulesList, SIGNAL('itemSelectionChanged()'), self.modulesSelectionChanged)
|
self.connect(self.ui.backendsList, SIGNAL('itemSelectionChanged()'), self.backendSelectionChanged)
|
||||||
self.connect(self.ui.proxyBox, SIGNAL('toggled(bool)'), self.proxyEditEnabled)
|
self.connect(self.ui.proxyBox, SIGNAL('toggled(bool)'), self.proxyEditEnabled)
|
||||||
self.connect(self.ui.addButton, SIGNAL('clicked()'), self.addEvent)
|
self.connect(self.ui.addButton, SIGNAL('clicked()'), self.addEvent)
|
||||||
self.connect(self.ui.removeButton, SIGNAL('clicked()'), self.removeEvent)
|
self.connect(self.ui.removeButton, SIGNAL('clicked()'), self.removeEvent)
|
||||||
self.connect(self.ui.configButtonBox, SIGNAL('accepted()'), self.acceptBackend)
|
self.connect(self.ui.configButtonBox, SIGNAL('accepted()'), self.acceptBackend)
|
||||||
self.connect(self.ui.configButtonBox, SIGNAL('rejected()'), self.rejectBackend)
|
self.connect(self.ui.configButtonBox, SIGNAL('rejected()'), self.rejectBackend)
|
||||||
|
|
||||||
def loadBackendsList(self):
|
def loadConfiguredBackendsList(self):
|
||||||
self.ui.backendsList.clear()
|
self.ui.configuredBackendsList.clear()
|
||||||
for instance_name, name, params in self.weboob.backends_config.iter_backends():
|
for instance_name, name, params in self.weboob.backends_config.iter_backends():
|
||||||
module = self.weboob.modules_loader.modules[name]
|
backend = self.weboob.backends_loader.loaded[name]
|
||||||
if self.caps and not module.has_caps(*self.caps):
|
if self.caps and not backend.has_caps(*self.caps):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
item = QTreeWidgetItem(None, [instance_name, name])
|
item = QTreeWidgetItem(None, [instance_name, name])
|
||||||
|
|
||||||
if module.get_icon_path():
|
if backend.icon_path:
|
||||||
img = QImage(module.get_icon_path())
|
img = QImage(backend.icon_path)
|
||||||
item.setIcon(0, QIcon(QPixmap.fromImage(img)))
|
item.setIcon(0, QIcon(QPixmap.fromImage(img)))
|
||||||
|
|
||||||
self.ui.backendsList.addTopLevelItem(item)
|
self.ui.configuredBackendsList.addTopLevelItem(item)
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
def backendClicked(self, item, col):
|
def configuredBackendClicked(self, item, col):
|
||||||
bname = unicode(item.text(0))
|
bname = unicode(item.text(0))
|
||||||
|
|
||||||
self.editBackend(bname)
|
self.editBackend(bname)
|
||||||
|
|
@ -87,7 +87,7 @@ class BackendCfg(QDialog):
|
||||||
self.editBackend()
|
self.editBackend()
|
||||||
|
|
||||||
def removeEvent(self):
|
def removeEvent(self):
|
||||||
item = self.ui.backendsList.currentItem()
|
item = self.ui.configuredBackendsList.currentItem()
|
||||||
if not item:
|
if not item:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@ class BackendCfg(QDialog):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.weboob.backends_config.remove_backend(bname)
|
self.weboob.backends_config.remove_backend(bname)
|
||||||
self.loadBackendsList()
|
self.loadConfiguredBackendsList()
|
||||||
|
|
||||||
def editBackend(self, bname=None):
|
def editBackend(self, bname=None):
|
||||||
self.ui.configFrame.show()
|
self.ui.configFrame.show()
|
||||||
|
|
@ -108,12 +108,12 @@ class BackendCfg(QDialog):
|
||||||
if bname is not None:
|
if bname is not None:
|
||||||
mname, params = self.weboob.backends_config.get_backend(bname)
|
mname, params = self.weboob.backends_config.get_backend(bname)
|
||||||
|
|
||||||
items = self.ui.modulesList.findItems(mname, Qt.MatchFixedString)
|
items = self.ui.backendsList.findItems(mname, Qt.MatchFixedString)
|
||||||
if not items:
|
if not items:
|
||||||
print 'Module not found'
|
print 'Backend not found'
|
||||||
else:
|
else:
|
||||||
self.ui.modulesList.setCurrentItem(items[0])
|
self.ui.backendsList.setCurrentItem(items[0])
|
||||||
self.ui.modulesList.setEnabled(False)
|
self.ui.backendsList.setEnabled(False)
|
||||||
|
|
||||||
self.ui.nameEdit.setText(bname)
|
self.ui.nameEdit.setText(bname)
|
||||||
self.ui.nameEdit.setEnabled(False)
|
self.ui.nameEdit.setEnabled(False)
|
||||||
|
|
@ -137,19 +137,19 @@ class BackendCfg(QDialog):
|
||||||
self.ui.nameEdit.setEnabled(True)
|
self.ui.nameEdit.setEnabled(True)
|
||||||
self.ui.proxyBox.setChecked(False)
|
self.ui.proxyBox.setChecked(False)
|
||||||
self.ui.proxyEdit.clear()
|
self.ui.proxyEdit.clear()
|
||||||
self.ui.modulesList.setEnabled(True)
|
self.ui.backendsList.setEnabled(True)
|
||||||
self.ui.modulesList.setCurrentRow(-1)
|
self.ui.backendsList.setCurrentRow(-1)
|
||||||
|
|
||||||
def acceptBackend(self):
|
def acceptBackend(self):
|
||||||
bname = unicode(self.ui.nameEdit.text())
|
bname = unicode(self.ui.nameEdit.text())
|
||||||
selection = self.ui.modulesList.selectedItems()
|
selection = self.ui.backendsList.selectedItems()
|
||||||
|
|
||||||
if not selection:
|
if not selection:
|
||||||
QMessageBox.critical(self, self.tr('Unable to add a backend'),
|
QMessageBox.critical(self, self.tr('Unable to add a configured backend'),
|
||||||
self.tr('Please select a module'))
|
self.tr('Please select a backend'))
|
||||||
return
|
return
|
||||||
|
|
||||||
module = self.weboob.modules_loader.modules[unicode(selection[0].text()).lower()]
|
backend = self.weboob.backends_loader.loaded[unicode(selection[0].text()).lower()]
|
||||||
|
|
||||||
params = {}
|
params = {}
|
||||||
missing = []
|
missing = []
|
||||||
|
|
@ -162,7 +162,7 @@ class BackendCfg(QDialog):
|
||||||
if not params['_proxy']:
|
if not params['_proxy']:
|
||||||
missing.append(self.tr('Proxy'))
|
missing.append(self.tr('Proxy'))
|
||||||
|
|
||||||
for key, field in module.get_config().iteritems():
|
for key, field in backend.config.iteritems():
|
||||||
label, value = self.config_widgets[key]
|
label, value = self.config_widgets[key]
|
||||||
|
|
||||||
if isinstance(value, QLineEdit):
|
if isinstance(value, QLineEdit):
|
||||||
|
|
@ -189,49 +189,49 @@ class BackendCfg(QDialog):
|
||||||
unicode(self.tr('Please set a value in this fields:\n%s')) % ('\n'.join(['- %s' % s for s in missing])))
|
unicode(self.tr('Please set a value in this fields:\n%s')) % ('\n'.join(['- %s' % s for s in missing])))
|
||||||
return
|
return
|
||||||
|
|
||||||
self.weboob.backends_config.add_backend(bname, module.get_name(), params, edit=not self.ui.nameEdit.isEnabled())
|
self.weboob.backends_config.add_backend(bname, backend.name, params, edit=not self.ui.nameEdit.isEnabled())
|
||||||
self.ui.configFrame.hide()
|
self.ui.configFrame.hide()
|
||||||
|
|
||||||
self.loadBackendsList()
|
self.loadConfiguredBackendsList()
|
||||||
|
|
||||||
def rejectBackend(self):
|
def rejectBackend(self):
|
||||||
self.ui.configFrame.hide()
|
self.ui.configFrame.hide()
|
||||||
|
|
||||||
def modulesSelectionChanged(self):
|
def backendSelectionChanged(self):
|
||||||
for key, (label, value) in self.config_widgets.iteritems():
|
for key, (label, value) in self.config_widgets.iteritems():
|
||||||
label.hide()
|
label.hide()
|
||||||
value.hide()
|
value.hide()
|
||||||
self.ui.configLayout.removeWidget(label)
|
self.ui.configLayout.removeWidget(label)
|
||||||
self.ui.configLayout.removeWidget(value)
|
self.ui.configLayout.removeWidget(value)
|
||||||
self.config_widgets.clear()
|
self.config_widgets.clear()
|
||||||
self.ui.moduleInfo.clear()
|
self.ui.backendInfo.clear()
|
||||||
|
|
||||||
selection = self.ui.modulesList.selectedItems()
|
selection = self.ui.backendsList.selectedItems()
|
||||||
if not selection:
|
if not selection:
|
||||||
return
|
return
|
||||||
|
|
||||||
module = self.weboob.modules_loader.modules[unicode(selection[0].text()).lower()]
|
backend = self.weboob.backends_loader.loaded[unicode(selection[0].text()).lower()]
|
||||||
|
|
||||||
if module.get_icon_path():
|
if backend.icon_path:
|
||||||
img = QImage(module.get_icon_path())
|
img = QImage(backend.icon_path)
|
||||||
self.ui.moduleInfo.document().addResource(QTextDocument.ImageResource, QUrl('mydata://logo.png'), QVariant(img))
|
self.ui.backendInfo.document().addResource(QTextDocument.ImageResource, QUrl('mydata://logo.png'), QVariant(img))
|
||||||
|
|
||||||
self.ui.moduleInfo.setText(unicode(self.tr(
|
self.ui.backendInfo.setText(unicode(self.tr(
|
||||||
'<h1>%s Module %s</h1>'
|
'<h1>%s Backend %s</h1>'
|
||||||
'<b>Version</b>: %s<br />'
|
'<b>Version</b>: %s<br />'
|
||||||
'<b>Maintainer</b>: %s<br />'
|
'<b>Maintainer</b>: %s<br />'
|
||||||
'<b>License</b>: %s<br />'
|
'<b>License</b>: %s<br />'
|
||||||
'<b>Description</b>: %s<br />'
|
'<b>Description</b>: %s<br />'
|
||||||
'<b>Capabilities</b>: %s<br />'))
|
'<b>Capabilities</b>: %s<br />'))
|
||||||
% ('<img src="mydata://logo.png" />' if module.get_icon_path() else '',
|
% ('<img src="mydata://logo.png" />' if backend.icon_path else '',
|
||||||
module.get_name().capitalize(),
|
backend.name.capitalize(),
|
||||||
module.get_version(),
|
backend.version,
|
||||||
module.get_maintainer().replace('&', '&').replace('<', '<').replace('>', '>'),
|
backend.maintainer.replace('&', '&').replace('<', '<').replace('>', '>'),
|
||||||
module.get_license(),
|
backend.license,
|
||||||
module.get_description(),
|
backend.description,
|
||||||
', '.join([cap.__name__ for cap in module.iter_caps()])))
|
', '.join([cap.__name__ for cap in backend.iter_caps()])))
|
||||||
|
|
||||||
for key, field in module.get_config().iteritems():
|
for key, field in backend.config.iteritems():
|
||||||
label = QLabel(u'%s:' % field.description)
|
label = QLabel(u'%s:' % field.description)
|
||||||
if isinstance(field.default, bool):
|
if isinstance(field.default, bool):
|
||||||
value = QCheckBox()
|
value = QCheckBox()
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>626</width>
|
<width>645</width>
|
||||||
<height>614</height>
|
<height>652</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeWidget" name="backendsList">
|
<widget class="QTreeWidget" name="configuredBackendsList">
|
||||||
<property name="editTriggers">
|
<property name="editTriggers">
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
</column>
|
</column>
|
||||||
<column>
|
<column>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Module</string>
|
<string>Backend</string>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
@ -125,99 +125,107 @@
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitter">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<property name="orientation">
|
<item>
|
||||||
<enum>Qt::Horizontal</enum>
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Available backends</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="backendsList">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QListWidget" name="modulesList">
|
<property name="frameShape">
|
||||||
<property name="sizePolicy">
|
<enum>QFrame::NoFrame</enum>
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
</property>
|
||||||
<horstretch>0</horstretch>
|
<property name="frameShadow">
|
||||||
<verstretch>0</verstretch>
|
<enum>QFrame::Plain</enum>
|
||||||
</sizepolicy>
|
</property>
|
||||||
</property>
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<property name="iconSize">
|
<item>
|
||||||
<size>
|
<widget class="QTextEdit" name="backendInfo">
|
||||||
<width>32</width>
|
<property name="sizePolicy">
|
||||||
<height>32</height>
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
</size>
|
<horstretch>0</horstretch>
|
||||||
</property>
|
<verstretch>0</verstretch>
|
||||||
<property name="spacing">
|
</sizepolicy>
|
||||||
<number>1</number>
|
</property>
|
||||||
</property>
|
<property name="readOnly">
|
||||||
<property name="sortingEnabled">
|
<bool>true</bool>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
<widget class="QFrame" name="frame_2">
|
<item>
|
||||||
<property name="sizePolicy">
|
<layout class="QFormLayout" name="configLayout">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<item row="0" column="0">
|
||||||
<horstretch>1</horstretch>
|
<widget class="QLabel" name="label">
|
||||||
<verstretch>0</verstretch>
|
<property name="text">
|
||||||
</sizepolicy>
|
<string>Name:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
</widget>
|
||||||
<enum>QFrame::NoFrame</enum>
|
</item>
|
||||||
</property>
|
<item row="0" column="1">
|
||||||
<property name="frameShadow">
|
<widget class="QLineEdit" name="nameEdit"/>
|
||||||
<enum>QFrame::Plain</enum>
|
</item>
|
||||||
</property>
|
<item row="1" column="0">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
<widget class="QCheckBox" name="proxyBox">
|
||||||
<item>
|
<property name="text">
|
||||||
<layout class="QFormLayout" name="configLayout">
|
<string>Proxy:</string>
|
||||||
<item row="0" column="0">
|
</property>
|
||||||
<widget class="QLabel" name="label">
|
</widget>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>Name:</string>
|
<item row="1" column="1">
|
||||||
</property>
|
<widget class="QLineEdit" name="proxyEdit">
|
||||||
</widget>
|
<property name="enabled">
|
||||||
</item>
|
<bool>false</bool>
|
||||||
<item row="0" column="1">
|
</property>
|
||||||
<widget class="QLineEdit" name="nameEdit"/>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
</layout>
|
||||||
<widget class="QCheckBox" name="proxyBox">
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Proxy:</string>
|
<widget class="QDialogButtonBox" name="configButtonBox">
|
||||||
</property>
|
<property name="orientation">
|
||||||
</widget>
|
<enum>Qt::Horizontal</enum>
|
||||||
</item>
|
</property>
|
||||||
<item row="1" column="1">
|
<property name="standardButtons">
|
||||||
<widget class="QLineEdit" name="proxyEdit">
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
<property name="enabled">
|
</property>
|
||||||
<bool>false</bool>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
</layout>
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="configButtonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QTextEdit" name="moduleInfo">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue