2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

210 lines
5.7 KiB
Python

"""
Plugin model definitions
"""
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import warnings
from django.utils.translation import gettext_lazy as _
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
import common.models
from plugin import InvenTreePlugin, registry
class PluginConfig(models.Model):
"""
A PluginConfig object holds settings for plugins.
Attributes:
key: slug of the plugin (this must be unique across all installed plugins!)
name: PluginName of the plugin - serves for a manual double check if the right plugin is used
active: Should the plugin be loaded?
"""
class Meta:
verbose_name = _("Plugin Configuration")
verbose_name_plural = _("Plugin Configurations")
key = models.CharField(
unique=True,
max_length=255,
verbose_name=_('Key'),
help_text=_('Key of plugin'),
)
name = models.CharField(
null=True,
blank=True,
max_length=255,
verbose_name=_('Name'),
help_text=_('PluginName of the plugin'),
)
active = models.BooleanField(
default=False,
verbose_name=_('Active'),
help_text=_('Is the plugin active'),
)
def __str__(self) -> str:
name = f'{self.name} - {self.key}'
if not self.active:
name += '(not active)'
return name
# extra attributes from the registry
def mixins(self):
try:
return self.plugin._mixinreg
except (AttributeError, ValueError): # pragma: no cover
return {}
# functions
def __init__(self, *args, **kwargs):
"""
Override to set original state of the plugin-config instance
"""
super().__init__(*args, **kwargs)
self.__org_active = self.active
# append settings from registry
self.plugin = registry.plugins.get(self.key, None)
def get_plugin_meta(name):
if self.plugin:
return str(getattr(self.plugin, name, None))
return None
self.meta = {
key: get_plugin_meta(key) for key in ['slug', 'human_name', 'description', 'author',
'pub_date', 'version', 'website', 'license',
'package_path', 'settings_url', ]
}
def save(self, force_insert=False, force_update=False, *args, **kwargs):
"""
Extend save method to reload plugins if the 'active' status changes
"""
reload = kwargs.pop('no_reload', False) # check if no_reload flag is set
ret = super().save(force_insert, force_update, *args, **kwargs)
if not reload:
if (self.active is False and self.__org_active is True) or \
(self.active is True and self.__org_active is False):
if settings.PLUGIN_TESTING:
warnings.warn('A reload was triggered')
registry.reload_plugins()
return ret
class PluginSetting(common.models.BaseInvenTreeSetting):
"""
This model represents settings for individual plugins
"""
class Meta:
unique_together = [
('plugin', 'key'),
]
plugin = models.ForeignKey(
PluginConfig,
related_name='settings',
null=False,
verbose_name=_('Plugin'),
on_delete=models.CASCADE,
)
@classmethod
def get_setting_definition(cls, key, **kwargs):
"""
In the BaseInvenTreeSetting class, we have a class attribute named 'SETTINGS',
which is a dict object that fully defines all the setting parameters.
Here, unlike the BaseInvenTreeSetting, we do not know the definitions of all settings
'ahead of time' (as they are defined externally in the plugins).
Settings can be provided by the caller, as kwargs['settings'].
If not provided, we'll look at the plugin registry to see what settings are available,
(if the plugin is specified!)
"""
if 'settings' not in kwargs:
plugin = kwargs.pop('plugin', None)
if plugin:
if issubclass(plugin.__class__, InvenTreePlugin):
plugin = plugin.plugin_config()
kwargs['settings'] = registry.mixins_settings.get(plugin.key, {})
return super().get_setting_definition(key, **kwargs)
def get_kwargs(self):
"""
Explicit kwargs required to uniquely identify a particular setting object,
in addition to the 'key' parameter
"""
return {
'plugin': self.plugin,
}
class NotificationUserSetting(common.models.BaseInvenTreeSetting):
"""
This model represents notification settings for a user
"""
class Meta:
unique_together = [
('method', 'user', 'key'),
]
@classmethod
def get_setting_definition(cls, key, **kwargs):
from common.notifications import storage
kwargs['settings'] = storage.user_settings
return super().get_setting_definition(key, **kwargs)
def get_kwargs(self):
"""
Explicit kwargs required to uniquely identify a particular setting object,
in addition to the 'key' parameter
"""
return {
'method': self.method,
'user': self.user,
}
method = models.CharField(
max_length=255,
verbose_name=_('Method'),
)
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
blank=True, null=True,
verbose_name=_('User'),
help_text=_('User'),
)
def __str__(self) -> str:
return f'{self.key} (for {self.user}): {self.value}'