mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +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:
		| @@ -11,6 +11,7 @@ from django.urls import reverse | ||||
|  | ||||
| from InvenTree.api_tester import InvenTreeAPITestCase, PluginMixin | ||||
| from InvenTree.helpers import InvenTreeTestCase, str2bool | ||||
| from plugin import registry | ||||
| from plugin.models import NotificationUserSetting | ||||
|  | ||||
| from .api import WebhookView | ||||
| @@ -560,6 +561,9 @@ class PluginSettingsApiTest(PluginMixin, InvenTreeAPITestCase): | ||||
|  | ||||
|     def test_valid_plugin_slug(self): | ||||
|         """Test that an valid plugin slug runs through.""" | ||||
|         # Activate plugin | ||||
|         registry.set_plugin_state('sample', True) | ||||
|  | ||||
|         # get data | ||||
|         url = reverse('api-plugin-setting-detail', kwargs={'plugin': 'sample', 'key': 'API_KEY'}) | ||||
|         response = self.get(url, expected_code=200) | ||||
|   | ||||
| @@ -16,6 +16,7 @@ from plugin.base.action.api import ActionPluginView | ||||
| from plugin.base.barcodes.api import barcode_api_urls | ||||
| from plugin.base.locate.api import LocatePluginView | ||||
| from plugin.models import PluginConfig, PluginSetting | ||||
| from plugin.plugin import InvenTreePlugin | ||||
| 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): | ||||
|     """Detail endpoint for a plugin-specific setting. | ||||
|  | ||||
| @@ -164,18 +197,10 @@ class PluginSettingDetail(RetrieveUpdateAPI): | ||||
|         plugin_slug = self.kwargs['plugin'] | ||||
|         key = self.kwargs['key'] | ||||
|  | ||||
|         # 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") | ||||
|         # Look up plugin | ||||
|         plugin = check_plugin(plugin_slug) | ||||
|  | ||||
|         # 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 | ||||
|  | ||||
|         settings = getattr(plugin, 'SETTINGS', {}) | ||||
|         settings = getattr(plugin, 'settings', {}) | ||||
|  | ||||
|         if key not in settings: | ||||
|             raise NotFound(detail=f"Plugin '{plugin_slug}' has no setting matching '{key}'") | ||||
|   | ||||
| @@ -67,6 +67,21 @@ class PluginsRegistry: | ||||
|  | ||||
|         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): | ||||
|         """Call a member function (named by 'func') of the plugin named by 'slug'. | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user