mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Cleanup plugin mixin registry (#4790)
* collect mixins dynamically * remove unfinsihed option to reorder mixins * clean up settings * fix text * fix mixin lookup * stupid error * fix assertations * use regustered function instead of private dict * switch to dict for reg * fix test * makke sure mixins also works with class * cleanup * fix reqs * fix test assertations
This commit is contained in:
parent
17057f4266
commit
017ccaa27a
@ -24,9 +24,9 @@ class BaseMixinDefinition:
|
||||
def test_mixin_name(self):
|
||||
"""Test that the mixin registers itseld correctly."""
|
||||
# mixin name
|
||||
self.assertIn(self.MIXIN_NAME, [item['key'] for item in self.mixin.registered_mixins])
|
||||
self.assertIn(self.MIXIN_NAME, {item['key'] for item in self.mixin.registered_mixins.values()})
|
||||
# human name
|
||||
self.assertIn(self.MIXIN_HUMAN_NAME, [item['human_name'] for item in self.mixin.registered_mixins])
|
||||
self.assertIn(self.MIXIN_HUMAN_NAME, {item['human_name'] for item in self.mixin.registered_mixins.values()})
|
||||
|
||||
|
||||
class SettingsMixinTest(BaseMixinDefinition, InvenTreeTestCase):
|
||||
|
@ -1,5 +1,6 @@
|
||||
"""Plugin model definitions."""
|
||||
|
||||
import inspect
|
||||
import warnings
|
||||
|
||||
from django.conf import settings
|
||||
@ -58,7 +59,9 @@ class PluginConfig(models.Model):
|
||||
def mixins(self):
|
||||
"""Returns all registered mixins."""
|
||||
try:
|
||||
return self.plugin._mixinreg
|
||||
if inspect.isclass(self.plugin):
|
||||
return self.plugin.get_registered_mixins(self, with_base=True, with_cls=False)
|
||||
return self.plugin.get_registered_mixins(with_base=True, with_cls=False)
|
||||
except (AttributeError, ValueError): # pragma: no cover
|
||||
return {}
|
||||
|
||||
@ -166,7 +169,9 @@ class PluginSetting(common.models.BaseInvenTreeSetting):
|
||||
if issubclass(plugin.__class__, InvenTreePlugin):
|
||||
plugin = plugin.plugin_config()
|
||||
|
||||
kwargs['settings'] = registry.mixins_settings.get(plugin.key, {})
|
||||
mixin_settings = getattr(registry, 'mixins_settings')
|
||||
if mixin_settings:
|
||||
kwargs['settings'] = mixin_settings.get(plugin.key, {})
|
||||
|
||||
return super().get_setting_definition(key, **kwargs)
|
||||
|
||||
|
@ -161,19 +161,29 @@ class MixinBase:
|
||||
self._mixinreg[key] = {
|
||||
'key': key,
|
||||
'human_name': human_name,
|
||||
'cls': cls,
|
||||
}
|
||||
|
||||
def get_registered_mixins(self, with_base: bool = False, with_cls: bool = True):
|
||||
"""Get all registered mixins for the plugin."""
|
||||
mixins = getattr(self, '_mixinreg', None)
|
||||
if not mixins:
|
||||
return {}
|
||||
|
||||
mixins = mixins.copy()
|
||||
# filter out base
|
||||
if not with_base and 'base' in mixins:
|
||||
del mixins['base']
|
||||
|
||||
# Do not return the mixin class if flas is set
|
||||
if not with_cls:
|
||||
return {key: {k: v for k, v in mixin.items() if k != 'cls'} for key, mixin in mixins.items()}
|
||||
return mixins
|
||||
|
||||
@property
|
||||
def registered_mixins(self, with_base: bool = False):
|
||||
"""Get all registered mixins for the plugin."""
|
||||
mixins = getattr(self, '_mixinreg', None)
|
||||
if mixins:
|
||||
# filter out base
|
||||
if not with_base and 'base' in mixins:
|
||||
del mixins['base']
|
||||
# only return dict
|
||||
mixins = list(mixins.values())
|
||||
return mixins
|
||||
return self.get_registered_mixins(with_base=with_base)
|
||||
|
||||
|
||||
class VersionMixin:
|
||||
|
@ -42,7 +42,7 @@ class PluginsRegistry:
|
||||
|
||||
DEFAULT_MIXIN_ORDER = [SettingsMixin, ScheduleMixin, AppMixin, UrlsMixin]
|
||||
|
||||
def __init__(self, mixin_order: list = None) -> None:
|
||||
def __init__(self) -> None:
|
||||
"""Initialize registry.
|
||||
|
||||
Set up all needed references for internal and external states.
|
||||
@ -53,6 +53,7 @@ class PluginsRegistry:
|
||||
self.plugins_full: Dict[str, InvenTreePlugin] = {} # List of all plugin instances
|
||||
|
||||
self.plugin_modules: List(InvenTreePlugin) = [] # Holds all discovered plugins
|
||||
self.mixin_modules: Dict[str, any] = {} # Holds all discovered mixins
|
||||
|
||||
self.errors = {} # Holds discovering errors
|
||||
|
||||
@ -63,10 +64,6 @@ class PluginsRegistry:
|
||||
|
||||
self.installed_apps = [] # Holds all added plugin_paths
|
||||
|
||||
# mixins
|
||||
self.mixins_settings = {}
|
||||
self.mixin_order = mixin_order or self.DEFAULT_MIXIN_ORDER
|
||||
|
||||
def get_plugin(self, slug):
|
||||
"""Lookup plugin by slug (unique key)."""
|
||||
if slug not in self.plugins:
|
||||
@ -322,6 +319,15 @@ class PluginsRegistry:
|
||||
|
||||
return collected_plugins
|
||||
|
||||
def discover_mixins(self):
|
||||
"""Discover all mixins from plugins and register them."""
|
||||
collected_mixins = {}
|
||||
|
||||
for plg in self.plugins.values():
|
||||
collected_mixins.update(plg.get_registered_mixins())
|
||||
|
||||
self.mixin_modules = collected_mixins
|
||||
|
||||
def install_plugin_file(self):
|
||||
"""Make sure all plugins are installed in the current environment."""
|
||||
if settings.PLUGIN_FILE_CHECKED:
|
||||
@ -468,6 +474,17 @@ class PluginsRegistry:
|
||||
else: # pragma: no cover
|
||||
safe_reference(plugin=plg, key=plg_key, active=False)
|
||||
|
||||
def __get_mixin_order(self):
|
||||
"""Returns a list of mixin classes, in the order that they should be activated."""
|
||||
# Preset list of mixins
|
||||
order = self.DEFAULT_MIXIN_ORDER
|
||||
|
||||
# Append mixins that are not defined in the default list
|
||||
order += [m.get('cls') for m in self.mixin_modules.values() if m.get('cls') not in order]
|
||||
|
||||
# Final list of mixins
|
||||
return order
|
||||
|
||||
def _activate_plugins(self, force_reload=False, full_reload: bool = False):
|
||||
"""Run activation functions for all plugins.
|
||||
|
||||
@ -475,11 +492,14 @@ class PluginsRegistry:
|
||||
force_reload (bool, optional): Also reload base apps. Defaults to False.
|
||||
full_reload (bool, optional): Reload everything - including plugin mechanism. Defaults to False.
|
||||
"""
|
||||
# activate integrations
|
||||
# Collect mixins
|
||||
self.discover_mixins()
|
||||
|
||||
# Activate integrations
|
||||
plugins = self.plugins.items()
|
||||
logger.info(f'Found {len(plugins)} active plugins')
|
||||
|
||||
for mixin in self.mixin_order:
|
||||
for mixin in self.__get_mixin_order():
|
||||
if hasattr(mixin, '_activate_mixin'):
|
||||
mixin._activate_mixin(self, plugins, force_reload=force_reload, full_reload=full_reload)
|
||||
|
||||
@ -491,7 +511,7 @@ class PluginsRegistry:
|
||||
Args:
|
||||
force_reload (bool, optional): Also reload base apps. Defaults to False.
|
||||
"""
|
||||
for mixin in self.mixin_order:
|
||||
for mixin in reversed(self.__get_mixin_order()):
|
||||
if hasattr(mixin, '_deactivate_mixin'):
|
||||
mixin._deactivate_mixin(self, force_reload=force_reload)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user