# -*- coding: utf-8 -*- # # Copyright (C) 2013 GNS3 Technologies Inc. # # 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, either version 3 of the License, or # (at your option) any later version. # # 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, see . import inspect import pkgutil from .modules import IModule import logging log = logging.getLogger(__name__) class Module(object): """ Module representation for the module manager :param name: module name :param cls: module class to be instantiated when the module is activated """ def __init__(self, name, cls): self._name = name self._cls = cls @property def name(self): return self._name @name.setter def name(self, new_name): self._name = new_name def cls(self): return self._cls class ModuleManager(object): """ Manages modules :param module_paths: path from where module are loaded """ def __init__(self, module_paths=['modules']): self._modules = [] self._module_paths = module_paths def load_modules(self): """ Finds all the possible modules (classes with IModule as a parent) """ for _, name, ispkg in pkgutil.iter_modules(self._module_paths): if (ispkg): log.debug("analyzing {} package directory".format(name)) try: file, pathname, description = imp.find_module(name, self._module_paths) module = imp.load_module(name, file, pathname, description) classes = inspect.getmembers(module, inspect.isclass) for module_class in classes: if issubclass(module_class[1], IModule): # make sure the module class has IModule as a parent if module_class[1].__module__ == name: log.info("loading {} module".format(module_class[0].lower())) info = Module(name=module_class[0].lower(), cls=module_class[1]) self._modules.append(info) except Exception: log.critical("error while analyzing {} package directory".format(name), exc_info=1) finally: if file: file.close() def get_all_modules(self): """ Returns all modules. :returns: list of Module objects """ return self._modules def activate_module(self, module, *args, **kwargs): """ Activates a given module. :param module: module to activate (Module object) :param args: args passed to the module :param kwargs: kwargs passed to the module :returns: instantiated module class """ module_class = module.cls() try: module_instance = module_class(module.name, *args, **kwargs) except Exception: log.critical("error while activating the {} module".format(module.name), exc_info=1) return None log.info("activating the {} module".format(module.name)) return module_instance