diff --git a/.gitignore b/.gitignore index 89559c0b..a85c96eb 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,6 @@ target/ # Vagrant .vagrant Vagrantfile + +# Node JS stuff +node_modules/ diff --git a/nengo_gui/config.py b/nengo_gui/config.py index 91ad8118..eb02d041 100644 --- a/nengo_gui/config.py +++ b/nengo_gui/config.py @@ -1,9 +1,15 @@ import inspect +import logging +from pkg_resources import iter_entry_points import nengo import nengo_gui.components + +logger = logging.getLogger(__name__) + + def make_param(name, default): try: # the most recent way of making Parameter objects @@ -32,7 +38,15 @@ def __init__(self): make_param(name='has_layout', default=False)) - for clsname, cls in inspect.getmembers(nengo_gui.components): + external_components = { + ep.name: ep.load() + for ep in iter_entry_points(group='nengo_gui.components')} + logger.info( + 'Components added to config: %s', external_components.keys()) + + components = inspect.getmembers(nengo_gui.components) + components += external_components.items() + for clsname, cls in components: if inspect.isclass(cls): if issubclass(cls, nengo_gui.components.component.Component): if cls != nengo_gui.components.component.Component: diff --git a/nengo_gui/guibackend.py b/nengo_gui/guibackend.py index 707afb71..09164c87 100644 --- a/nengo_gui/guibackend.py +++ b/nengo_gui/guibackend.py @@ -9,6 +9,8 @@ import os import os.path import pkgutil +from pkg_resources import iter_entry_points, safe_name +import posixpath try: from urllib.parse import unquote except ImportError: # Python 2.7 @@ -98,6 +100,7 @@ class GuiRequestHandler(server.HttpWsRequestHandler): '/': 'serve_main', '/login': 'login_page', '/static': 'serve_static', + '/plugin': 'serve_plugin', '/browse': 'browse', '/favicon.ico': 'serve_favicon', } @@ -147,12 +150,20 @@ def serve_static(self): data = pkgutil.get_data('nengo_gui', fn) return server.HttpResponse(data, mimetype) + @RequireAuthentication('/login') + def serve_plugin(self): + """Routes request to plugin.""" + res = posixpath.relpath(self.resource, '/plugin') + dist_name, plugin_name, path = res.split('/', 2) + plugin = self.server.plugins[safe_name(dist_name) + '/' + plugin_name] + return plugin.serve('/' + path) + @RequireAuthentication('/login') def browse(self): r = [b'