mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
add a general context checker
This commit is contained in:
parent
3239e60702
commit
1cfc03d698
@ -18,8 +18,10 @@ logger = logging.getLogger('inventree')
|
|||||||
# region base classes
|
# region base classes
|
||||||
class NotificationMethod:
|
class NotificationMethod:
|
||||||
METHOD_NAME = ''
|
METHOD_NAME = ''
|
||||||
|
CONTEXT_BUILTIN = ['name', 'message', ]
|
||||||
|
CONTEXT_EXTRA = []
|
||||||
|
|
||||||
def __init__(self, obj, entry_name, receivers) -> None:
|
def __init__(self, obj, entry_name, receivers, context) -> None:
|
||||||
# Check if a sending fnc is defined
|
# Check if a sending fnc is defined
|
||||||
if (not hasattr(self, 'send')) and (not hasattr(self, 'send_bulk')):
|
if (not hasattr(self, 'send')) and (not hasattr(self, 'send_bulk')):
|
||||||
raise NotImplementedError('A NotificationMethod must either define a `send` or a `send_bulk` method')
|
raise NotImplementedError('A NotificationMethod must either define a `send` or a `send_bulk` method')
|
||||||
@ -32,10 +34,46 @@ class NotificationMethod:
|
|||||||
self.obj = obj
|
self.obj = obj
|
||||||
self.entry_name = entry_name
|
self.entry_name = entry_name
|
||||||
self.receivers = receivers
|
self.receivers = receivers
|
||||||
|
self.context = self.check_context(context)
|
||||||
|
|
||||||
# Gather recipients
|
# Gather recipients
|
||||||
self.recipients = self.get_recipients()
|
self.recipients = self.get_recipients()
|
||||||
|
|
||||||
|
def check_context(self, context):
|
||||||
|
def check(ref, obj):
|
||||||
|
# the obj is not accesible so we are on the end
|
||||||
|
if not isinstance(obj, (list, dict, tuple, )):
|
||||||
|
return ref
|
||||||
|
|
||||||
|
# check if the ref exsists
|
||||||
|
if isinstance(ref, str):
|
||||||
|
if not obj.get(ref):
|
||||||
|
return ref
|
||||||
|
return False
|
||||||
|
|
||||||
|
# nested
|
||||||
|
elif isinstance(ref, (tuple, list)):
|
||||||
|
if len(ref) == 1:
|
||||||
|
return check(ref[0], obj)
|
||||||
|
ret = check(ref[0], obj)
|
||||||
|
if ret:
|
||||||
|
return ret
|
||||||
|
return check(ref[1:], obj[ref[0]])
|
||||||
|
|
||||||
|
# other cases -> raise
|
||||||
|
raise NotImplementedError('This type can not be used as a context reference')
|
||||||
|
|
||||||
|
missing = []
|
||||||
|
for item in (*self.CONTEXT_BUILTIN, *self.CONTEXT_EXTRA):
|
||||||
|
ret = check(item, context)
|
||||||
|
if ret:
|
||||||
|
missing.append(ret)
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
raise NotImplementedError(f'The `context` is missing the following items:\n{missing}')
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
def get_recipients(self):
|
def get_recipients(self):
|
||||||
raise NotImplementedError('The `get_recipients` method must be implemented!')
|
raise NotImplementedError('The `get_recipients` method must be implemented!')
|
||||||
|
|
||||||
@ -50,12 +88,12 @@ class NotificationMethod:
|
|||||||
|
|
||||||
|
|
||||||
class SingleNotificationMethod(NotificationMethod):
|
class SingleNotificationMethod(NotificationMethod):
|
||||||
def send(self, receiver, context):
|
def send(self, receiver):
|
||||||
raise NotImplementedError('The `send` method must be overriden!')
|
raise NotImplementedError('The `send` method must be overriden!')
|
||||||
|
|
||||||
|
|
||||||
class BulkNotificationMethod(NotificationMethod):
|
class BulkNotificationMethod(NotificationMethod):
|
||||||
def send_bulk(self, context):
|
def send_bulk(self):
|
||||||
raise NotImplementedError('The `send` method must be overriden!')
|
raise NotImplementedError('The `send` method must be overriden!')
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
@ -63,26 +101,22 @@ class BulkNotificationMethod(NotificationMethod):
|
|||||||
# region implementations
|
# region implementations
|
||||||
class EmailNotification(BulkNotificationMethod):
|
class EmailNotification(BulkNotificationMethod):
|
||||||
METHOD_NAME = 'mail'
|
METHOD_NAME = 'mail'
|
||||||
|
CONTEXT_EXTRA = [
|
||||||
|
('template', ),
|
||||||
|
('template', 'html', ),
|
||||||
|
('template', 'subject', ),
|
||||||
|
]
|
||||||
|
|
||||||
def get_recipients(self):
|
def get_recipients(self):
|
||||||
return EmailAddress.objects.filter(
|
return EmailAddress.objects.filter(
|
||||||
user__in=self.receivers,
|
user__in=self.receivers,
|
||||||
)
|
)
|
||||||
|
|
||||||
def send_bulk(self, context):
|
def send_bulk(self):
|
||||||
# TODO: In the future, include the part image in the email template
|
html_message = render_to_string(self.context['template']['html'], self.context)
|
||||||
|
|
||||||
if 'template' not in context:
|
|
||||||
raise NotImplementedError('Templates must be provided in the `context`')
|
|
||||||
if 'html' not in context['template']:
|
|
||||||
raise NotImplementedError("template['html'] must be provided in the `context`")
|
|
||||||
if 'subject' not in context['template']:
|
|
||||||
raise NotImplementedError("template['subject'] must be provided in the `context`")
|
|
||||||
|
|
||||||
html_message = render_to_string(context['template']['html'], context)
|
|
||||||
recipients = self.recipients.values_list('email', flat=True)
|
recipients = self.recipients.values_list('email', flat=True)
|
||||||
|
|
||||||
InvenTree.tasks.send_email(context['template']['subject'], '', recipients, html_message=html_message)
|
InvenTree.tasks.send_email(self.context['template']['subject'], '', recipients, html_message=html_message)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -92,14 +126,14 @@ class UIMessageNotification(SingleNotificationMethod):
|
|||||||
def get_recipients(self):
|
def get_recipients(self):
|
||||||
return self.receivers
|
return self.receivers
|
||||||
|
|
||||||
def send(self, receiver, context):
|
def send(self, receiver):
|
||||||
NotificationMessage.objects.create(
|
NotificationMessage.objects.create(
|
||||||
target_object = self.obj,
|
target_object = self.obj,
|
||||||
source_object = receiver,
|
source_object = receiver,
|
||||||
user = receiver,
|
user = receiver,
|
||||||
category = self.entry_name,
|
category = self.entry_name,
|
||||||
name = context['name'],
|
name = self.context['name'],
|
||||||
message = context['message'],
|
message = self.context['message'],
|
||||||
)
|
)
|
||||||
# endregion
|
# endregion
|
||||||
# endregion
|
# endregion
|
||||||
@ -165,7 +199,7 @@ def trigger_notifaction(obj, entry_name=None, obj_ref='pk', receivers=None, rece
|
|||||||
|
|
||||||
def deliver_notification(cls: NotificationMethod, obj, entry_name: str, receivers, notification_context: dict):
|
def deliver_notification(cls: NotificationMethod, obj, entry_name: str, receivers, notification_context: dict):
|
||||||
# Init delivery method
|
# Init delivery method
|
||||||
method = cls(obj, entry_name, receivers)
|
method = cls(obj, entry_name, receivers, notification_context)
|
||||||
|
|
||||||
if method.recipients and len(method.recipients) > 0:
|
if method.recipients and len(method.recipients) > 0:
|
||||||
# Log start
|
# Log start
|
||||||
@ -179,12 +213,12 @@ def deliver_notification(cls: NotificationMethod, obj, entry_name: str, receiver
|
|||||||
|
|
||||||
# Select delivery method and execute it
|
# Select delivery method and execute it
|
||||||
if hasattr(method, 'send_bulk'):
|
if hasattr(method, 'send_bulk'):
|
||||||
success = method.send_bulk(notification_context)
|
success = method.send_bulk()
|
||||||
success_count = len(method.recipients)
|
success_count = len(method.recipients)
|
||||||
|
|
||||||
elif hasattr(method, 'send'):
|
elif hasattr(method, 'send'):
|
||||||
for rec in method.recipients:
|
for rec in method.recipients:
|
||||||
if method.send(rec, notification_context):
|
if method.send(rec):
|
||||||
success_count += 1
|
success_count += 1
|
||||||
else:
|
else:
|
||||||
success = False
|
success = False
|
||||||
|
Loading…
Reference in New Issue
Block a user