mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-30 12:36:45 +00:00
refactor plugin loading
This commit is contained in:
parent
175b6ca053
commit
0e6f203660
@ -262,7 +262,7 @@ INSTALLED_APPS = [
|
|||||||
'report.apps.ReportConfig',
|
'report.apps.ReportConfig',
|
||||||
'stock.apps.StockConfig',
|
'stock.apps.StockConfig',
|
||||||
'users.apps.UsersConfig',
|
'users.apps.UsersConfig',
|
||||||
'plugin.apps.PluginConfig',
|
'plugin.apps.PluginAppConfig',
|
||||||
'InvenTree.apps.InvenTreeConfig', # InvenTree app runs last
|
'InvenTree.apps.InvenTreeConfig', # InvenTree app runs last
|
||||||
|
|
||||||
# Third part add-ons
|
# Third part add-ons
|
||||||
|
@ -20,55 +20,23 @@ from plugin.integration import IntegrationPluginBase
|
|||||||
logger = logging.getLogger('inventree')
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
|
|
||||||
class PluginConfig(AppConfig):
|
class PluginAppConfig(AppConfig):
|
||||||
name = 'plugin'
|
name = 'plugin'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from common.models import InvenTreeSetting
|
self.collect_plugins()
|
||||||
from plugin.models import PluginConfig
|
|
||||||
|
|
||||||
# Collect plugins from paths
|
|
||||||
for plugin in settings.PLUGIN_DIRS:
|
|
||||||
modules = inventree_plugins.get_plugins(importlib.import_module(plugin), IntegrationPluginBase, True)
|
|
||||||
if modules:
|
|
||||||
[settings.PLUGINS.append(item) for item in modules]
|
|
||||||
|
|
||||||
# Collect plugins from setup entry points
|
|
||||||
for entry in metadata.entry_points().get('inventree_plugins', []):
|
|
||||||
plugin = entry.load()
|
|
||||||
plugin.is_package = True
|
|
||||||
settings.PLUGINS.append(plugin)
|
|
||||||
|
|
||||||
# Log found plugins
|
|
||||||
logger.info(f'Found {len(settings.PLUGINS)} plugins!')
|
|
||||||
logger.info(", ".join([a.__module__ for a in settings.PLUGINS]))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.info('Starting plugin initialisation')
|
# we are using the db from here - so for migrations etc we need to try this block
|
||||||
# Initialize integration plugins
|
self.init_plugins()
|
||||||
for plugin in inventree_plugins.load_integration_plugins():
|
self.activate_plugins()
|
||||||
# check if package
|
except (OperationalError, ProgrammingError):
|
||||||
was_packaged = getattr(plugin, 'is_package', False)
|
# Exception if the database has not been migrated yet
|
||||||
|
pass
|
||||||
|
|
||||||
# check if activated
|
def activate_plugins(self):
|
||||||
# these checks only use attributes - never use plugin supplied functions -> that would lead to arbitrary code execution!!
|
"""fullfill integrations for all activated plugins"""
|
||||||
plug_name = plugin.PLUGIN_NAME
|
from common.models import InvenTreeSetting
|
||||||
plug_key = plugin.PLUGIN_SLUG if getattr(plugin, 'PLUGIN_SLUG', None) else plug_name
|
|
||||||
plugin_db_setting, _ = PluginConfig.objects.get_or_create(key=plug_key, name=plug_name)
|
|
||||||
|
|
||||||
if plugin_db_setting.active:
|
|
||||||
# init package
|
|
||||||
# now we can be sure that an admin has activated the plugin -> as of Nov 2021 there are not many checks in place
|
|
||||||
# but we could enhance those to check signatures, run the plugin against a whitelist etc.
|
|
||||||
logger.info(f'Loading integration plugin {plugin.PLUGIN_NAME}')
|
|
||||||
plugin = plugin()
|
|
||||||
logger.info(f'Loaded integration plugin {plugin.slug}')
|
|
||||||
plugin.is_package = was_packaged
|
|
||||||
# safe reference
|
|
||||||
settings.INTEGRATION_PLUGINS[plugin.slug] = plugin
|
|
||||||
else:
|
|
||||||
# save for later reference
|
|
||||||
settings.INTEGRATION_PLUGINS_INACTIVE[plug_key] = plugin_db_setting
|
|
||||||
|
|
||||||
# activate integrations
|
# activate integrations
|
||||||
plugins = settings.INTEGRATION_PLUGINS.items()
|
plugins = settings.INTEGRATION_PLUGINS.items()
|
||||||
@ -111,6 +79,51 @@ class PluginConfig(AppConfig):
|
|||||||
apps.apps_ready = apps.models_ready = apps.loading = apps.ready = False
|
apps.apps_ready = apps.models_ready = apps.loading = apps.ready = False
|
||||||
apps.clear_cache()
|
apps.clear_cache()
|
||||||
apps.populate(settings.INSTALLED_APPS)
|
apps.populate(settings.INSTALLED_APPS)
|
||||||
except (OperationalError, ProgrammingError):
|
|
||||||
# Exception if the database has not been migrated yet
|
def init_plugins(self):
|
||||||
pass
|
"""initialise all found plugins"""
|
||||||
|
from plugin.models import PluginConfig
|
||||||
|
|
||||||
|
logger.info('Starting plugin initialisation')
|
||||||
|
# Initialize integration plugins
|
||||||
|
for plugin in inventree_plugins.load_integration_plugins():
|
||||||
|
# check if package
|
||||||
|
was_packaged = getattr(plugin, 'is_package', False)
|
||||||
|
|
||||||
|
# check if activated
|
||||||
|
# these checks only use attributes - never use plugin supplied functions -> that would lead to arbitrary code execution!!
|
||||||
|
plug_name = plugin.PLUGIN_NAME
|
||||||
|
plug_key = plugin.PLUGIN_SLUG if getattr(plugin, 'PLUGIN_SLUG', None) else plug_name
|
||||||
|
plugin_db_setting, _ = PluginConfig.objects.get_or_create(key=plug_key, name=plug_name)
|
||||||
|
|
||||||
|
if plugin_db_setting.active:
|
||||||
|
# init package
|
||||||
|
# now we can be sure that an admin has activated the plugin -> as of Nov 2021 there are not many checks in place
|
||||||
|
# but we could enhance those to check signatures, run the plugin against a whitelist etc.
|
||||||
|
logger.info(f'Loading integration plugin {plugin.PLUGIN_NAME}')
|
||||||
|
plugin = plugin()
|
||||||
|
logger.info(f'Loaded integration plugin {plugin.slug}')
|
||||||
|
plugin.is_package = was_packaged
|
||||||
|
# safe reference
|
||||||
|
settings.INTEGRATION_PLUGINS[plugin.slug] = plugin
|
||||||
|
else:
|
||||||
|
# save for later reference
|
||||||
|
settings.INTEGRATION_PLUGINS_INACTIVE[plug_key] = plugin_db_setting
|
||||||
|
|
||||||
|
def collect_plugins(self):
|
||||||
|
"""collect integration plugins from all possible ways of loading"""
|
||||||
|
# Collect plugins from paths
|
||||||
|
for plugin in settings.PLUGIN_DIRS:
|
||||||
|
modules = inventree_plugins.get_plugins(importlib.import_module(plugin), IntegrationPluginBase, True)
|
||||||
|
if modules:
|
||||||
|
[settings.PLUGINS.append(item) for item in modules]
|
||||||
|
|
||||||
|
# Collect plugins from setup entry points
|
||||||
|
for entry in metadata.entry_points().get('inventree_plugins', []):
|
||||||
|
plugin = entry.load()
|
||||||
|
plugin.is_package = True
|
||||||
|
settings.PLUGINS.append(plugin)
|
||||||
|
|
||||||
|
# Log found plugins
|
||||||
|
logger.info(f'Found {len(settings.PLUGINS)} plugins!')
|
||||||
|
logger.info(", ".join([a.__module__ for a in settings.PLUGINS]))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user