diff --git a/datasette/app.py b/datasette/app.py index 919a0a51..df6b6d60 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -31,7 +31,6 @@ from .utils import ( escape_css_string, escape_sqlite, format_bytes, - get_plugins, module_from_path, sqlite3, to_css_class, @@ -47,7 +46,7 @@ from .utils.asgi import ( asgi_send_redirect, ) from .tracer import AsgiTracer -from .plugins import pm, DEFAULT_PLUGINS +from .plugins import pm, DEFAULT_PLUGINS, get_plugins from .version import __version__ app_root = Path(__file__).parent.parent @@ -459,7 +458,7 @@ class Datasette: } def plugins(self, show_all=False): - ps = list(get_plugins(pm)) + ps = list(get_plugins()) if not show_all: ps = [p for p in ps if p["name"] not in DEFAULT_PLUGINS] return [ @@ -613,13 +612,12 @@ class Datasette: template_paths = [] if self.template_dir: template_paths.append(self.template_dir) - template_paths.extend( - [ - plugin["templates_path"] - for plugin in get_plugins(pm) - if plugin["templates_path"] - ] - ) + plugin_template_paths = [ + plugin["templates_path"] + for plugin in get_plugins() + if plugin["templates_path"] + ] + template_paths.extend(plugin_template_paths) template_paths.append(default_templates) template_loader = ChoiceLoader( [ @@ -661,7 +659,7 @@ class Datasette: add_route(asgi_static(dirname), r"/" + path + "/(?P.*)$") # Mount any plugin static/ directories - for plugin in get_plugins(pm): + for plugin in get_plugins(): if plugin["static_path"]: add_route( asgi_static(plugin["static_path"]), diff --git a/datasette/plugins.py b/datasette/plugins.py index 6e7cfccd..6e1e785e 100644 --- a/datasette/plugins.py +++ b/datasette/plugins.py @@ -1,5 +1,6 @@ import importlib import pluggy +import pkg_resources import sys from . import hookspecs @@ -22,3 +23,35 @@ if not hasattr(sys, "_called_from_test"): for plugin in DEFAULT_PLUGINS: mod = importlib.import_module(plugin) pm.register(mod, plugin) + + +def get_plugins(): + plugins = [] + plugin_to_distinfo = dict(pm.list_plugin_distinfo()) + for plugin in pm.get_plugins(): + static_path = None + templates_path = None + if plugin.__name__ not in DEFAULT_PLUGINS: + try: + if pkg_resources.resource_isdir(plugin.__name__, "static"): + static_path = pkg_resources.resource_filename( + plugin.__name__, "static" + ) + if pkg_resources.resource_isdir(plugin.__name__, "templates"): + templates_path = pkg_resources.resource_filename( + plugin.__name__, "templates" + ) + except (KeyError, ImportError): + # Caused by --plugins_dir= plugins - KeyError/ImportError thrown in Py3.5 + pass + plugin_info = { + "name": plugin.__name__, + "static_path": static_path, + "templates_path": templates_path, + } + distinfo = plugin_to_distinfo.get(plugin) + if distinfo: + plugin_info["version"] = distinfo.version + plugin_info["name"] = distinfo.project_name + plugins.append(plugin_info) + return plugins diff --git a/datasette/utils/__init__.py b/datasette/utils/__init__.py index 79ac8e02..be99f890 100644 --- a/datasette/utils/__init__.py +++ b/datasette/utils/__init__.py @@ -5,7 +5,6 @@ import click import hashlib import json import os -import pkg_resources import re import shlex import tempfile @@ -616,35 +615,6 @@ def module_from_path(path, name): return mod -def get_plugins(pm): - plugins = [] - plugin_to_distinfo = dict(pm.list_plugin_distinfo()) - for plugin in pm.get_plugins(): - static_path = None - templates_path = None - try: - if pkg_resources.resource_isdir(plugin.__name__, "static"): - static_path = pkg_resources.resource_filename(plugin.__name__, "static") - if pkg_resources.resource_isdir(plugin.__name__, "templates"): - templates_path = pkg_resources.resource_filename( - plugin.__name__, "templates" - ) - except (KeyError, ImportError): - # Caused by --plugins_dir= plugins - KeyError/ImportError thrown in Py3.5 - pass - plugin_info = { - "name": plugin.__name__, - "static_path": static_path, - "templates_path": templates_path, - } - distinfo = plugin_to_distinfo.get(plugin) - if distinfo: - plugin_info["version"] = distinfo.version - plugin_info["name"] = distinfo.project_name - plugins.append(plugin_info) - return plugins - - async def resolve_table_and_format(table_and_format, table_exists, allowed_formats=[]): if "." in table_and_format: # Check if a table exists with this exact name diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 44ac0b8e..7d734056 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -1,5 +1,6 @@ from bs4 import BeautifulSoup as Soup from .fixtures import app_client, make_app_client, TEMP_PLUGIN_SECRET_FILE # noqa +from datasette.plugins import get_plugins, DEFAULT_PLUGINS from datasette.utils import sqlite3 import base64 import json @@ -241,3 +242,13 @@ def test_plugins_async_template_function(restore_working_directory): sqlite3.connect(":memory:").execute("select sqlite_version()").fetchone()[0] ) assert expected == extra_from_awaitable_function + + +def test_default_plugins_have_no_templates_path_or_static_path(): + # The default plugins that ship with Datasette should have their static_path and + # templates_path all set to None + plugins = get_plugins() + for plugin in plugins: + if plugin["name"] in DEFAULT_PLUGINS: + assert None is plugin["static_path"] + assert None is plugin["templates_path"]