Source code for lib_openmolar.common.plugin_tools.plugin_handler
#! /usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
## ##
## Copyright 2010, Neil Wallace <rowinggolfer@googlemail.com> ##
## ##
## 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 <http://www.gnu.org/licenses/>. ##
## ##
###############################################################################
import inspect
import logging
import os
import sys
import zipfile
import zipimport
from lib_openmolar.common import Plugin
from PyQt4.QtCore import QResource
[docs]class PluginHandler(object):
'''
A class to verify and install plugins
'''
#: locations of directories where plugins reside
PLUGIN_DIRS = []
#: locations of directories where naked plugins reside
NAKED_PLUGIN_DIRS = []
_plugins = []
_fee_scales = []
[docs] def get_pluggable_classes(self, module):
'''
Args:
module (module object)
generates a list of all classes which are subclassed
from lib_openmolar.client.Plugin in the module "module"
'''
for name in dir(module):
obj = getattr(module, name)
## check is this object is a class.. and that it inherits
## from Plugin.. (but is not the Plugin base class itself!)
## hence issubclass wouldn't work
if inspect.isclass(obj) and Plugin in obj.mro()[1:]:
klass = obj()
yield klass
[docs] def get_modules(self, plugin_dir):
'''
finds all modules in plugin_dir
'''
sys.path.insert(0, str(plugin_dir))
for file_ in os.listdir(str(plugin_dir)):
full_path = os.path.join(str(plugin_dir), file_)
if file_.endswith(".py"):
LOGGER.info("NAKED PLUGIN FOUND '%s'"% full_path)
if plugin_dir in self.NAKED_PLUGIN_DIRS:
module = file_.replace('.py','')
mod = __import__(module)
yield mod
else:
LOGGER.info(
'NOT COMPILING %s is not a known store for naked plugins'%
plugin_dir)
elif zipfile.is_zipfile(full_path):
module = file_.replace('.zip','')
try:
z = zipimport.zipimporter(full_path)
mod = z.load_module(module)
yield mod
except (zipimport.ZipImportError, zipfile.BadZipfile) as e:
LOGGER.exception ("incompatible plugin '%s'"% full_path)
[docs] def get_plugins(self, plugin_dir):
'''
peruses a directory and finds all plugins
'''
i = 0
for mod in self.get_modules(plugin_dir):
plugins = self.get_pluggable_classes(mod)
for plugin in plugins:
self.install_plugin(plugin)
i += 1
return i
[docs] def load_plugins(self):
'''
this function is called by the client application to load plugins
'''
LOGGER.info ("loading plugins...")
i = 0
for plugin_dir in self.PLUGIN_DIRS:
LOGGER.info ("looking for plugins in directory %s"% plugin_dir)
try:
i += self.get_plugins(plugin_dir)
except Exception as e:
LOGGER.exception ("Exception loading plugin")
LOGGER.info("%d plugin(s) loaded"% i)
[docs] def install_plugin(self, plugin):
'''
installs a plugin (of type BasePlugin)
'''
if plugin.TYPE == plugin.FEE_SCALE:
self.install_fee_scale(plugin)
try:
LOGGER.debug("setting up plugin %s"% plugin)
plugin.setup_plugin()
except Exception, e:
LOGGER.exception(
"Exception during plugin.setup_plugin '%s'"% plugin.name)
self._plugins.append(plugin)
@property
[docs] def plugins(self):
'''
a list of all plugins (of type BasePlugin)
'''
return self._plugins
[docs] def install_fee_scale(self, fee_scale):
'''
installs a fee_scale (of type BasePlugin)
'''
LOGGER.info ("installing fee_scale %s"% fee_scale)
self._fee_scales.append(fee_scale)
@property
[docs] def fee_scales(self):
'''
a list of all fee_scales installed (fee_scale = a type of BasePlugin)
'''
return sorted(self._fee_scales)
if __name__ == "__main__":
import lib_openmolar.admin
logging.basicConfig(level = logging.DEBUG)
ph = PluginHandler()
ph.PLUGIN_DIRS = [
"/home/neil/openmolar/hg_openmolar/plugins",
"/home/neil/openmolar/hg_openmolar/plugins/src"]
ph.NAKED_PLUGIN_DIRS = [
"/home/neil/openmolar/hg_openmolar/plugins/src",
]
ph.load_plugins()