3 # Copyright (C) 2013 Simo Sorce <simo@redhat.com>
5 # see file 'COPYING' for use and warranty information
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 from ipsilon.util.config import Config
25 from ipsilon.util.data import AdminStore
26 from ipsilon.util.log import Log
29 class Plugins(object):
32 self._providers_tree = None
34 def _load_class(self, tree, class_type, file_name, *pargs):
35 cherrypy.log.error('Check module %s for class %s' % (file_name,
37 name, ext = os.path.splitext(os.path.split(file_name)[-1])
39 if ext.lower() == '.py':
40 mod = imp.load_source(name, file_name)
41 # elif ext.lower() == '.pyc':
42 # mod = imp.load_compiled(name, file_name)
45 except Exception, e: # pylint: disable=broad-except
46 cherrypy.log.error('Failed to load "%s" module: [%s]' % (name, e))
49 if hasattr(mod, class_type):
50 instance = getattr(mod, class_type)(*pargs)
51 public_name = getattr(instance, 'name', name)
52 tree[public_name] = instance
53 cherrypy.log.error('Added module %s as %s' % (name, public_name))
55 def _load_classes(self, tree, path, class_type, *pargs):
58 files = os.listdir(path)
59 except Exception, e: # pylint: disable=broad-except
60 cherrypy.log.error('No modules in %s: [%s]' % (path, e))
64 filename = os.path.join(path, name)
65 self._load_class(tree, class_type, filename, *pargs)
67 def get_plugins(self, path, class_type, *pargs):
69 self._load_classes(plugins, path, class_type, *pargs)
73 class PluginLoader(Log):
75 def __init__(self, baseobj, facility, plugin_type):
76 self._pathname, _ = os.path.split(inspect.getfile(baseobj))
77 self.facility = facility
78 self._plugin_type = plugin_type
79 self.available = dict()
83 # Defer initialization or instantiating the store will fail at load
84 # time when used with Installer plugins as the cherrypy config context
85 # is created after all Installer plugins are loaded.
89 self.__data = AdminStore()
93 def is_readonly(self):
94 return self._data.is_readonly
96 def get_plugins(self):
98 return p.get_plugins(self._pathname, self._plugin_type, self)
100 def refresh_enabled(self):
101 config = self._data.load_options(self.facility, name='global')
104 if 'enabled' in config:
105 self.enabled = config['enabled'].split(',')
107 def get_plugin_data(self):
108 self.available = self.get_plugins()
109 self.refresh_enabled()
111 def save_enabled(self, enabled):
113 self._data.save_options(self.facility, 'global',
114 {'enabled': ','.join(enabled)})
116 self._data.delete_options(self.facility, 'global',
118 self.debug('Plugin enabled state saved: %s' % enabled)
119 self.refresh_enabled()
122 class PluginInstaller(PluginLoader):
123 def __init__(self, baseobj, facility):
124 super(PluginInstaller, self).__init__(baseobj, facility, 'Installer')
127 class PluginObject(Log):
129 def __init__(self, plugins):
132 self._data = AdminStore()
133 self._plugins = plugins
134 self.is_enabled = False
137 def is_readonly(self):
138 return self._data.is_readonly
143 def on_disable(self):
146 def save_enabled_state(self):
148 self._plugins.refresh_enabled()
149 enabled.extend(self._plugins.enabled)
151 if self.name not in enabled:
152 enabled.append(self.name)
154 if self.name in enabled:
155 enabled.remove(self.name)
156 self._plugins.save_enabled(enabled)
162 self.refresh_plugin_config()
164 self.is_enabled = True
165 self.debug('Plugin enabled: %s' % self.name)
168 if not self.is_enabled:
173 self.is_enabled = False
174 self.debug('Plugin disabled: %s' % self.name)
176 def import_config(self, config):
177 self._config = config
179 def export_config(self):
182 def get_plugin_config(self):
183 return self._data.load_options(self._plugins.facility, self.name)
185 def refresh_plugin_config(self):
186 config = self.get_plugin_config()
188 self.import_config(config)
190 def save_plugin_config(self, config=None):
192 config = self.export_config()
194 self._data.save_options(self._plugins.facility, self.name, config)
196 def get_data(self, idval=None, name=None, value=None):
197 return self._data.get_data(self.name, idval=idval, name=name,
200 def save_data(self, data):
201 self._data.save_data(self.name, data)
203 def new_datum(self, datum):
204 self._data.new_datum(self.name, datum)
206 def del_datum(self, idval):
207 self._data.del_datum(self.name, idval)
209 def wipe_config_values(self):
210 self._data.delete_options(self._plugins.facility, self.name, None)
213 self._data.wipe_data(self.name)
216 class PluginConfig(Log):
221 def new_config(self, name, *config_args):
222 self._config = Config(name, *config_args)
224 def get_config_obj(self):
225 if self._config is None:
226 raise AttributeError('Config not initialized')
229 def import_config(self, config):
231 raise AttributeError('Config not initialized, cannot import')
233 for key, value in config.iteritems():
234 if key in self._config:
235 self._config[key].import_value(str(value))
237 def export_config(self):
239 for name, option in self._config.iteritems():
240 config[name] = option.export_value()
243 def get_config_value(self, name):
245 raise AttributeError('Config not initialized')
246 return self._config[name].get_value()
248 def set_config_value(self, name, value):
250 raise AttributeError('Config not initialized')
251 return self._config[name].set_value(value)