From 8df5649b6f1122f822ace698bfc70d3b34b4fb56 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Wed, 25 Jan 2023 21:05:09 +0100 Subject: [PATCH] [FR] Add API endpoint to activate plugins (#4186) * make plugin urls def cleaner * rename plugin managment endpoints * [FR] Add API endpoint to activate plugins Fixes #4182 * fix for api url change * bump API version --- InvenTree/InvenTree/api_version.py | 4 +- InvenTree/plugin/api.py | 60 +++++++++++-------- InvenTree/plugin/serializers.py | 4 ++ InvenTree/plugin/test_plugin.py | 2 +- .../InvenTree/settings/settings.html | 2 +- InvenTree/templates/js/dynamic/settings.js | 2 +- InvenTree/templates/js/translated/label.js | 2 +- InvenTree/templates/js/translated/plugin.js | 4 +- 8 files changed, 49 insertions(+), 31 deletions(-) diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py index 4971e2782e..f76469bf76 100644 --- a/InvenTree/InvenTree/api_version.py +++ b/InvenTree/InvenTree/api_version.py @@ -2,10 +2,12 @@ # InvenTree API version -INVENTREE_API_VERSION = 89 +INVENTREE_API_VERSION = 90 """ Increment this API version number whenever there is a significant change to the API that any clients need to know about +v90 -> 2023-01-25 : https://github.com/inventree/InvenTree/pull/4186/files + - Adds a dedicated endpoint to activate a plugin v89 -> 2023-01-25 : https://github.com/inventree/InvenTree/pull/4214 - Adds updated field to SupplierPart API - Adds API date orddering for supplier part list diff --git a/InvenTree/plugin/api.py b/InvenTree/plugin/api.py index 108550239c..3c131fafc4 100644 --- a/InvenTree/plugin/api.py +++ b/InvenTree/plugin/api.py @@ -10,7 +10,8 @@ from rest_framework.response import Response import plugin.serializers as PluginSerializers from common.api import GlobalSettingsPermissions from InvenTree.mixins import (CreateAPI, ListAPI, RetrieveUpdateAPI, - RetrieveUpdateDestroyAPI) + RetrieveUpdateDestroyAPI, UpdateAPI) +from InvenTree.permissions import IsSuperuser from plugin.base.action.api import ActionPluginView from plugin.base.barcodes.api import barcode_api_urls from plugin.base.locate.api import LocatePluginView @@ -122,6 +123,20 @@ class PluginInstall(CreateAPI): return serializer.save() +class PluginActivate(UpdateAPI): + """Endpoint for activating a plugin.""" + + queryset = PluginConfig.objects.all() + serializer_class = PluginSerializers.PluginConfigEmptySerializer + permission_classes = [IsSuperuser, ] + + def perform_update(self, serializer): + """Activate the plugin.""" + instance = serializer.instance + instance.active = True + instance.save() + + class PluginSettingList(ListAPI): """List endpoint for all plugin related settings. @@ -216,27 +231,24 @@ plugin_api_urls = [ re_path(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'), re_path(r'^barcode/', include(barcode_api_urls)), re_path(r'^locate/', LocatePluginView.as_view(), name='api-locate-plugin'), + re_path(r'^plugins/', include([ + # Plugin settings URLs + re_path(r'^settings/', include([ + re_path(r'^(?P\w+)/(?P\w+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'), + re_path(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'), + ])), + + # Detail views for a single PluginConfig item + re_path(r'^(?P\d+)/', include([ + re_path(r'^activate/', PluginActivate.as_view(), name='api-plugin-detail-activate'), + re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'), + ])), + + # Plugin managment + re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'), + re_path(r'^activate/', PluginActivate.as_view(), name='api-plugin-activate'), + + # Anything else + re_path(r'^.*$', PluginList.as_view(), name='api-plugin-list'), + ])) ] - -general_plugin_api_urls = [ - - # Plugin settings URLs - re_path(r'^settings/', include([ - re_path(r'^(?P\w+)/(?P\w+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'), - re_path(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'), - ])), - - # Detail views for a single PluginConfig item - re_path(r'^(?P\d+)/', include([ - re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'), - ])), - - re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'), - - # Anything else - re_path(r'^.*$', PluginList.as_view(), name='api-plugin-list'), -] - -plugin_api_urls.append( - re_path(r'^plugin/', include(general_plugin_api_urls)) -) diff --git a/InvenTree/plugin/serializers.py b/InvenTree/plugin/serializers.py index 267d88f462..913ed66011 100644 --- a/InvenTree/plugin/serializers.py +++ b/InvenTree/plugin/serializers.py @@ -159,6 +159,10 @@ class PluginConfigInstallSerializer(serializers.Serializer): return ret +class PluginConfigEmptySerializer(serializers.Serializer): + """Serializer for a PluginConfig.""" + + class PluginSettingSerializer(GenericReferencedSettingSerializer): """Serializer for the PluginSetting model.""" diff --git a/InvenTree/plugin/test_plugin.py b/InvenTree/plugin/test_plugin.py index 471a2b0f09..953915841d 100644 --- a/InvenTree/plugin/test_plugin.py +++ b/InvenTree/plugin/test_plugin.py @@ -54,7 +54,7 @@ class PluginTagTests(TestCase): def test_tag_safe_url(self): """Test that the safe url tag works expected.""" # right url - self.assertEqual(plugin_tags.safe_url('api-plugin-install'), '/api/plugin/install/') + self.assertEqual(plugin_tags.safe_url('api-plugin-install'), '/api/plugins/install/') # wrong url self.assertEqual(plugin_tags.safe_url('indexas'), None) diff --git a/InvenTree/templates/InvenTree/settings/settings.html b/InvenTree/templates/InvenTree/settings/settings.html index 83939c418b..2461b84dd7 100644 --- a/InvenTree/templates/InvenTree/settings/settings.html +++ b/InvenTree/templates/InvenTree/settings/settings.html @@ -79,7 +79,7 @@ $('table').find('.boolean-setting').change(function() { if (notification) { url = `/api/settings/notification/${pk}/`; } else if (plugin) { - url = `/api/plugin/settings/${plugin}/${setting}/`; + url = `/api/plugins/settings/${plugin}/${setting}/`; } else if (user) { url = `/api/settings/user/${setting}/`; } diff --git a/InvenTree/templates/js/dynamic/settings.js b/InvenTree/templates/js/dynamic/settings.js index ab9ac30397..9dac2a3371 100644 --- a/InvenTree/templates/js/dynamic/settings.js +++ b/InvenTree/templates/js/dynamic/settings.js @@ -44,7 +44,7 @@ function editSetting(key, options={}) { var url = ''; if (plugin) { - url = `/api/plugin/settings/${plugin}/${key}/`; + url = `/api/plugins/settings/${plugin}/${key}/`; } else if (notification) { url = `/api/settings/notification/${pk}/`; } else if (global) { diff --git a/InvenTree/templates/js/translated/label.js b/InvenTree/templates/js/translated/label.js index 9ece9b3265..18cd1605d0 100644 --- a/InvenTree/templates/js/translated/label.js +++ b/InvenTree/templates/js/translated/label.js @@ -235,7 +235,7 @@ function selectLabel(labels, items, options={}) { // Request a list of available label printing plugins from the server if (plugins_enabled) { inventreeGet( - `/api/plugin/`, + `/api/plugins/`, { mixin: 'labels', }, diff --git a/InvenTree/templates/js/translated/plugin.js b/InvenTree/templates/js/translated/plugin.js index 77c31e46d1..f17d8505f7 100644 --- a/InvenTree/templates/js/translated/plugin.js +++ b/InvenTree/templates/js/translated/plugin.js @@ -11,7 +11,7 @@ */ function installPlugin() { - constructForm(`/api/plugin/install/`, { + constructForm(`/api/plugins/install/`, { method: 'POST', title: '{% trans "Install Plugin" %}', fields: { @@ -50,7 +50,7 @@ function locateItemOrLocation(options={}) { // Request the list of available 'locate' plugins inventreeGet( - `/api/plugin/`, + `/api/plugins/`, { mixin: 'locate', },