0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-12-01 11:41:20 +01:00

Remove Notifier submit, reject, approve methods, and replace with specific subclasses of Notifier

This commit is contained in:
jacobtm 2020-01-30 14:43:29 +00:00 committed by Matt Westcott
parent 21cc989913
commit ceb17fa849
2 changed files with 129 additions and 67 deletions

View File

@ -136,35 +136,38 @@ def send_notification(page_revision_id, notification, excluded_user_id):
class Notifier:
"""Class for sending email notifications upon events: callable, taking a notifying_instance and a notification (str)
"""Class for sending email notifications upon events: callable, taking a instance and a notification (str)
and sending email notifications using rendered templates"""
def __init__(self, valid_classes, valid_notifications):
notification = ''
def __init__(self, valid_classes):
self.valid_classes = valid_classes
self.valid_notifications = valid_notifications
def can_handle(self, notifying_instance, notification, **kwargs):
return isinstance(notifying_instance, self.valid_classes) and notification in self.valid_notifications
def can_handle(self, instance, **kwargs):
return isinstance(instance, self.valid_classes)
def get_recipient_users(self, instance, **kwargs):
"""Gets the ideal set of recipient users, without accounting for notification preferences or missing email addresses"""
def get_recipient_users(self, notifying_instance, notification, **kwargs):
return set()
def get_valid_recipients(self, notifying_instance, notification, **kwargs):
def get_valid_recipients(self, instance, **kwargs):
"""Filters notification recipients to those allowing the notification type on their UserProfile, and those
with an email address"""
return {recipient for recipient in self.get_recipient_users(notifying_instance, notification, **kwargs) if recipient.email and getattr(
return {recipient for recipient in self.get_recipient_users(instance, **kwargs) if recipient.email and getattr(
UserProfile.get_for_user(recipient),
notification + '_notifications'
self.notification + '_notifications'
)}
def get_template_base_prefix(self, notifying_instance, **kwargs):
return camelcase_to_underscore(type(notifying_instance).__name__)+'_'
def get_template_base_prefix(self, instance, **kwargs):
return camelcase_to_underscore(type(instance).__name__)+'_'
def get_template_set(self, notifying_instance, notification, **kwargs):
def get_template_set(self, instance, **kwargs):
"""Return a dictionary of template paths for the templates for the email subject and the text and html
alternatives"""
template_base = self.get_template_base_prefix(notifying_instance) + notification
template_base = self.get_template_base_prefix(instance) + self.notification
template_subject = 'wagtailadmin/notifications/' + template_base + '_subject.txt'
template_text = 'wagtailadmin/notifications/' + template_base + '.txt'
@ -176,7 +179,7 @@ class Notifier:
'html': template_html,
}
def get_context(self, notifying_instance, notification, **kwargs):
def get_context(self, instance, **kwargs):
return {'settings': settings}
def send_emails(self, template_set, context, recipients, **kwargs):
@ -214,80 +217,101 @@ class Notifier:
return sent_count == len(recipients)
def __call__(self, notifying_instance, notification, **kwargs):
"""Send emails corresponding to the notification (eg 'approved') from an instance, notifying_instance"""
def __call__(self, instance=None, **kwargs):
"""Send emails from an instance, returning True if all emails sent correctly"""
if not self.can_handle(notifying_instance, notification, **kwargs):
if not self.can_handle(instance, **kwargs):
return False
recipients = self.get_valid_recipients(notifying_instance, notification, **kwargs)
recipients = self.get_valid_recipients(instance, **kwargs)
if not recipients:
return True
template_set = self.get_template_set(notifying_instance, notification, **kwargs)
template_set = self.get_template_set(instance, **kwargs)
context = self.get_context(notifying_instance, notification, **kwargs)
context = self.get_context(instance, **kwargs)
return self.send_emails(template_set, context, recipients, **kwargs)
def approved(self, instance=None, **kwargs):
return self(instance, 'approved', **kwargs)
def rejected(self, instance=None, **kwargs):
return self(instance, 'rejected', **kwargs)
def submitted(self, instance=None, **kwargs):
return self(instance, 'submitted', **kwargs)
class WorkflowStateNotifier(Notifier):
class BaseWorkflowStateNotifier(Notifier):
"""A Notifier to send updates for WorkflowState events"""
def __init__(self, valid_notifications):
super().__init__((WorkflowState,), valid_notifications)
def __init__(self):
super().__init__((WorkflowState,))
def get_recipient_users(self, workflow_state, notification, **kwargs):
triggering_user = kwargs.get('user', None)
recipients = {}
if notification in ('approved', 'rejected'):
requested_by = workflow_state.requested_by
if requested_by != triggering_user:
recipients = {requested_by}
elif notification == 'submitted':
include_superusers = getattr(settings, 'WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS', True)
if include_superusers:
recipients = get_user_model().objects.filter(is_superuser=True)
if triggering_user:
recipients.exclude(pk=triggering_user.pk)
return recipients
def get_context(self, workflow_state, notification, **kwargs):
context = super().get_context(workflow_state, notification, **kwargs)
def get_context(self, workflow_state, **kwargs):
context = super().get_context(workflow_state, **kwargs)
context['page'] = workflow_state.page
context['workflow'] = workflow_state.workflow
return context
class GroupApprovalTaskStateNotifier(Notifier):
class WorkflowStateApprovalNotifier(BaseWorkflowStateNotifier):
"""A Notifier to send updates for WorkflowState approval events"""
notification = 'approved'
def get_recipient_users(self, workflow_state, **kwargs):
triggering_user = kwargs.get('user', None)
recipients = {}
requested_by = workflow_state.requested_by
if requested_by != triggering_user:
recipients = {requested_by}
return recipients
class WorkflowStateRejectionNotifier(BaseWorkflowStateNotifier):
"""A Notifier to send updates for WorkflowState rejection events"""
notification = 'rejected'
def get_recipient_users(self, workflow_state, **kwargs):
triggering_user = kwargs.get('user', None)
recipients = {}
requested_by = workflow_state.requested_by
if requested_by != triggering_user:
recipients = {requested_by}
return recipients
class WorkflowStateSubmissionNotifier(BaseWorkflowStateNotifier):
"""A Notifier to send updates for WorkflowState submission events"""
notification = 'submitted'
def get_recipient_users(self, workflow_state, **kwargs):
triggering_user = kwargs.get('user', None)
recipients = {}
include_superusers = getattr(settings, 'WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS', True)
if include_superusers:
recipients = get_user_model().objects.filter(is_superuser=True)
if triggering_user:
recipients.exclude(pk=triggering_user.pk)
return recipients
class BaseGroupApprovalTaskStateNotifier(Notifier):
"""A Notifier to send updates for GroupApprovalTask events"""
def __init__(self, valid_notifications):
super().__init__((TaskState,), valid_notifications)
def __init__(self):
super().__init__((TaskState,))
def can_handle(self, notifying_instance, notification, **kwargs):
return super().can_handle(notifying_instance, notification, **kwargs) and isinstance(notifying_instance.task.specific, GroupApprovalTask)
def can_handle(self, instance, **kwargs):
return super().can_handle(instance, **kwargs) and isinstance(instance.task.specific, GroupApprovalTask)
def get_context(self, task_state, notification, **kwargs):
context = super().get_context(task_state, notification, **kwargs)
def get_context(self, task_state, **kwargs):
context = super().get_context(task_state, **kwargs)
context['page'] = task_state.workflow_state.page
context['task'] = task_state.task.specific
return context
def get_recipient_users(self, task_state, notification, **kwargs):
def get_recipient_users(self, task_state, **kwargs):
triggering_user = kwargs.get('user', None)
requested_by = task_state.workflow_state.requested_by
group_members = task_state.task.specific.group.user_set.all()
recipients = group_members
@ -300,8 +324,43 @@ class GroupApprovalTaskStateNotifier(Notifier):
if triggering_user:
recipients = recipients.exclude(pk=triggering_user.pk)
return recipients
class GroupApprovalTaskStateSubmissionNotifier(BaseGroupApprovalTaskStateNotifier):
"""A Notifier to send updates for GroupApprovalTask submission events"""
notification = 'submitted'
class GroupApprovalTaskStateApprovalNotifier(BaseGroupApprovalTaskStateNotifier):
"""A Notifier to send updates for GroupApprovalTask approval events"""
notification = 'approved'
def get_recipient_users(self, task_state, **kwargs):
recipients = super().get_recipient_users(task_state, **kwargs)
requested_by = task_state.workflow_state.requested_by
# add the notifier's requester
if notification != "submitted" and (not triggering_user or triggering_user.pk != requested_by.pk):
triggering_user = kwargs.get('user', None)
if (not triggering_user or triggering_user.pk != requested_by.pk):
recipients = set(recipients)
recipients.add(requested_by)
return recipients
class GroupApprovalTaskStateRejectionNotifier(BaseGroupApprovalTaskStateNotifier):
"""A Notifier to send updates for GroupApprovalTask rejection events"""
notification = 'rejected'
def get_recipient_users(self, task_state, **kwargs):
recipients = super().get_recipient_users(task_state, **kwargs)
requested_by = task_state.workflow_state.requested_by
# add the notifier's requester
triggering_user = kwargs.get('user', None)
if (not triggering_user or triggering_user.pk != requested_by.pk):
recipients = set(recipients)
recipients.add(requested_by)

View File

@ -1,14 +1,17 @@
from wagtail.admin.mail import GroupApprovalTaskStateNotifier, WorkflowStateNotifier
from wagtail.admin.mail import GroupApprovalTaskStateSubmissionNotifier, WorkflowStateApprovalNotifier, WorkflowStateRejectionNotifier, WorkflowStateSubmissionNotifier
from wagtail.core.models import TaskState, WorkflowState
from wagtail.core.signals import task_submitted, workflow_approved, workflow_rejected, workflow_submitted
group_approval_task_state_notifier = GroupApprovalTaskStateNotifier({'submitted'})
workflow_state_notifier = WorkflowStateNotifier({'submitted', 'approved', 'rejected'})
task_submission_notifier = GroupApprovalTaskStateSubmissionNotifier()
workflow_submission_notifier = WorkflowStateSubmissionNotifier()
workflow_approval_notifier = WorkflowStateApprovalNotifier()
workflow_rejection_notifier = WorkflowStateRejectionNotifier()
def register_signal_handlers():
task_submitted.connect(group_approval_task_state_notifier.submitted, sender=TaskState, dispatch_uid='group_approval_task_submitted_email_notification')
task_submitted.connect(task_submission_notifier, sender=TaskState, dispatch_uid='group_approval_task_submitted_email_notification')
workflow_submitted.connect(workflow_state_notifier.submitted, sender=WorkflowState, dispatch_uid='workflow_state_submitted_email_notification')
workflow_rejected.connect(workflow_state_notifier.rejected, sender=WorkflowState, dispatch_uid='workflow_state_rejected_email_notification')
workflow_approved.connect(workflow_state_notifier.approved, sender=WorkflowState, dispatch_uid='workflow_state_approved_email_notification')
workflow_submitted.connect(workflow_submission_notifier, sender=WorkflowState, dispatch_uid='workflow_state_submitted_email_notification')
workflow_rejected.connect(workflow_rejection_notifier, sender=WorkflowState, dispatch_uid='workflow_state_rejected_email_notification')
workflow_approved.connect(workflow_approval_notifier, sender=WorkflowState, dispatch_uid='workflow_state_approved_email_notification')