def wikiPlugins(kind, cfg): """ Gets a dict containing the names of all plugins of <kind> as the key and the containing module name as the value. :param kind: what kind of modules we look for :rtype: dict :returns: plugin name to containing module name mapping """ # short-cut if we've loaded the dict already # (or already failed to load it) cache = cfg._site_plugin_lists if kind in cache: result = cache[kind] else: result = {} for modname in cfg._plugin_modules: try: module = pysupport.importName(modname, kind) packagepath = os.path.dirname(module.__file__) plugins = pysupport.getPluginModules(packagepath) for p in plugins: if p not in result: result[p] = '{0}.{1}'.format(modname, kind) except AttributeError: pass cache[kind] = result return result
def do_chart(pagename, request): """ Show page charts """ _ = request.getText if not request.user.may.read(pagename): msg = _("You are not allowed to view this page.") return request.page.send_page(request, msg=msg) if not request.cfg.chart_options: msg = _("Charts are not available!") return request.page.send_page(request, msg=msg) chart_type = request.form.get('type', [''])[0].strip() if not chart_type: msg = _('You need to provide a chart type!') return request.page.send_page(request, msg=msg) try: func = pysupport.importName("MoinMoin.stats." + chart_type, 'draw') except (ImportError, AttributeError): msg = _('Bad chart type "%s"!') % chart_type return request.page.send_page(request, msg=msg) func(pagename, request) raise MoinMoinNoFooter
def importWikiPlugin(cfg, kind, name, function): """ Import plugin from the wiki data directory We try to import only ONCE - then cache the plugin, even if we got None. This way we prevent expensive import of existing plugins for each call to a plugin. @param cfg: wiki config instance @param kind: what kind of module we want to import @param name: the name of the module @param function: the function name @rtype: callable @return: "function" of module "name" of kind "kind", or None """ global _wiki_plugins # Wiki plugins are located under 'wikiconfigname.plugin' module. modulename = '%s.plugin.%s.%s' % (cfg.siteid, kind, name) key = (modulename, function) try: # Try cache first - fast! plugin = _wiki_plugins[key] except KeyError: # Try to import from disk and cache result - slow! plugin = pysupport.importName(modulename, function) _wiki_plugins[key] = plugin return plugin
def importPlugin(cfg, kind, name, function="execute"): """ Import wiki or builtin plugin Returns an object from a plugin module or None if module or 'function' is not found. kind may be one of 'action', 'formatter', 'macro', 'processor', 'parser' or any other directory that exist in MoinMoin or data/plugin Wiki plugins will always override builtin plugins. If you want specific plugin, use either importWikiPlugin or importName directly. @param cfg: wiki config instance @param kind: what kind of module we want to import @param name: the name of the module @param function: the function name @rtype: callable @return: "function" of module "name" of kind "kind", or None """ # Try to import from the wiki plugin = importWikiPlugin(cfg, kind, name, function) if plugin is None: # Try to get the plugin from MoinMoin modulename = 'MoinMoin.%s.%s' % (kind, name) plugin = pysupport.importName(modulename, function) return plugin
def execute(pagename, request): """ Show page charts """ _ = request.getText if not request.user.may.read(pagename): request.theme.add_msg(_("You are not allowed to view this page."), "error") return request.page.send_page() if not request.cfg.chart_options: request.theme.add_msg(_("Charts are not available!"), "error") return request.page.send_page() chart_type = request.values.get('type', '').strip() if not chart_type: request.theme.add_msg(_('You need to provide a chart type!'), "error") return request.page.send_page() try: func = pysupport.importName("MoinMoin.stats.%s" % chart_type, 'draw') except (ImportError, AttributeError): request.theme.add_msg( _('Bad chart type "%s"!') % wikiutil.escape(chart_type), "error") return request.page.send_page() func(pagename, request)
def testExisting(self): """ pysupport: import wiki parser from moin succeed This tests if a module can be imported from the package MoinMoin. Should never fail! """ self.failUnless(pysupport.importName('MoinMoin.parser.wiki', 'Parser'))
def builtinPlugins(kind): """ Gets a list of modules in MoinMoin.'kind' :param kind: what kind of modules we look for :rtype: list :returns: module names """ modulename = "MoinMoin." + kind return pysupport.importName(modulename, "modules")
def builtinPlugins(kind): """ Gets a list of modules in MoinMoin.'kind' @param kind: what kind of modules we look for @rtype: list @return: module names """ modulename = "MoinMoin." + kind plugins = pysupport.importName(modulename, "modules") return plugins or []
def wikiPlugins(kind, cfg): """ Gets a list of modules in data/plugin/'kind' @param kind: what kind of modules we look for @rtype: list @return: module names """ # Wiki plugins are located in wikiconfig.plugin module modulename = '%s.plugin.%s' % (cfg.siteid, kind) plugins = pysupport.importName(modulename, "modules") return plugins or []
def testNonEsisting(self): """ pysupport: import nonexistent plugin return None """ name = 'abcdefghijkl' # Make sure that the file does not exists for suffix in ['.py', '.pyc']: path = os.path.join(self.parserdir, name + suffix) assert not os.path.exists(path), \ "Can't run test, path exists: %r" % path self.failIf(pysupport.importName('plugin.parser.%s' % name, 'Parser'))
def execute(macro, args, **kw): _ = macro.request.getText formatter = macro.request.formatter if not args: return (formatter.sysmsg(1) + formatter.text(_('You need to provide a chart type!')) + formatter.sysmsg(0)) func = pysupport.importName("MoinMoin.stats." + args, "linkto") if not func: return (formatter.sysmsg(1) + formatter.text(_('Bad chart type "%s"!') % args) + formatter.sysmsg(0)) return func(macro.formatter.page.page_name, macro.request)
def testExisting(self): """ pysupport: import existing wiki plugin Tests if a module can be imported from an arbitrary path like it is done in moin for plugins. Some strange bug in the old implementation failed on an import of os, cause os does a from os.path import that will stumble over a poisoned sys.modules. """ try: self.createTestPlugin() plugin = pysupport.importName(self.pluginModule, self.name) self.assertEqual(getattr(plugin, '__name__', None), self.name, 'Failed to import the test plugin') finally: self.deleteTestPlugin()
def macro_StatsChart(macro, chart_type=''): _ = macro.request.getText formatter = macro.request.formatter if not chart_type: return (formatter.sysmsg(1) + formatter.text(_('You need to provide a chart type!')) + formatter.sysmsg(0)) try: # stats module without 'linkto' will raise AttributeError func = pysupport.importName("MoinMoin.stats.%s" % chart_type, "linkto") except ImportError: return (formatter.sysmsg(1) + formatter.text(_('Bad chart type "%s"!') % chart_type) + formatter.sysmsg(0)) return func(macro.formatter.page.page_name, macro.request)
def testExisting(self): """ pysupport: import existing plugin succeed Tests if a module can be imported from an arbitrary path like it is done in moin for plugins. Some strange bug in the old implementation failed on an import of os, cause os does a from os.path import that will stumble over a poisoned sys.modules. """ # Save a test plugin pluginName = 'MoinMoinTestParser' data = ''' import sys, os class Parser: pass ''' # Plugin path does not include the suffix! pluginPath = os.path.join(self.parserdir, pluginName) # File must not exists - or we might destroy user data! for suffix in ['.py', '.pyc']: assert not os.path.exists(pluginPath + suffix), \ "Can't run test, path exists: %r" % path try: # Write test plugin f = file(pluginPath + '.py', 'w') f.write(data) f.close() modulename = request.cfg.siteid + '.plugin.parser.' + pluginName plugin = pysupport.importName(modulename, 'Parser') self.failUnless(plugin.__name__ == 'Parser', 'Failed to import the test plugin') finally: # Remove the test plugin, including the pyc file. for suffix in ['.py', '.pyc']: try: os.unlink(pluginPath + suffix) except OSError: pass
def execute(pagename, request): """ Show page charts """ _ = request.getText if not request.user.may.read(pagename): request.theme.add_msg(_("You are not allowed to view this page."), "error") return request.page.send_page() if not request.cfg.chart_options: request.theme.add_msg(_("Charts are not available!"), "error") return request.page.send_page() chart_type = request.values.get('type', '').strip() if not chart_type: request.theme.add_msg(_('You need to provide a chart type!'), "error") return request.page.send_page() try: func = pysupport.importName("MoinMoin.stats.%s" % chart_type, 'draw') except (ImportError, AttributeError): request.theme.add_msg(_('Bad chart type "%s"!') % wikiutil.escape(chart_type), "error") return request.page.send_page() func(pagename, request)
def testExisting(self): """ pysupport: import name from existing module """ from MoinMoin.parser import text_moin_wiki Parser = pysupport.importName('MoinMoin.parser.text_moin_wiki', 'Parser') assert Parser is text_moin_wiki.Parser
def loadLanguage(request, lang): """ Load text dictionary for a specific language. Note that while ISO language coded use a dash, like 'en-us', our languages files use '_' like 'en_us' because they are saved as Python source files. Raises an exception if this method is called from within itself (by the formatter). In that case, the translation file is buggy. Possible causes are having a text that is interpreted to again need a text in the same language. That means you cannot use the GetText macro in translated strings, nor any wiki markup that requires translated strings (eg. "attachment:"). """ from MoinMoin import caching cache = caching.CacheEntry(request, arena='i18n', key=lang) langfilename = os.path.join(os.path.dirname(__file__), filename(lang) + '.py') needsupdate = cache.needsUpdate(langfilename) if not needsupdate: try: (uc_texts, uc_unformatted) = pickle.loads(cache.content()) except (IOError,ValueError,pickle.UnpicklingError): #bad pickle data, no pickle needsupdate = 1 if needsupdate: from MoinMoin.util import pysupport lang_module = "MoinMoin.i18n." + filename(lang) texts = pysupport.importName(lang_module, "text") if not texts: return (None, None) meta = pysupport.importName(lang_module, "meta") encoding = meta['encoding'] # convert to unicode uc_texts = {} for idx in texts: uidx = idx.decode(encoding) utxt = texts[idx].decode(encoding) uc_texts[uidx] = utxt uc_unformatted = uc_texts.copy() # is this already on wiki markup? if meta.get('wikimarkup', False): # use the wiki parser now to replace some wiki markup with html text = "" global _done_markups if not _done_markups.has_key(lang): _done_markups[lang] = 1 for key in uc_texts: text = uc_texts[key] uc_texts[key] = formatMarkup(request, text) _done_markups[lang] = 2 else: if _done_markups[lang] == 1: raise Exception("Cyclic usage detected; you cannot have translated texts include translated texts again! " "This error might also occur because of things that are interpreted wiki-like inside translated strings. " "This time the error occurred while formatting %s." % text) cache.update(pickle.dumps((uc_texts, uc_unformatted), PICKLE_PROTOCOL)) return (uc_texts, uc_unformatted)
def do_chart(pagename, request): if request.user.may.read(pagename) and request.cfg.chart_options: chart_type = request.form['type'][0] func = pysupport.importName("MoinMoin.stats." + chart_type, "draw") func(pagename, request) raise MoinMoinNoFooter
def testNonEsisting(self): """ pysupport: import nonexistent wiki plugin fail """ if self.pluginExists(): raise TestSkiped('plugin exists: %s' % self.plugin) self.failIf(pysupport.importName(self.pluginModule, self.name))
def testNonExisting(self): """ pysupport: import nonexistent moin parser return None """ self.failIf(pysupport.importName('MoinMoin.parser.abcdefghijkl', 'Parser'))
def testExisting(self): """ pysupport: import name from existing module """ from MoinMoin.util.pysupport import importName t = pysupport.importName('MoinMoin.util.pysupport', 'importName') assert importName is t