weboob-devel/weboob/modules.py

128 lines
4 KiB
Python

# -*- coding: utf-8 -*-
"""
Copyright(C) 2010 Romain Bignon
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
import re
import os
from ConfigParser import SafeConfigParser
from logging import warning, debug
import weboob.backends as backends
from weboob.backend import Backend
from weboob.capabilities.cap import ICap
from weboob.tools.misc import itersubclasses
class Module:
def __init__(self, name, module):
self.name = name
self.module = module
self.klass = None
for attrname in dir(self.module):
attr = getattr(self.module, attrname)
if isinstance(attr, type) and issubclass(attr, Backend) and attr != Backend:
self.klass = attr
if not self.klass:
raise ImportError("This is not a backend module (no Backend class found)")
def get_name(self):
return self.klass.NAME
def get_maintainer(self):
return '%s <%s>' % (self.klass.MAINTAINER, self.klass.EMAIL)
def get_version(self):
return self.klass.VERSION
def get_description(self):
return self.klass.DESCRIPTION
def get_license(self):
return self.klass.LICENSE
def get_config(self):
return self.klass.CONFIG
def iter_caps(self):
for subclass in itersubclasses(self.klass):
if issubclass(subclass, ICap):
yield subclass
def has_caps(self, *caps):
for c in caps:
if issubclass(self.klass, c):
return True
return False
def create_backend(self, weboob, name, config):
return self.klass(weboob, name, config)
class BackendsConfig:
def __init__(self, confpath):
self.confpath = confpath
def iter_backends(self):
config = SafeConfigParser()
config.read(self.confpath)
for name in config.sections():
params = dict(config.items(name))
try:
yield name, params.pop('_type'), params
except KeyError:
warning("Missing field '_type' for backend '%s'", name)
continue
def add_backend(self, name, _type, params):
config = SafeConfigParser()
config.read(self.confpath)
config.add_section(name)
config.set(name, '_type', _type)
for key, value in params.iteritems():
config.set(name, key, value)
config.save(self.confpath)
def remove_backend(self, name):
config = SafeConfigParser()
config.read(self.confpath)
config.remove_section(name)
config.save(self.confpath)
class ModulesLoader:
def __init__(self):
self.modules = {}
def load(self):
path = backends.__path__[0]
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:
self.load_module('weboob.backends.%s' % m.group(1))
def load_module(self, name):
try:
module = Module(name, __import__(name, fromlist=[name]))
except ImportError, e:
warning('Unable to load module %s: %s' % (name, e))
return
if name in self.modules:
warning('Module "%s" is already loaded (%s)' % self.modules[name].module)
return
self.modules[module.get_name()] = module
debug('Loaded module %s (%s)' % (name, module.module.__name__))