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.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) | ||||||
|   | |||||||
| @@ -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}'") | ||||||
|   | |||||||
| @@ -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'. | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user