mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-30 04:26:44 +00:00
Scheduled tasks get registered for the background worker
This commit is contained in:
parent
ff598a22ff
commit
3eb1fa32f9
@ -2,6 +2,8 @@
|
|||||||
Plugin mixin classes
|
Plugin mixin classes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
from django.db.utils import OperationalError, ProgrammingError
|
from django.db.utils import OperationalError, ProgrammingError
|
||||||
|
|
||||||
@ -9,6 +11,9 @@ from plugin.models import PluginConfig, PluginSetting
|
|||||||
from plugin.urls import PLUGIN_BASE
|
from plugin.urls import PLUGIN_BASE
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
|
|
||||||
class SettingsMixin:
|
class SettingsMixin:
|
||||||
"""
|
"""
|
||||||
Mixin that enables global settings for the plugin
|
Mixin that enables global settings for the plugin
|
||||||
@ -116,6 +121,58 @@ class ScheduleMixin:
|
|||||||
if schedule == 'I' and 'minutes' not in task:
|
if schedule == 'I' and 'minutes' not in task:
|
||||||
raise ValueError(f"Task '{key}' is missing 'minutes' parameter")
|
raise ValueError(f"Task '{key}' is missing 'minutes' parameter")
|
||||||
|
|
||||||
|
def get_task_name(self, key):
|
||||||
|
# Generate a 'unique' task name
|
||||||
|
slug = self.plugin_slug()
|
||||||
|
return f"plugin.{slug}.{key}"
|
||||||
|
|
||||||
|
def get_task_names(self):
|
||||||
|
# Returns a list of all task names associated with this plugin instance
|
||||||
|
return [self.get_task_name(key) for key in self.scheduled_tasks.keys()]
|
||||||
|
|
||||||
|
def register_tasks(self):
|
||||||
|
"""
|
||||||
|
Register the tasks with the database
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django_q.models import Schedule
|
||||||
|
|
||||||
|
for key, task in self.scheduled_tasks.items():
|
||||||
|
|
||||||
|
task_name = self.get_task_name(key)
|
||||||
|
|
||||||
|
# If a matching scheduled task does not exist, create it!
|
||||||
|
if not Schedule.objects.filter(name=task_name).exists():
|
||||||
|
|
||||||
|
logger.info(f"Adding scheduled task '{task_name}'")
|
||||||
|
|
||||||
|
Schedule.objects.create(
|
||||||
|
name=task_name,
|
||||||
|
func=task['func'],
|
||||||
|
schedule_type=task['schedule'],
|
||||||
|
minutes=task.get('minutes', None),
|
||||||
|
repeats=task.get('repeats', -1),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister_tasks(self):
|
||||||
|
"""
|
||||||
|
Deregister the tasks with the database
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django_q.models import Schedule
|
||||||
|
|
||||||
|
for key, task in self.scheduled_tasks.items():
|
||||||
|
|
||||||
|
task_name = self.get_task_name(key)
|
||||||
|
|
||||||
|
try:
|
||||||
|
scheduled_task = Schedule.objects.get(name=task_name)
|
||||||
|
scheduled_task.delete()
|
||||||
|
except Schedule.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UrlsMixin:
|
class UrlsMixin:
|
||||||
"""
|
"""
|
||||||
Mixin that enables custom URLs for the plugin
|
Mixin that enables custom URLs for the plugin
|
||||||
|
@ -262,18 +262,21 @@ class PluginsRegistry:
|
|||||||
logger.info(f'Found {len(plugins)} active plugins')
|
logger.info(f'Found {len(plugins)} active plugins')
|
||||||
|
|
||||||
self.activate_integration_settings(plugins)
|
self.activate_integration_settings(plugins)
|
||||||
|
self.activate_integration_schedule(plugins)
|
||||||
self.activate_integration_app(plugins, force_reload=force_reload)
|
self.activate_integration_app(plugins, force_reload=force_reload)
|
||||||
|
|
||||||
def _deactivate_plugins(self):
|
def _deactivate_plugins(self):
|
||||||
"""
|
"""
|
||||||
Run integration deactivation functions for all plugins
|
Run integration deactivation functions for all plugins
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.deactivate_integration_app()
|
self.deactivate_integration_app()
|
||||||
|
self.deactivate_integration_schedule()
|
||||||
self.deactivate_integration_settings()
|
self.deactivate_integration_settings()
|
||||||
|
|
||||||
def activate_integration_settings(self, plugins):
|
def activate_integration_settings(self, plugins):
|
||||||
|
|
||||||
logger.info('Registering IntegrationPlugin global settings')
|
logger.info('Activating plugin settings')
|
||||||
|
|
||||||
self.mixins_settings = {}
|
self.mixins_settings = {}
|
||||||
|
|
||||||
@ -293,8 +296,50 @@ class PluginsRegistry:
|
|||||||
# clear cache
|
# clear cache
|
||||||
self.mixins_settings = {}
|
self.mixins_settings = {}
|
||||||
|
|
||||||
|
def activate_integration_schedule(self, plugins):
|
||||||
|
|
||||||
|
logger.info('Activating plugin tasks')
|
||||||
|
|
||||||
|
from common.models import InvenTreeSetting
|
||||||
|
from django_q.models import Schedule
|
||||||
|
|
||||||
|
# List of tasks we have activated
|
||||||
|
task_keys = []
|
||||||
|
|
||||||
|
if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_SCHEDULE'):
|
||||||
|
|
||||||
|
for slug, plugin in plugins:
|
||||||
|
|
||||||
|
if plugin.mixin_enabled('schedule'):
|
||||||
|
config = plugin.plugin_config()
|
||||||
|
|
||||||
|
# Only active tasks for plugins which are enabled
|
||||||
|
if config and config.active:
|
||||||
|
plugin.register_tasks()
|
||||||
|
task_keys += plugin.get_task_names()
|
||||||
|
|
||||||
|
logger.info(f"Activated {len(task_keys)} scheduled tasks")
|
||||||
|
|
||||||
|
# Remove any scheduled tasks which do not match
|
||||||
|
# This stops 'old' plugin tasks from accumulating
|
||||||
|
scheduled_plugin_tasks = Schedule.objects.filter(name__istartswith="plugin.")
|
||||||
|
|
||||||
|
deleted_count = 0
|
||||||
|
|
||||||
|
for task in scheduled_plugin_tasks:
|
||||||
|
if task.name not in task_keys:
|
||||||
|
task.delete()
|
||||||
|
deleted_count += 1
|
||||||
|
|
||||||
|
if deleted_count > 0:
|
||||||
|
logger.info(f"Removed {deleted_count} old scheduled tasks")
|
||||||
|
|
||||||
|
def deactivate_integration_schedule(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def activate_integration_app(self, plugins, force_reload=False):
|
def activate_integration_app(self, plugins, force_reload=False):
|
||||||
"""activate AppMixin plugins - add custom apps and reload
|
"""
|
||||||
|
Activate AppMixin plugins - add custom apps and reload
|
||||||
|
|
||||||
:param plugins: list of IntegrationPlugins that should be installed
|
:param plugins: list of IntegrationPlugins that should be installed
|
||||||
:type plugins: dict
|
:type plugins: dict
|
||||||
@ -378,7 +423,10 @@ class PluginsRegistry:
|
|||||||
return plugin_path
|
return plugin_path
|
||||||
|
|
||||||
def deactivate_integration_app(self):
|
def deactivate_integration_app(self):
|
||||||
"""deactivate integration app - some magic required"""
|
"""
|
||||||
|
Deactivate integration app - some magic required
|
||||||
|
"""
|
||||||
|
|
||||||
# unregister models from admin
|
# unregister models from admin
|
||||||
for plugin_path in self.installed_apps:
|
for plugin_path in self.installed_apps:
|
||||||
models = [] # the modelrefs need to be collected as poping an item in a iter is not welcomed
|
models = [] # the modelrefs need to be collected as poping an item in a iter is not welcomed
|
||||||
|
@ -26,12 +26,12 @@ class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase):
|
|||||||
|
|
||||||
SCHEDULED_TASKS = {
|
SCHEDULED_TASKS = {
|
||||||
'hello': {
|
'hello': {
|
||||||
'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_hello',
|
'func': 'plugin.samples.integration.scheduled_task.print_hello',
|
||||||
'schedule': 'I',
|
'schedule': 'I',
|
||||||
'minutes': 5,
|
'minutes': 5,
|
||||||
},
|
},
|
||||||
'world': {
|
'world': {
|
||||||
'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_world',
|
'func': 'plugin.samples.integration.scheduled_task.print_hello',
|
||||||
'schedule': 'H',
|
'schedule': 'H',
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user