Skip to content
modules.py 3.97 KiB
Newer Older
Romain Bignon's avatar
Romain Bignon committed
# -*- 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
Romain Bignon's avatar
Romain Bignon committed
from logging import warning, debug
Romain Bignon's avatar
Romain Bignon committed

import weboob.backends as backends
from weboob.backend import Backend
from weboob.capabilities.cap import ICap
from weboob.tools.misc import itersubclasses
Romain Bignon's avatar
Romain Bignon committed

class Module:
Romain Bignon's avatar
Romain Bignon committed
    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

Romain Bignon's avatar
Romain Bignon committed
    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)
Romain Bignon's avatar
Romain Bignon committed

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)

Romain Bignon's avatar
Romain Bignon committed
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))
Romain Bignon's avatar
Romain Bignon committed
            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__))