Crude plugin store display

This commit is contained in:
Régis Behmo 2025-01-09 18:49:29 +01:00
parent db2b205ff7
commit 8a6a54b04d
6 changed files with 42 additions and 14 deletions

View File

@ -40,6 +40,15 @@ async def home() -> str:
return await render_template("index.html", **shared_template_context())
@app.get("/plugin/store")
async def plugin_store() -> str:
return await render_template(
"plugin_store.html",
plugins=tutorclient.Client.plugins_in_store(),
**shared_template_context(),
)
@app.get("/plugin/<name>")
async def plugin(name: str) -> str:
# TODO check that plugin exists

View File

@ -1,6 +1,4 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

View File

@ -11,6 +11,7 @@
{% else %}
<input type="text" name="value" value="{{ value }}" size="50"/>
{% endif %}
{# TODO how to display lists? #}
<button type="submit" disabled>update</button>
</form>

View File

@ -29,7 +29,7 @@
</div>
<div class="content">
<ul>
<li>Configuration</li>
<li><a href="{{ url_for('plugin_store') }}">Plugin store</a></li>
<li><a href="{{ url_for('cli_logs') }}">Command logs</a></li>
</ul>
</div>

View File

@ -0,0 +1,18 @@
{% extends "index.html" %}
{% block workspace_header %}Plugin store{% endblock %}
{% block workspace_content %}
<ul>
{% for plugin in plugins %}
<li>{{ plugin.name }}: {{ plugin.short_description }}
<!-- TODO convert markdown to html -->
<p>{{ plugin.description }}</p>
<ul>
<li>url: {{ plugin.url }}</li>
<li>index: {{ plugin.index }}</li>
</ul>
</li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -1,6 +1,7 @@
import asyncio
import contextlib
import logging
import os
import shlex
import subprocess
import tempfile
@ -17,6 +18,7 @@ from tutor.types import Config
import tutor.commands.cli
import tutor.config
import tutor.utils
import tutor.plugins.indexes
from . import constants
@ -31,24 +33,17 @@ class Project:
# Project root
ROOT: str = ""
# Full configuration
CONFIG: dict[str, t.Any] = {}
_HOOKED: bool = False
@classmethod
def connect(cls, root: str) -> None:
"""
Call whenever we are ready to connect to the Tutor hooks API.
"""
if not cls._HOOKED:
cls._HOOKED = True
hooks.Actions.CONFIG_LOADED.add()(cls._update_config)
cls.ROOT = root
@classmethod
def _update_config(cls, config: Config) -> None:
cls.CONFIG = config
def get_config(cls) -> Config:
# TODO cache?
return tutor.config.load_full(cls.ROOT)
@classmethod
def get_user_config(cls) -> Config:
@ -282,6 +277,12 @@ class CliPool:
class Client:
@classmethod
def plugins_in_store(cls) -> list[tutor.plugins.indexes.IndexEntry]:
if not os.path.exists(tutor.plugins.indexes.Indexes.CACHE_PATH):
CliPool.run_sequential(["plugins", "update"])
return list(tutor.plugins.indexes.iter_cache_entries())
@classmethod
def installed_plugins(cls) -> list[str]:
return sorted(set(hooks.Filters.PLUGINS_INSTALLED.iterate()))
@ -295,7 +296,8 @@ class Client:
plugin_config = hooks.Filters.CONFIG_UNIQUE.iterate_from_context(
hooks.Contexts.app(name).name
)
return {key: Project.CONFIG.get(key, value) for key, value in plugin_config}
config = Project.get_config()
return {key: config.get(key, value) for key, value in plugin_config}
@classmethod
def plugin_config_defaults(cls, name: str) -> Config: