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