mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	add a general context checker
This commit is contained in:
		| @@ -18,8 +18,10 @@ logger = logging.getLogger('inventree') | ||||
| # region base classes | ||||
| class NotificationMethod: | ||||
|     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 | ||||
|         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') | ||||
| @@ -32,10 +34,46 @@ class NotificationMethod: | ||||
|         self.obj = obj | ||||
|         self.entry_name = entry_name | ||||
|         self.receivers = receivers | ||||
|         self.context = self.check_context(context) | ||||
|  | ||||
|         # Gather 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): | ||||
|         raise NotImplementedError('The `get_recipients` method must be implemented!') | ||||
|  | ||||
| @@ -50,12 +88,12 @@ class NotificationMethod: | ||||
|  | ||||
|  | ||||
| class SingleNotificationMethod(NotificationMethod): | ||||
|     def send(self, receiver, context): | ||||
|     def send(self, receiver): | ||||
|         raise NotImplementedError('The `send` method must be overriden!') | ||||
|  | ||||
|  | ||||
| class BulkNotificationMethod(NotificationMethod): | ||||
|     def send_bulk(self, context): | ||||
|     def send_bulk(self): | ||||
|         raise NotImplementedError('The `send` method must be overriden!') | ||||
| # endregion | ||||
|  | ||||
| @@ -63,26 +101,22 @@ class BulkNotificationMethod(NotificationMethod): | ||||
| # region implementations | ||||
| class EmailNotification(BulkNotificationMethod): | ||||
|     METHOD_NAME = 'mail' | ||||
|     CONTEXT_EXTRA = [ | ||||
|         ('template', ), | ||||
|         ('template', 'html', ), | ||||
|         ('template', 'subject', ), | ||||
|     ] | ||||
|  | ||||
|     def get_recipients(self): | ||||
|         return EmailAddress.objects.filter( | ||||
|             user__in=self.receivers, | ||||
|         ) | ||||
|  | ||||
|     def send_bulk(self, context): | ||||
|         # TODO: In the future, include the part image in the email template | ||||
|  | ||||
|         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) | ||||
|     def send_bulk(self): | ||||
|         html_message = render_to_string(self.context['template']['html'], self.context) | ||||
|         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 | ||||
|  | ||||
| @@ -92,14 +126,14 @@ class UIMessageNotification(SingleNotificationMethod): | ||||
|     def get_recipients(self): | ||||
|         return self.receivers | ||||
|  | ||||
|     def send(self, receiver, context): | ||||
|     def send(self, receiver): | ||||
|         NotificationMessage.objects.create( | ||||
|             target_object = self.obj, | ||||
|             source_object = receiver, | ||||
|             user = receiver, | ||||
|             category = self.entry_name, | ||||
|             name = context['name'], | ||||
|             message = context['message'], | ||||
|             name = self.context['name'], | ||||
|             message = self.context['message'], | ||||
|         ) | ||||
| # 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): | ||||
|     # 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: | ||||
|         # Log start | ||||
| @@ -179,12 +213,12 @@ def deliver_notification(cls: NotificationMethod, obj, entry_name: str, receiver | ||||
|  | ||||
|         # Select delivery method and execute it | ||||
|         if hasattr(method, 'send_bulk'): | ||||
|             success = method.send_bulk(notification_context) | ||||
|             success = method.send_bulk() | ||||
|             success_count = len(method.recipients) | ||||
|  | ||||
|         elif hasattr(method, 'send'): | ||||
|             for rec in method.recipients: | ||||
|                 if method.send(rec, notification_context): | ||||
|                 if method.send(rec): | ||||
|                     success_count += 1 | ||||
|                 else: | ||||
|                     success = False | ||||
|   | ||||
		Reference in New Issue
	
	Block a user