1 # Copyright (C) 2013 Simo Sorce <simo@redhat.com>
3 # see file 'COPYING' for use and warranty information
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 from ipsilon.util.config import Config
23 from ipsilon.util.data import AdminStore
24 from ipsilon.util.log import Log
27 class Plugins(object):
30 self._providers_tree = None
32 def _load_class(self, tree, class_type, file_name, *pargs):
33 cherrypy.log.error('Check module %s for class %s' % (file_name,
35 name, ext = os.path.splitext(os.path.split(file_name)[-1])
37 if ext.lower() == '.py':
38 mod = imp.load_source(name, file_name)
39 # elif ext.lower() == '.pyc':
40 # mod = imp.load_compiled(name, file_name)
43 except Exception, e: # pylint: disable=broad-except
44 cherrypy.log.error('Failed to load "%s" module: [%s]' % (name, e))
47 if hasattr(mod, class_type):
48 instance = getattr(mod, class_type)(*pargs)
49 public_name = getattr(instance, 'name', name)
50 tree[public_name] = instance
51 cherrypy.log.error('Added module %s as %s' % (name, public_name))
53 def _load_classes(self, tree, path, class_type, *pargs):
56 files = os.listdir(path)
57 except Exception, e: # pylint: disable=broad-except
58 cherrypy.log.error('No modules in %s: [%s]' % (path, e))
62 filename = os.path.join(path, name)
63 self._load_class(tree, class_type, filename, *pargs)
65 def get_plugins(self, path, class_type, *pargs):
67 self._load_classes(plugins, path, class_type, *pargs)
71 class PluginLoader(Log):
73 def __init__(self, baseobj, facility, plugin_type):
74 self._pathname, _ = os.path.split(inspect.getfile(baseobj))
75 self.facility = facility
76 self._plugin_type = plugin_type
77 self.available = dict()
81 # Defer initialization or instantiating the store will fail at load
82 # time when used with Installer plugins as the cherrypy config context
83 # is created after all Installer plugins are loaded.
87 self.__data = AdminStore()
91 def is_readonly(self):
92 return self._data.is_readonly
94 def get_plugins(self):
96 return p.get_plugins(self._pathname, self._plugin_type, self)
98 def refresh_enabled(self):
99 config = self._data.load_options(self.facility, name='global')
102 if 'enabled' in config:
103 self.enabled = config['enabled'].split(',')
105 def get_plugin_data(self):
106 self.available = self.get_plugins()
107 self.refresh_enabled()
109 def save_enabled(self, enabled):
111 self._data.save_options(self.facility, 'global',
112 {'enabled': ','.join(enabled)})
114 self._data.delete_options(self.facility, 'global',
116 self.debug('Plugin enabled state saved: %s' % enabled)
117 self.refresh_enabled()
120 class PluginInstaller(PluginLoader):
121 def __init__(self, baseobj, facility):
122 super(PluginInstaller, self).__init__(baseobj, facility, 'Installer')
125 class PluginObject(Log):
127 def __init__(self, plugins):
130 self._data = AdminStore()
131 self._plugins = plugins
132 self.is_enabled = False
135 def is_readonly(self):
136 return self._data.is_readonly
141 def on_disable(self):
144 def save_enabled_state(self):
146 self._plugins.refresh_enabled()
147 enabled.extend(self._plugins.enabled)
149 if self.name not in enabled:
150 enabled.append(self.name)
152 if self.name in enabled:
153 enabled.remove(self.name)
154 self._plugins.save_enabled(enabled)
160 self.refresh_plugin_config()
162 self.is_enabled = True
163 self.debug('Plugin enabled: %s' % self.name)
166 if not self.is_enabled:
171 self.is_enabled = False
172 self.debug('Plugin disabled: %s' % self.name)
174 def import_config(self, config):
175 self._config = config
177 def export_config(self):
180 def get_plugin_config(self):
181 return self._data.load_options(self._plugins.facility, self.name)
183 def refresh_plugin_config(self):
184 config = self.get_plugin_config()
186 self.import_config(config)
188 def save_plugin_config(self, config=None):
190 config = self.export_config()
192 self._data.save_options(self._plugins.facility, self.name, config)
194 def get_data(self, idval=None, name=None, value=None):
195 return self._data.get_data(self.name, idval=idval, name=name,
198 def save_data(self, data):
199 self._data.save_data(self.name, data)
201 def new_datum(self, datum):
202 self._data.new_datum(self.name, datum)
204 def del_datum(self, idval):
205 self._data.del_datum(self.name, idval)
207 def wipe_config_values(self):
208 self._data.delete_options(self._plugins.facility, self.name, None)
211 self._data.wipe_data(self.name)
214 class PluginConfig(Log):
219 def new_config(self, name, *config_args):
220 self._config = Config(name, *config_args)
222 def get_config_obj(self):
223 if self._config is None:
224 raise AttributeError('Config not initialized')
227 def import_config(self, config):
229 raise AttributeError('Config not initialized, cannot import')
231 for key, value in config.iteritems():
232 if key in self._config:
233 self._config[key].import_value(str(value))
235 def export_config(self):
237 for name, option in self._config.iteritems():
238 config[name] = option.export_value()
241 def get_config_value(self, name):
243 raise AttributeError('Config not initialized')
244 return self._config[name].get_value()
246 def set_config_value(self, name, value):
248 raise AttributeError('Config not initialized')
249 return self._config[name].set_value(value)