2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-07 15:58:49 +00:00

Plugin API refactor (#3637)

* out-of-scope: refactor plugin lookup

* lookup by settings (runtime not predefined)

* Add registry function to set state of plugin quickly

* Ensure plugin is active before assertations
This commit is contained in:
Matthias Mair 2022-10-17 13:08:28 +02:00 committed by GitHub
parent 0b0594c7ff
commit 0bab40fe88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 11 deletions

View File

@ -11,6 +11,7 @@ from django.urls import reverse
from InvenTree.api_tester import InvenTreeAPITestCase, PluginMixin from InvenTree.api_tester import InvenTreeAPITestCase, PluginMixin
from InvenTree.helpers import InvenTreeTestCase, str2bool from InvenTree.helpers import InvenTreeTestCase, str2bool
from plugin import registry
from plugin.models import NotificationUserSetting from plugin.models import NotificationUserSetting
from .api import WebhookView from .api import WebhookView
@ -560,6 +561,9 @@ class PluginSettingsApiTest(PluginMixin, InvenTreeAPITestCase):
def test_valid_plugin_slug(self): def test_valid_plugin_slug(self):
"""Test that an valid plugin slug runs through.""" """Test that an valid plugin slug runs through."""
# Activate plugin
registry.set_plugin_state('sample', True)
# get data # get data
url = reverse('api-plugin-setting-detail', kwargs={'plugin': 'sample', 'key': 'API_KEY'}) url = reverse('api-plugin-setting-detail', kwargs={'plugin': 'sample', 'key': 'API_KEY'})
response = self.get(url, expected_code=200) response = self.get(url, expected_code=200)

View File

@ -16,6 +16,7 @@ from plugin.base.action.api import ActionPluginView
from plugin.base.barcodes.api import barcode_api_urls from plugin.base.barcodes.api import barcode_api_urls
from plugin.base.locate.api import LocatePluginView from plugin.base.locate.api import LocatePluginView
from plugin.models import PluginConfig, PluginSetting from plugin.models import PluginConfig, PluginSetting
from plugin.plugin import InvenTreePlugin
from plugin.registry import registry from plugin.registry import registry
@ -146,6 +147,38 @@ class PluginSettingList(ListAPI):
] ]
def check_plugin(plugin_slug: str) -> InvenTreePlugin:
"""Check that a plugin for the provided slug exsists and get the config.
Args:
plugin_slug (str): Slug for plugin.
Raises:
NotFound: If plugin is not installed
NotFound: If plugin is not correctly registered
NotFound: If plugin is not active
Returns:
InvenTreePlugin: The config object for the provided plugin.
"""
# Check that the 'plugin' specified is valid!
if not PluginConfig.objects.filter(key=plugin_slug).exists():
raise NotFound(detail=f"Plugin '{plugin_slug}' not installed")
# Get the list of settings available for the specified plugin
plugin = registry.get_plugin(plugin_slug)
if plugin is None:
# This only occurs if the plugin mechanism broke
raise NotFound(detail=f"Plugin '{plugin_slug}' not found") # pragma: no cover
# Check that the plugin is activated
if not plugin.is_active():
raise NotFound(detail=f"Plugin '{plugin_slug}' is not active")
return plugin
class PluginSettingDetail(RetrieveUpdateAPI): class PluginSettingDetail(RetrieveUpdateAPI):
"""Detail endpoint for a plugin-specific setting. """Detail endpoint for a plugin-specific setting.
@ -164,18 +197,10 @@ class PluginSettingDetail(RetrieveUpdateAPI):
plugin_slug = self.kwargs['plugin'] plugin_slug = self.kwargs['plugin']
key = self.kwargs['key'] key = self.kwargs['key']
# Check that the 'plugin' specified is valid! # Look up plugin
if not PluginConfig.objects.filter(key=plugin_slug).exists(): plugin = check_plugin(plugin_slug)
raise NotFound(detail=f"Plugin '{plugin_slug}' not installed")
# Get the list of settings available for the specified plugin settings = getattr(plugin, 'settings', {})
plugin = registry.get_plugin(plugin_slug)
if plugin is None:
# This only occurs if the plugin mechanism broke
raise NotFound(detail=f"Plugin '{plugin_slug}' not found") # pragma: no cover
settings = getattr(plugin, 'SETTINGS', {})
if key not in settings: if key not in settings:
raise NotFound(detail=f"Plugin '{plugin_slug}' has no setting matching '{key}'") raise NotFound(detail=f"Plugin '{plugin_slug}' has no setting matching '{key}'")

View File

@ -67,6 +67,21 @@ class PluginsRegistry:
return self.plugins[slug] return self.plugins[slug]
def set_plugin_state(self, slug, state):
"""Set the state(active/inactive) of a plugin.
Args:
slug (str): Plugin slug
state (bool): Plugin state - true = active, false = inactive
"""
if slug not in self.plugins_full:
logger.warning(f"Plugin registry has no record of plugin '{slug}'")
return
plugin = self.plugins_full[slug].db
plugin.active = state
plugin.save()
def call_plugin_function(self, slug, func, *args, **kwargs): def call_plugin_function(self, slug, func, *args, **kwargs):
"""Call a member function (named by 'func') of the plugin named by 'slug'. """Call a member function (named by 'func') of the plugin named by 'slug'.