mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 20:16:44 +00:00
More refactoring:
- Rename "mixins_globalsettings" to "mixing_settings" - Fix translation on settings page template
This commit is contained in:
parent
737467a1fd
commit
f3bfe6e7ca
@ -4,8 +4,7 @@ from __future__ import unicode_literals
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
import plugin.models as models
|
import plugin.models as models
|
||||||
from plugin import plugin_reg
|
import plugin.registry as registry
|
||||||
|
|
||||||
|
|
||||||
def plugin_update(queryset, new_status: bool):
|
def plugin_update(queryset, new_status: bool):
|
||||||
"""general function for bulk changing plugins"""
|
"""general function for bulk changing plugins"""
|
||||||
@ -20,7 +19,7 @@ def plugin_update(queryset, new_status: bool):
|
|||||||
|
|
||||||
# reload plugins if they changed
|
# reload plugins if they changed
|
||||||
if apps_changed:
|
if apps_changed:
|
||||||
plugin_reg.reload_plugins()
|
registry.plugin_registry.reload_plugins()
|
||||||
|
|
||||||
|
|
||||||
@admin.action(description='Activate plugin(s)')
|
@admin.action(description='Activate plugin(s)')
|
||||||
@ -42,6 +41,13 @@ class PluginSettingInline(admin.TabularInline):
|
|||||||
|
|
||||||
model = models.PluginSetting
|
model = models.PluginSetting
|
||||||
|
|
||||||
|
read_only_fields = [
|
||||||
|
'key',
|
||||||
|
]
|
||||||
|
|
||||||
|
def has_add_permission(self, request, obj):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class PluginConfigAdmin(admin.ModelAdmin):
|
class PluginConfigAdmin(admin.ModelAdmin):
|
||||||
"""Custom admin with restricted id fields"""
|
"""Custom admin with restricted id fields"""
|
||||||
|
@ -3,7 +3,9 @@ Plugin mixin classes
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
|
from django.db.utils import OperationalError, ProgrammingError
|
||||||
|
|
||||||
|
from plugin.models import PluginConfig, PluginSetting
|
||||||
from plugin.urls import PLUGIN_BASE
|
from plugin.urls import PLUGIN_BASE
|
||||||
|
|
||||||
|
|
||||||
@ -18,43 +20,48 @@ class SettingsMixin:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.add_mixin('settings', 'has_settings', __class__)
|
self.add_mixin('settings', 'has_settings', __class__)
|
||||||
self.globalsettings = getattr(self, 'SETTINGS', None)
|
self.settings = getattr(self, 'SETTINGS', {})
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_settings(self):
|
def has_settings(self):
|
||||||
"""
|
"""
|
||||||
Does this plugin use custom global settings
|
Does this plugin use custom global settings
|
||||||
"""
|
"""
|
||||||
return bool(self.globalsettings)
|
return bool(self.settings)
|
||||||
|
|
||||||
@property
|
def get_setting(self, key):
|
||||||
def globalsettingspatterns(self):
|
|
||||||
"""
|
"""
|
||||||
Get patterns for InvenTreeSetting defintion
|
Return the 'value' of the setting associated with this plugin
|
||||||
"""
|
"""
|
||||||
if self.has_settings:
|
|
||||||
return {f'PLUGIN_{self.slug.upper()}_{key}': value for key, value in self.globalsettings.items()}
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _globalsetting_name(self, key):
|
# Find the plugin configuration associated with this plugin
|
||||||
"""
|
|
||||||
Get global name of setting
|
|
||||||
"""
|
|
||||||
return f'PLUGIN_{self.slug.upper()}_{key}'
|
|
||||||
|
|
||||||
def get_globalsetting(self, key):
|
try:
|
||||||
"""
|
plugin, _ = PluginConfig.objects.get_or_create(key=self.plugin_slug(), name=self.plugin_name())
|
||||||
get plugin global setting by key
|
except (OperationalError, ProgrammingError) as error:
|
||||||
"""
|
plugin = None
|
||||||
from common.models import InvenTreeSetting
|
|
||||||
return InvenTreeSetting.get_setting(self._globalsetting_name(key))
|
if not plugin:
|
||||||
|
# Plugin cannot be found, return default value
|
||||||
|
return PluginSetting.get_setting_default(key, settings=self.settings)
|
||||||
|
|
||||||
def set_globalsetting(self, key, value, user):
|
return PluginSetting.get_setting(key, plugin=plugin, settings=self.settings)
|
||||||
|
|
||||||
|
def set_setting(self, key, value, user):
|
||||||
"""
|
"""
|
||||||
set plugin global setting by key
|
Set plugin setting value by key
|
||||||
"""
|
"""
|
||||||
from common.models import InvenTreeSetting
|
|
||||||
return InvenTreeSetting.set_setting(self._globalsetting_name(key), value, user)
|
try:
|
||||||
|
plugin, _ = PluginConfig.objects.get_or_create(key=self.plugin_slug(), name=self.plugin_name())
|
||||||
|
except (OperationalError, ProgrammingError) as error:
|
||||||
|
plugin = None
|
||||||
|
|
||||||
|
if not plugin:
|
||||||
|
# Cannot find associated plugin model, return
|
||||||
|
return
|
||||||
|
|
||||||
|
PluginSetting.set_setting(key, value, user, plugin=plugin, settings=self.settings)
|
||||||
|
|
||||||
|
|
||||||
class UrlsMixin:
|
class UrlsMixin:
|
||||||
|
@ -59,8 +59,6 @@ class IntegrationPluginBase(MixinBase, plugin.InvenTreePlugin):
|
|||||||
"""
|
"""
|
||||||
The IntegrationPluginBase class is used to integrate with 3rd party software
|
The IntegrationPluginBase class is used to integrate with 3rd party software
|
||||||
"""
|
"""
|
||||||
PLUGIN_SLUG = None
|
|
||||||
PLUGIN_TITLE = None
|
|
||||||
|
|
||||||
AUTHOR = None
|
AUTHOR = None
|
||||||
DESCRIPTION = None
|
DESCRIPTION = None
|
||||||
@ -84,11 +82,7 @@ class IntegrationPluginBase(MixinBase, plugin.InvenTreePlugin):
|
|||||||
# region properties
|
# region properties
|
||||||
@property
|
@property
|
||||||
def slug(self):
|
def slug(self):
|
||||||
"""slug for the plugin"""
|
return self.plugin_slug()
|
||||||
slug = getattr(self, 'PLUGIN_SLUG', None)
|
|
||||||
if not slug:
|
|
||||||
slug = self.plugin_name()
|
|
||||||
return slugify(slug)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def human_name(self):
|
def human_name(self):
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
"""Base Class for InvenTree plugins"""
|
"""Base Class for InvenTree plugins"""
|
||||||
|
|
||||||
|
|
||||||
|
from django.utils.text import slugify
|
||||||
|
|
||||||
|
|
||||||
class InvenTreePlugin():
|
class InvenTreePlugin():
|
||||||
"""
|
"""
|
||||||
Base class for a plugin
|
Base class for a plugin
|
||||||
@ -10,9 +13,28 @@ class InvenTreePlugin():
|
|||||||
# Override the plugin name for each concrete plugin instance
|
# Override the plugin name for each concrete plugin instance
|
||||||
PLUGIN_NAME = ''
|
PLUGIN_NAME = ''
|
||||||
|
|
||||||
|
PLUGIN_SLUG = ''
|
||||||
|
|
||||||
|
PLUGIN_TITLE = ''
|
||||||
|
|
||||||
def plugin_name(self):
|
def plugin_name(self):
|
||||||
"""get plugin name"""
|
"""
|
||||||
|
Return the name of this plugin plugin
|
||||||
|
"""
|
||||||
return self.PLUGIN_NAME
|
return self.PLUGIN_NAME
|
||||||
|
|
||||||
|
def plugin_slug(self):
|
||||||
|
|
||||||
|
slug = getattr(self, 'PLUGIN_SLUG', None)
|
||||||
|
|
||||||
|
if slug is None:
|
||||||
|
slug = self.plugin_name()
|
||||||
|
|
||||||
|
return slugify(slug)
|
||||||
|
|
||||||
|
def plugin_title(self):
|
||||||
|
|
||||||
|
return self.PLUGIN_TITLE
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
@ -50,7 +50,7 @@ class Plugins:
|
|||||||
# integration specific
|
# integration specific
|
||||||
self.installed_apps = [] # Holds all added plugin_paths
|
self.installed_apps = [] # Holds all added plugin_paths
|
||||||
# mixins
|
# mixins
|
||||||
self.mixins_globalsettings = {}
|
self.mixins_settings = {}
|
||||||
|
|
||||||
# region public plugin functions
|
# region public plugin functions
|
||||||
def load_plugins(self):
|
def load_plugins(self):
|
||||||
@ -252,8 +252,8 @@ class Plugins:
|
|||||||
logger.info('Registering IntegrationPlugin global settings')
|
logger.info('Registering IntegrationPlugin global settings')
|
||||||
for slug, plugin in plugins:
|
for slug, plugin in plugins:
|
||||||
if plugin.mixin_enabled('settings'):
|
if plugin.mixin_enabled('settings'):
|
||||||
plugin_setting = plugin.globalsettingspatterns
|
plugin_setting = plugin.settings
|
||||||
self.mixins_globalsettings[slug] = plugin_setting
|
self.mixins_settings[slug] = plugin_setting
|
||||||
|
|
||||||
# Add to settings dir
|
# Add to settings dir
|
||||||
InvenTreeSetting.SETTINGS.update(plugin_setting)
|
InvenTreeSetting.SETTINGS.update(plugin_setting)
|
||||||
@ -263,7 +263,7 @@ class Plugins:
|
|||||||
|
|
||||||
# collect all settings
|
# collect all settings
|
||||||
plugin_settings = {}
|
plugin_settings = {}
|
||||||
for _, plugin_setting in self.mixins_globalsettings.items():
|
for _, plugin_setting in self.mixins_settings.items():
|
||||||
plugin_settings.update(plugin_setting)
|
plugin_settings.update(plugin_setting)
|
||||||
|
|
||||||
# remove settings
|
# remove settings
|
||||||
@ -271,7 +271,7 @@ class Plugins:
|
|||||||
InvenTreeSetting.SETTINGS.pop(setting)
|
InvenTreeSetting.SETTINGS.pop(setting)
|
||||||
|
|
||||||
# clear cache
|
# clear cache
|
||||||
self.mixins_globalsettings = {}
|
self.mixins_Fsettings = {}
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region integration_app
|
# region integration_app
|
||||||
|
@ -44,6 +44,15 @@ class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixi
|
|||||||
'default': True,
|
'default': True,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
},
|
},
|
||||||
|
'API_KEY': {
|
||||||
|
'name': _('API Key'),
|
||||||
|
'description': _('Key required for accessing external API'),
|
||||||
|
},
|
||||||
|
'NUMERICAL_SETTING': {
|
||||||
|
'name': _('Numerical'),
|
||||||
|
'description': _('A numerical setting'),
|
||||||
|
'validator': int,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
NAVIGATION = [
|
NAVIGATION = [
|
||||||
|
@ -26,9 +26,9 @@ def inactive_plugin_list(*args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
@register.simple_tag()
|
@register.simple_tag()
|
||||||
def plugin_globalsettings(plugin, *args, **kwargs):
|
def plugin_settings(plugin, *args, **kwargs):
|
||||||
""" Return a list of all global settings for a plugin """
|
""" Return a list of all custom settings for a plugin """
|
||||||
return plugin_reg.mixins_globalsettings.get(plugin)
|
return plugin_reg.mixins_settings.get(plugin)
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag()
|
@register.simple_tag()
|
||||||
|
@ -46,15 +46,15 @@ class SettingsMixinTest(BaseMixinDefinition, TestCase):
|
|||||||
|
|
||||||
# calling settings
|
# calling settings
|
||||||
# not existing
|
# not existing
|
||||||
self.assertEqual(self.mixin.get_globalsetting('ABCD'), '')
|
self.assertEqual(self.mixin.get_setting('ABCD'), '')
|
||||||
self.assertEqual(self.mixin_nothing.get_globalsetting('ABCD'), '')
|
self.assertEqual(self.mixin_nothing.get_setting('ABCD'), '')
|
||||||
|
|
||||||
# right setting
|
# right setting
|
||||||
self.mixin.set_globalsetting('SETTING1', '12345', self.test_user)
|
self.mixin.set_setting('SETTING1', '12345', self.test_user)
|
||||||
self.assertEqual(self.mixin.get_globalsetting('SETTING1'), '12345')
|
self.assertEqual(self.mixin.get_setting('SETTING1'), '12345')
|
||||||
|
|
||||||
# no setting
|
# no setting
|
||||||
self.assertEqual(self.mixin_nothing.get_globalsetting(''), '')
|
self.assertEqual(self.mixin_nothing.get_setting(''), '')
|
||||||
|
|
||||||
|
|
||||||
class UrlsMixinTest(BaseMixinDefinition, TestCase):
|
class UrlsMixinTest(BaseMixinDefinition, TestCase):
|
||||||
|
@ -63,11 +63,11 @@ class PluginTagTests(TestCase):
|
|||||||
"""test that all inactive plugins are listed"""
|
"""test that all inactive plugins are listed"""
|
||||||
self.assertEqual(plugin_tags.inactive_plugin_list(), plugin_reg.plugins_inactive)
|
self.assertEqual(plugin_tags.inactive_plugin_list(), plugin_reg.plugins_inactive)
|
||||||
|
|
||||||
def test_tag_plugin_globalsettings(self):
|
def test_tag_plugin_settings(self):
|
||||||
"""check all plugins are listed"""
|
"""check all plugins are listed"""
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
plugin_tags.plugin_globalsettings(self.sample),
|
plugin_tags.plugin_settings(self.sample),
|
||||||
plugin_reg.mixins_globalsettings.get(self.sample)
|
plugin_reg.mixins_settings.get(self.sample)
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_tag_mixin_enabled(self):
|
def test_tag_mixin_enabled(self):
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<h4>{% trans "Settings" %}</h4>
|
<h4>{% trans "Settings" %}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% plugin_globalsettings plugin_key as plugin_settings %}
|
{% plugin_settings plugin_key as plugin_settings %}
|
||||||
|
|
||||||
<table class='table table-striped table-condensed'>
|
<table class='table table-striped table-condensed'>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<span class='fas {{ icon }}'></span>
|
<span class='fas {{ icon }}'></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td><strong>{% trans setting.name %}</strong></td>
|
<td><strong>{{ setting.name }}</strong></td>
|
||||||
<td>
|
<td>
|
||||||
{% if setting.is_bool %}
|
{% if setting.is_bool %}
|
||||||
<div class='form-check form-switch'>
|
<div class='form-check form-switch'>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td>
|
<td>
|
||||||
{% trans setting.description %}
|
{{ setting.description }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class='btn-group float-right'>
|
<div class='btn-group float-right'>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user