From 63eb49777a5ce289c3910ea87929702e88990b39 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 7 Jan 2022 22:22:59 +1100 Subject: [PATCH] Add mixin class to respond to internal events --- .../plugin/builtin/integration/mixins.py | 64 +++++++++++++++++++ InvenTree/plugin/mixins/__init__.py | 3 +- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index c6198ed7a1..68288121e2 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -80,6 +80,7 @@ class ScheduleMixin: ALLOWABLE_SCHEDULE_TYPES = ['I', 'H', 'D', 'W', 'M', 'Q', 'Y'] + # Override this in subclass model SCHEDULED_TASKS = {} class MixinMeta: @@ -180,6 +181,69 @@ class ScheduleMixin: logger.warning("unregister_tasks failed, database not ready") +class EventMixin: + """ + Mixin that provides support for responding to triggered events. + + Implementing classes must provide a list of tuples, + which provide pairs of 'event':'function' + + Notes: + + Events are called by name, and based on the django signal nomenclature, + e.g. 'part.pre_save' + + Receiving functions must be prototyped to match the 'event' they receive. + + Example: + + EVENTS = [ + ('part.pre_save', 'myplugin.functions.do_stuff'), + ('build.complete', 'myplugin.functions.process_completed_build'), + ] + """ + + # Override this in subclass model + EVENTS = [] + + class MixinMeta: + MIXIN_NAME = 'Events' + + def __init__(self): + super().__init__() + self.add_mixin('events', 'has_events', __class__) + self.events = getattr(self, 'EVENTS', []) + + self.validate_events() + + @property + def has_events(self): + return bool(self.events) and len(self.events) > 0 + + def validate_events(self): + """ + Check that the provided event callbacks are valid + """ + + if not self.has_events: + raise ValueError('EVENTS not defined') + + for pair in self.events: + valid = True + + if len(pair) == 2: + event = pair[0].strip() + func = pair[1].strip() + + if len(event) == 0 or len(func) == 0: + valid = False + else: + valid = False + + if not valid: + raise ValueError("Invalid event callback: " + str(pair)) + + class UrlsMixin: """ Mixin that enables custom URLs for the plugin diff --git a/InvenTree/plugin/mixins/__init__.py b/InvenTree/plugin/mixins/__init__.py index e9c910bb9e..3df552df75 100644 --- a/InvenTree/plugin/mixins/__init__.py +++ b/InvenTree/plugin/mixins/__init__.py @@ -2,10 +2,11 @@ Utility class to enable simpler imports """ -from ..builtin.integration.mixins import AppMixin, SettingsMixin, ScheduleMixin, UrlsMixin, NavigationMixin +from ..builtin.integration.mixins import AppMixin, SettingsMixin, EventMixin, ScheduleMixin, UrlsMixin, NavigationMixin __all__ = [ 'AppMixin', + 'EventMixin', 'NavigationMixin', 'ScheduleMixin', 'SettingsMixin',