From 94ea8d8266175509ddb2bc4cf48c273d948da766 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 23 Mar 2012 13:00:55 -0400 Subject: added TemplateHelper plugin to easily provide convenience methods to templates --- src/lib/Server/Plugin.py | 5 +- src/lib/Server/Plugins/TemplateHelper.py | 83 ++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/lib/Server/Plugins/TemplateHelper.py (limited to 'src/lib') diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py index 06de18f29..c48859a44 100644 --- a/src/lib/Server/Plugin.py +++ b/src/lib/Server/Plugin.py @@ -935,7 +935,7 @@ class SpecificData(object): logger.error("Failed to read file %s" % self.name) -class EntrySet: +class EntrySet(object): """Entry sets deal with the host- and group-specific entries.""" ignore = re.compile("^(\.#.*|.*~|\\..*\\.(sw[px])|.*\\.genshi_include)$") @@ -1011,7 +1011,8 @@ class EntrySet: spec = self.specificity_from_filename(event.filename) except SpecificityError: if not self.ignore.match(event.filename): - logger.error("Could not process filename %s; ignoring" % fpath) + logger.error("Could not process filename %s; ignoring" % + fpath) return self.entries[event.filename] = self.entry_type(fpath, spec, self.encoding) diff --git a/src/lib/Server/Plugins/TemplateHelper.py b/src/lib/Server/Plugins/TemplateHelper.py new file mode 100644 index 000000000..42eafed56 --- /dev/null +++ b/src/lib/Server/Plugins/TemplateHelper.py @@ -0,0 +1,83 @@ +import re +import imp +import sys +import logging +import Bcfg2.Server.Plugin + +logger = logging.getLogger(__name__) + +class HelperModule(Bcfg2.Server.Plugin.SpecificData): + _module_name_re = re.compile(r'([^/]+?)\.py') + + def __init__(self, name, specific, encoding): + Bcfg2.Server.Plugin.SpecificData.__init__(self, name, specific, + encoding) + match = self._module_name_re.search(self.name) + if match: + self._module_name = match.group(1) + else: + self._module_name = name + self._attrs = [] + + def handle_event(self, event): + Bcfg2.Server.Plugin.SpecificData.handle_event(self, event) + try: + module = imp.load_source(self._module_name, self.name) + except: + err = sys.exc_info()[1] + logger.error("TemplateHelper: Failed to import %s: %s" % + (self.name, err)) + return + + if not hasattr(module, "__export__"): + logger.error("TemplateHelper: %s has no __export__ list" % + self.name) + return + + for sym in module.__export__: + if sym not in self._attrs and hasattr(self, sym): + logger.warning("TemplateHelper: %s: %s is a reserved keyword, " + "skipping export" % (self.name, sym)) + setattr(self, sym, getattr(module, sym)) + # remove old exports + for sym in set(self._attrs) - set(module.__export__): + delattr(self, sym) + + self._attrs = module.__export__ + + +class HelperSet(Bcfg2.Server.Plugin.EntrySet): + ignore = re.compile("^(\.#.*|.*~|\\..*\\.(sw[px])|.*\.py[co])$") + + def __init__(self, path, fam, encoding, plugin_name): + fpattern = '[0-9A-Za-z_\-]+\.py' + self.plugin_name = plugin_name + Bcfg2.Server.Plugin.EntrySet.__init__(self, fpattern, path, + HelperModule, encoding) + fam.AddMonitor(path, self) + + def HandleEvent(self, event): + if (event.filename != self.path and + not self.ignore.match(event.filename)): + return self.handle_event(event) + + +class TemplateHelper(Bcfg2.Server.Plugin.Plugin, + Bcfg2.Server.Plugin.Connector): + """ A plugin to provide helper classes and functions to templates """ + name = 'TemplateHelper' + __author__ = 'chris.a.st.pierre@gmail.com' + + def __init__(self, core, datastore): + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + Bcfg2.Server.Plugin.Connector.__init__(self) + + try: + self.helpers = HelperSet(self.data, core.fam, core.encoding, + self.name) + except: + raise Bcfg2.Server.Plugin.PluginInitError + + def get_additional_data(self, metadata): + return dict([(h._module_name, h) + for h in list(self.helpers.entries.values())]) -- cgit v1.2.3-1-g7c22