2018-04-16 00:56:15 +00:00
|
|
|
from pluggy import HookimplMarker
|
|
|
|
from pluggy import HookspecMarker
|
|
|
|
|
2018-08-28 08:35:21 +00:00
|
|
|
hookspec = HookspecMarker("datasette")
|
|
|
|
hookimpl = HookimplMarker("datasette")
|
2018-04-16 00:56:15 +00:00
|
|
|
|
|
|
|
|
2020-06-13 17:55:41 +00:00
|
|
|
@hookspec
|
|
|
|
def startup(datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Fires directly after Datasette first starts running"""
|
2020-06-13 17:55:41 +00:00
|
|
|
|
|
|
|
|
2021-06-26 22:24:54 +00:00
|
|
|
@hookspec
|
2021-06-27 00:02:42 +00:00
|
|
|
def get_metadata(datasette, key, database, table):
|
|
|
|
"""Return metadata to be merged into Datasette's metadata dictionary"""
|
2021-06-26 22:24:54 +00:00
|
|
|
|
|
|
|
|
2019-07-03 03:57:28 +00:00
|
|
|
@hookspec
|
|
|
|
def asgi_wrapper(datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Returns an ASGI middleware callable to wrap our ASGI application with"""
|
2019-07-03 03:57:28 +00:00
|
|
|
|
|
|
|
|
2018-04-16 00:56:15 +00:00
|
|
|
@hookspec
|
2020-02-22 01:32:40 +00:00
|
|
|
def prepare_connection(conn, database, datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Modify SQLite connection in some way e.g. register custom SQL functions"""
|
2018-04-16 00:56:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
|
|
|
def prepare_jinja2_environment(env):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Modify Jinja2 template environment e.g. register custom template tags"""
|
2018-04-18 03:12:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
2020-08-16 18:09:53 +00:00
|
|
|
def extra_css_urls(template, database, table, columns, view_name, request, datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Extra CSS URLs added by this plugin"""
|
2018-04-18 03:12:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
2020-08-16 18:09:53 +00:00
|
|
|
def extra_js_urls(template, database, table, columns, view_name, request, datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Extra JavaScript URLs added by this plugin"""
|
publish_subcommand hook + default plugins mechanism, used for publish heroku/now (#349)
This change introduces a new plugin hook, publish_subcommand, which can be
used to implement new subcommands for the "datasette publish" command family.
I've used this new hook to refactor out the "publish now" and "publish heroku"
implementations into separate modules. I've also added unit tests for these
two publishers, mocking the subprocess.call and subprocess.check_output
functions.
As part of this, I introduced a mechanism for loading default plugins. These
are defined in the new "default_plugins" list inside datasette/app.py
Closes #217 (Plugin support for datasette publish)
Closes #348 (Unit tests for "datasette publish")
Refs #14, #59, #102, #103, #146, #236, #347
2018-07-26 05:15:59 +00:00
|
|
|
|
|
|
|
|
2018-08-28 08:56:44 +00:00
|
|
|
@hookspec
|
2020-08-16 18:09:53 +00:00
|
|
|
def extra_body_script(
|
|
|
|
template, database, table, columns, view_name, request, datasette
|
|
|
|
):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Extra JavaScript code to be included in <script> at bottom of body"""
|
2018-08-28 08:56:44 +00:00
|
|
|
|
|
|
|
|
2019-07-06 00:05:56 +00:00
|
|
|
@hookspec
|
2020-08-16 18:09:53 +00:00
|
|
|
def extra_template_vars(
|
|
|
|
template, database, table, columns, view_name, request, datasette
|
|
|
|
):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Extra template variables to be made available to the template - can return dict or callable or awaitable"""
|
2019-07-06 00:05:56 +00:00
|
|
|
|
|
|
|
|
publish_subcommand hook + default plugins mechanism, used for publish heroku/now (#349)
This change introduces a new plugin hook, publish_subcommand, which can be
used to implement new subcommands for the "datasette publish" command family.
I've used this new hook to refactor out the "publish now" and "publish heroku"
implementations into separate modules. I've also added unit tests for these
two publishers, mocking the subprocess.call and subprocess.check_output
functions.
As part of this, I introduced a mechanism for loading default plugins. These
are defined in the new "default_plugins" list inside datasette/app.py
Closes #217 (Plugin support for datasette publish)
Closes #348 (Unit tests for "datasette publish")
Refs #14, #59, #102, #103, #146, #236, #347
2018-07-26 05:15:59 +00:00
|
|
|
@hookspec
|
|
|
|
def publish_subcommand(publish):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Subcommands for 'datasette publish'"""
|
2018-08-05 00:14:56 +00:00
|
|
|
|
|
|
|
|
2021-08-09 00:38:42 +00:00
|
|
|
@hookspec
|
2022-07-07 16:30:49 +00:00
|
|
|
def render_cell(row, value, column, table, database, datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Customize rendering of HTML table cell values"""
|
2019-05-01 23:01:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
|
|
|
def register_output_renderer(datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Register a renderer to output data in a different format"""
|
Extract facet code out into a new plugin hook, closes #427 (#445)
Datasette previously only supported one type of faceting: exact column value counting.
With this change, faceting logic is extracted out into one or more separate classes which can implement other patterns of faceting - this is discussed in #427, but potential upcoming facet types include facet-by-date, facet-by-JSON-array, facet-by-many-2-many and more.
A new plugin hook, register_facet_classes, can be used by plugins to add in additional facet classes.
Each class must implement two methods: suggest(), which scans columns in the table to decide if they might be worth suggesting for faceting, and facet_results(), which executes the facet operation and returns results ready to be displayed in the UI.
2019-05-03 00:11:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
|
|
|
def register_facet_classes():
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Register Facet subclasses"""
|
2020-05-30 20:24:00 +00:00
|
|
|
|
|
|
|
|
2020-06-09 03:12:06 +00:00
|
|
|
@hookspec
|
2021-07-26 23:16:46 +00:00
|
|
|
def register_routes(datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Register URL routes: return a list of (regex, view_function) pairs"""
|
2020-06-09 03:12:06 +00:00
|
|
|
|
|
|
|
|
2021-08-28 01:39:42 +00:00
|
|
|
@hookspec
|
|
|
|
def register_commands(cli):
|
|
|
|
"""Register additional CLI commands, e.g. 'datasette mycommand ...'"""
|
|
|
|
|
|
|
|
|
2020-05-30 20:24:00 +00:00
|
|
|
@hookspec
|
|
|
|
def actor_from_request(datasette, request):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Return an actor dictionary based on the incoming request"""
|
2020-05-30 20:24:00 +00:00
|
|
|
|
|
|
|
|
2021-12-17 19:02:14 +00:00
|
|
|
@hookspec
|
|
|
|
def filters_from_request(request, database, table, datasette):
|
|
|
|
"""
|
|
|
|
Return datasette.filters.FilterArguments(
|
|
|
|
where_clauses=[str, str, str],
|
|
|
|
params={},
|
|
|
|
human_descriptions=[str, str, str],
|
|
|
|
extra_context={}
|
|
|
|
) based on the request"""
|
|
|
|
|
|
|
|
|
2020-05-30 20:24:00 +00:00
|
|
|
@hookspec
|
2020-06-08 18:59:11 +00:00
|
|
|
def permission_allowed(datasette, actor, action, resource):
|
2021-08-03 17:03:08 +00:00
|
|
|
"""Check if actor is allowed to perform this action - return True, False or None"""
|
2020-06-18 23:22:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
|
|
|
def canned_queries(datasette, database, actor):
|
2021-08-03 17:03:08 +00:00
|
|
|
"""Return a dictionary of canned query definitions or an awaitable function that returns them"""
|
2020-06-28 02:58:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
|
|
|
def register_magic_parameters(datasette):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Return a list of (name, function) magic parameter functions"""
|
2020-07-01 04:17:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
|
|
|
def forbidden(datasette, request, message):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Custom response for a 403 forbidden error"""
|
2020-10-30 03:45:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
2021-06-10 04:45:24 +00:00
|
|
|
def menu_links(datasette, actor, request):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Links for the navigation menu"""
|
2020-10-30 05:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
2021-06-10 04:45:24 +00:00
|
|
|
def table_actions(datasette, actor, database, table, request):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Links for the table actions menu"""
|
2020-11-02 18:27:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
2021-06-10 04:45:24 +00:00
|
|
|
def database_actions(datasette, actor, database, request):
|
2020-12-23 17:04:32 +00:00
|
|
|
"""Links for the database actions menu"""
|
2021-06-23 22:39:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookspec
|
|
|
|
def skip_csrf(datasette, scope):
|
|
|
|
"""Mechanism for skipping CSRF checks for certain requests"""
|