X-Git-Url: http://git.tremily.us/?a=blobdiff_plain;f=hooke%2Fplugin%2F__init__.py;h=2418b69d5d3903c95b10ea781265f8678388d51a;hb=62cfb3bde4faa22da8d131571dc6f093682a0cca;hp=edef66aa98eef405bfdb419670d41617ba0aae15;hpb=b43edada38d9884b169730002d76321e00957745;p=hooke.git diff --git a/hooke/plugin/__init__.py b/hooke/plugin/__init__.py index edef66a..2418b69 100644 --- a/hooke/plugin/__init__.py +++ b/hooke/plugin/__init__.py @@ -1,3 +1,21 @@ +# Copyright (C) 2010 W. Trevor King +# +# This file is part of Hooke. +# +# Hooke is free software: you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# Hooke is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with Hooke. If not, see +# . + """The `plugin` module provides optional submodules that add new Hooke commands. @@ -7,17 +25,16 @@ All of the science happens in here. import ConfigParser as configparser from ..config import Setting -from ..util.graph import Node, Graph +from ..util.pluggable import IsSubclass, construct_graph PLUGIN_MODULES = [ # ('autopeak', True), # ('curvetools', True), ('cut', True), - ('debug', True), # ('fit', True), # ('flatfilts-rolf', True), -# ('flatfilts', True), + ('flatfilt', True), # ('generalclamp', True), # ('generaltccd', True), # ('generalvclamp', True), @@ -32,7 +49,6 @@ PLUGIN_MODULES = [ # ('review', True), # ('showconvoluted', True), # ('superimpose', True), - ('system', True), # ('tutorial', True), ] """List of plugin modules and whether they should be included by @@ -40,7 +56,12 @@ default. TODO: autodiscovery """ BUILTIN_MODULES = [ + 'config', + 'curve', + 'debug', + 'note', 'playlist', + 'system', ] """List of builtin modules. TODO: autodiscovery """ @@ -62,9 +83,10 @@ class Plugin (object): self.name = name self.setting_section = '%s plugin' % self.name self.config = {} + self._commands = [] def dependencies(self): - """Return a list of :class:`Plugin`\s we require.""" + """Return a list of names of :class:`Plugin`\s we require.""" return [] def default_settings(self): @@ -77,10 +99,21 @@ class Plugin (object): """ return [] + def _setup_commands(self): + """Perform internal setup on stored commands. + + Currently: + + * Adds a `plugin` attribute to each command so they can access + the plugin configuration with `.plugin.config`. + """ + for command in self._commands: + command.plugin = self + def commands(self): """Return a list of :class:`hooke.command.Command`\s provided. """ - return [] + return list(self._commands) class Builtin (Plugin): """A required collection of Hooke commands. @@ -92,78 +125,6 @@ class Builtin (Plugin): # Construct plugin dependency graph and load plugin instances. -def construct_graph(this_modname, submodnames, class_selector, - assert_name_match=True): - """Search the submodules `submodnames` of a module `this_modname` - for class objects for which `class_selector(class)` returns - `True`. These classes are instantiated, and the `instance.name` - is compared to the `submodname` (if `assert_name_match` is - `True`). - - The instances are further arranged into a dependency - :class:`hooke.util.graph.Graph` according to their - `instance.dependencies()` values. The topologically sorted graph - is returned. - """ - instances = {} - for submodname in submodnames: - count = len([s for s in submodnames if s == submodname]) - assert count > 0, 'No %s entries: %s' % (submodname, submodnames) - assert count == 1, 'Multiple (%d) %s entries: %s' \ - % (count, submodname, submodnames) - this_mod = __import__(this_modname, fromlist=[submodname]) - submod = getattr(this_mod, submodname) - for objname in dir(submod): - obj = getattr(submod, objname) - if class_selector(obj): - instance = obj() - if assert_name_match == True and instance.name != submodname: - raise Exception( - 'Instance name %s does not match module name %s' - % (instance.name, submodname)) - instances[instance.name] = instance - graph = Graph([Node([instances[name] for name in i.dependencies()], - data=i) - for i in instances.values()]) - graph.topological_sort() - return graph - -class IsSubclass (object): - """A safe subclass comparator. - - Examples - -------- - - >>> class A (object): - ... pass - >>> class B (A): - ... pass - >>> C = 5 - >>> is_subclass = IsSubclass(A) - >>> is_subclass(A) - True - >>> is_subclass = IsSubclass(A, blacklist=[A]) - >>> is_subclass(A) - False - >>> is_subclass(B) - True - >>> is_subclass(C) - False - """ - def __init__(self, base_class, blacklist=None): - self.base_class = base_class - if blacklist == None: - blacklist = [] - self.blacklist = blacklist - def __call__(self, other): - try: - subclass = issubclass(other, self.base_class) - except TypeError: - return False - if other in self.blacklist: - return False - return subclass - PLUGIN_GRAPH = construct_graph( this_modname=__name__, submodnames=[name for name,include in PLUGIN_MODULES] + BUILTIN_MODULES,