comparison MoinMoin/wikiutil.py @ 51:54d5932d5a03

merge moin--main--1.3--patch-930: fix error handling in plugins, fix broken chart action Patches applied: * arch@arch.thinkmo.de--2003-archives/moin--main--1.3--patch-930 fix error handling in plugins, fix broken chart action * nirs@freeshell.org--2005/moin--fix--1.3--patch-50 merge from main * nirs@freeshell.org--2005/moin--fix--1.3--patch-51 fix error handling in plugins * nirs@freeshell.org--2005/moin--fix--1.3--patch-52 merge from main * nirs@freeshell.org--2005/moin--fix--1.3--patch-53 update changes with chart action fix imported from: moin--main--1.5--patch-52
author Nir Soffer <nirs@freeshell.org>
date Thu, 29 Sep 2005 00:36:27 +0000
parents f0af060fb82b
children 699811601bed
comparison
equal deleted inserted replaced
50:69dfbae549ac 51:54d5932d5a03
566 ############################################################################# 566 #############################################################################
567 567
568 def importPlugin(cfg, kind, name, function="execute"): 568 def importPlugin(cfg, kind, name, function="execute"):
569 """ Import wiki or builtin plugin 569 """ Import wiki or builtin plugin
570 570
571 Returns an object from a plugin module or None if module or 571 Returns function from a plugin module. If the module can not be
572 'function' is not found. 572 imported, raise ImportError. If function is not there, raise
573 AttributeError.
573 574
574 kind may be one of 'action', 'formatter', 'macro', 'processor', 575 kind may be one of 'action', 'formatter', 'macro', 'processor',
575 'parser' or any other directory that exist in MoinMoin or 576 'parser' or any other directory that exist in MoinMoin or
576 data/plugin 577 data/plugin
577 578
583 @param name: the name of the module 584 @param name: the name of the module
584 @param function: the function name 585 @param function: the function name
585 @rtype: callable 586 @rtype: callable
586 @return: "function" of module "name" of kind "kind", or None 587 @return: "function" of module "name" of kind "kind", or None
587 """ 588 """
588 # Try to import from the wiki 589 try:
589 plugin = importWikiPlugin(cfg, kind, name, function) 590 plugin = importWikiPlugin(cfg, kind, name, function)
590 if plugin is None: 591 except ImportError:
591 # Try to get the plugin from MoinMoin
592 modulename = 'MoinMoin.%s.%s' % (kind, name) 592 modulename = 'MoinMoin.%s.%s' % (kind, name)
593 plugin = pysupport.importName(modulename, function) 593 plugin = pysupport.importName(modulename, function)
594
595 return plugin 594 return plugin
596 595
597 def importWikiPlugin(cfg, kind, name, function): 596 def importWikiPlugin(cfg, kind, name, function):
598 """ Import plugin from the wiki data directory 597 """ Import and cache plugin from the wiki data directory
599 598
599 Returns function from a plugin module. If the module can not be
600 imported, raise ImportError. If function is not there, raise
601 AttributeError.
602
600 We try to import only ONCE - then cache the plugin, even if we got 603 We try to import only ONCE - then cache the plugin, even if we got
601 None. This way we prevent expensive import of existing plugins for 604 None. This way we prevent expensive import of existing plugins for
602 each call to a plugin. 605 each call to a plugin.
603 606
604 @param cfg: wiki config instance 607 @param cfg: wiki config instance
605 @param kind: what kind of module we want to import 608 @param kind: what kind of module we want to import
606 @param name: the name of the module 609 @param name: the name of the module
607 @param function: the function name 610 @param function: the function name
608 @rtype: callable 611 @rtype: callable
609 @return: "function" of module "name" of kind "kind", or None 612 @return: "function" of module "name" of kind "kind"
610 """ 613 """
611 614 try:
615 wikiPlugins = cfg._wiki_plugins
616 except AttributeError:
617 wikiPlugins = cfg._wiki_plugins = {}
618
612 # Wiki plugins are located under 'wikiconfigname.plugin' module. 619 # Wiki plugins are located under 'wikiconfigname.plugin' module.
613 modulename = '%s.plugin.%s.%s' % (cfg.siteid, kind, name) 620 modulename = '%s.plugin.%s.%s' % (cfg.siteid, kind, name)
614 key = (modulename, function) 621 # Try cache or import once from disk
615 try: 622 try:
616 # Try cache first - fast! 623 module = wikiPlugins[modulename]
617 plugin = cfg._wiki_plugins[key] 624 except KeyError:
618 except (KeyError, AttributeError):
619 # Try to import from disk and cache result - slow!
620 plugin = pysupport.importName(modulename, function)
621 try: 625 try:
622 cfg._wiki_plugins[key] = plugin 626 module = __import__(modulename, globals(), {}, ['dummy'])
623 except AttributeError: 627 except ImportError:
624 cfg._wiki_plugins = {key: plugin} 628 module = wikiPlugins[modulename] = None
625 return plugin 629 if module is None:
630 raise ImportError
631 return getattr(module, function)
626 632
627 # If we use threads, make this function thread safe 633 # If we use threads, make this function thread safe
628 if config.use_threads: 634 if config.use_threads:
629 importWikiPlugin = pysupport.makeThreadSafe(importWikiPlugin) 635 importWikiPlugin = pysupport.makeThreadSafe(importWikiPlugin)
630 636
637
631 def builtinPlugins(kind): 638 def builtinPlugins(kind):
632 """ Gets a list of modules in MoinMoin.'kind' 639 """ Gets a list of modules in MoinMoin.'kind'
633 640
634 @param kind: what kind of modules we look for 641 @param kind: what kind of modules we look for
635 @rtype: list 642 @rtype: list
636 @return: module names 643 @return: module names
637 """ 644 """
638 modulename = "MoinMoin." + kind 645 modulename = "MoinMoin." + kind
639 plugins = pysupport.importName(modulename, "modules") 646 return pysupport.importName(modulename, "modules")
640 return plugins or []
641 647
642 648
643 def wikiPlugins(kind, cfg): 649 def wikiPlugins(kind, cfg):
644 """ Gets a list of modules in data/plugin/'kind' 650 """ Gets a list of modules in data/plugin/'kind'
651
652 Require valid plugin directory. e.g missing 'parser' directory or
653 missing '__init__.py' file will raise errors.
645 654
646 @param kind: what kind of modules we look for 655 @param kind: what kind of modules we look for
647 @rtype: list 656 @rtype: list
648 @return: module names 657 @return: module names
649 """ 658 """
650 # Wiki plugins are located in wikiconfig.plugin module 659 # Wiki plugins are located in wikiconfig.plugin module
651 modulename = '%s.plugin.%s' % (cfg.siteid, kind) 660 modulename = '%s.plugin.%s' % (cfg.siteid, kind)
652 plugins = pysupport.importName(modulename, "modules") 661 return pysupport.importName(modulename, "modules")
653 return plugins or []
654 662
655 663
656 def getPlugins(kind, cfg): 664 def getPlugins(kind, cfg):
657 """ Gets a list of plugin names of kind 665 """ Gets a list of plugin names of kind
658 666
690 """ 698 """
691 if not hasattr(cfg, '_EXT_TO_PARSER'): 699 if not hasattr(cfg, '_EXT_TO_PARSER'):
692 import types 700 import types
693 etp, etd = {}, None 701 etp, etd = {}, None
694 for pname in getPlugins('parser', cfg): 702 for pname in getPlugins('parser', cfg):
695 Parser = importPlugin(cfg, 'parser', pname, 'Parser') 703 try:
696 if Parser is not None: 704 Parser = importPlugin(cfg, 'parser', pname, 'Parser')
697 if hasattr(Parser, 'extensions'): 705 except ImportError:
698 exts = Parser.extensions 706 continue
699 if type(exts) == types.ListType: 707 if hasattr(Parser, 'extensions'):
700 for ext in Parser.extensions: 708 exts = Parser.extensions
701 etp[ext] = Parser 709 if type(exts) == types.ListType:
702 elif str(exts) == '*': 710 for ext in Parser.extensions:
703 etd = Parser 711 etp[ext] = Parser
712 elif str(exts) == '*':
713 etd = Parser
704 cfg._EXT_TO_PARSER = etp 714 cfg._EXT_TO_PARSER = etp
705 cfg._EXT_TO_PARSER_DEFAULT = etd 715 cfg._EXT_TO_PARSER_DEFAULT = etd
706 716
707 return cfg._EXT_TO_PARSER.get(extension, cfg._EXT_TO_PARSER_DEFAULT) 717 return cfg._EXT_TO_PARSER.get(extension, cfg._EXT_TO_PARSER_DEFAULT)
708 718