コード例 #1
0
ファイル: account.py プロジェクト: balazs-endresz/wagtail
def change_avatar(request):
    if request.method == 'POST':
        user_profile = UserProfile.get_for_user(request.user)
        form = AvatarPreferencesForm(request.POST, request.FILES, instance=user_profile)
        if form.is_valid():
            form.save()
            messages.success(request, _("Your preferences have been updated successfully!"))
            return redirect('wagtailadmin_account_change_avatar')
    else:
        form = AvatarPreferencesForm(instance=UserProfile.get_for_user(request.user))

    return render(request, 'wagtailadmin/account/change_avatar.html', {'form': form})
コード例 #2
0
ファイル: account.py プロジェクト: balazs-endresz/wagtail
def current_time_zone(request):
    if request.method == 'POST':
        form = CurrentTimeZoneForm(request.POST, instance=UserProfile.get_for_user(request.user))

        if form.is_valid():
            form.save()
            messages.success(request, _("Your preferences have been updated."))
            return redirect('wagtailadmin_account')
    else:
        form = CurrentTimeZoneForm(instance=UserProfile.get_for_user(request.user))

    return render(request, 'wagtailadmin/account/current_time_zone.html', {
        'form': form,
    })
コード例 #3
0
    def test_uploaded_avatar(self):
        user_profile = UserProfile.get_for_user(self.test_user)
        user_profile.avatar = get_test_image_file(filename='custom-avatar.png')
        user_profile.save()

        url = avatar_url(self.test_user)
        self.assertIn('custom-avatar', url)
コード例 #4
0
def language_preferences(request):
    if request.method == 'POST':
        form = PreferredLanguageForm(request.POST, instance=UserProfile.get_for_user(request.user))

        if form.is_valid():
            user_profile = form.save()
            # This will set the language only for this request/thread
            # (so that the 'success' messages is in the right language)
            activate(user_profile.get_preferred_language())
            messages.success(request, _("Your preferences have been updated."))
            return redirect('wagtailadmin_account')
    else:
        form = PreferredLanguageForm(instance=UserProfile.get_for_user(request.user))

    return render(request, 'wagtailadmin/account/language_preferences.html', {
        'form': form,
    })
コード例 #5
0
    def test_set_custom_avatar_stores_and_get_custom_avatar(self):
        response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
                                    {'avatar': self.avatar},
                                    follow=True)

        self.assertEqual(response.status_code, 200)

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
        self.assertIn(os.path.basename(self.avatar.name), profile.avatar.url)
コード例 #6
0
def notification_preferences(request):
    if request.method == 'POST':
        form = NotificationPreferencesForm(request.POST, instance=UserProfile.get_for_user(request.user))

        if form.is_valid():
            form.save()
            messages.success(request, _("Your preferences have been updated."))
            return redirect('wagtailadmin_account')
    else:
        form = NotificationPreferencesForm(instance=UserProfile.get_for_user(request.user))

    # quick-and-dirty catch-all in case the form has been rendered with no
    # fields, as the user has no customisable permissions
    if not form.fields:
        return redirect('wagtailadmin_account')

    return render(request, 'wagtailadmin/account/notification_preferences.html', {
        'form': form,
    })
コード例 #7
0
    def process_request(self, request):
        tzname = None

        if request.user and not request.user.is_anonymous:
            up = UserProfile.get_for_user(request.user)
            tzname = up.timezone

        if tzname:
            timezone.activate(pytz.timezone(tzname))
        else:
            timezone.deactivate()
コード例 #8
0
    def test_unset_language_preferences(self):
        # Post new values to the language preferences page
        post_data = {
            'preferred_language': ''
        }
        response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the language preferences are stored
        self.assertEqual(profile.preferred_language, '')
コード例 #9
0
    def test_unset_current_time_zone(self):
        # Post new values to the current time zone page
        post_data = {
            'current_time_zone': ''
        }
        response = self.client.post(reverse('wagtailadmin_account_current_time_zone'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the current time zone are stored
        self.assertEqual(profile.current_time_zone, '')
コード例 #10
0
def notification_preferences(request):
    if request.method == 'POST':
        form = NotificationPreferencesForm(request.POST,
                                           instance=UserProfile.get_for_user(
                                               request.user))

        if form.is_valid():
            form.save()
            messages.success(request, _("Your preferences have been updated."))
            return redirect('wagtailadmin_account')
    else:
        form = NotificationPreferencesForm(
            instance=UserProfile.get_for_user(request.user))

    # quick-and-dirty catch-all in case the form has been rendered with no
    # fields, as the user has no customisable permissions
    if not form.fields:
        return redirect('wagtailadmin_account')

    return render(request,
                  'wagtailadmin/account/notification_preferences.html', {
                      'form': form,
                  })
コード例 #11
0
    def test_unset_language_preferences(self):
        # Post new values to the language preferences page
        post_data = {
            'preferred_language': ''
        }
        response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the language preferences are stored
        self.assertEqual(profile.preferred_language, '')
コード例 #12
0
    def test_unset_current_time_zone(self):
        # Post new values to the current time zone page
        post_data = {'current_time_zone': ''}
        response = self.client.post(
            reverse('wagtailadmin_account_current_time_zone'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(
            get_user_model().objects.get(pk=self.user.pk))

        # Check that the current time zone are stored
        self.assertEqual(profile.current_time_zone, '')
コード例 #13
0
    def test_clear_removes_current_avatar(self):
        """
        Tests that submitting a blank value for avatar doesn't remove it.
        """
        profile = UserProfile.get_for_user(self.user)
        profile.avatar = self.avatar
        profile.save()

        # Upload a new avatar
        response = self.post_form({"avatar-clear": "on"})
        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse("wagtailadmin_account"))

        # Check the avatar was changed
        profile.refresh_from_db()
        self.assertIn("test.png", profile.avatar.url)
コード例 #14
0
    def test_change_language_preferences(self):
        response = self.post_form({
            "locale-preferred_language": "es",
        })

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse("wagtailadmin_account"))

        profile = UserProfile.get_for_user(self.user)
        profile.refresh_from_db()

        # Check that the language preferences are stored
        self.assertEqual(profile.preferred_language, "es")

        # check that the updated language preference is now indicated in HTML header
        response = self.client.get(reverse("wagtailadmin_home"))
        self.assertContains(response, '<html lang="es" dir="ltr">')
コード例 #15
0
    def save(self, commit=True):
        user = super().save(commit=False)

        if self.password_enabled:
            password = self.cleaned_data['password1']
            if password:
                user.set_password(password)

        if commit:
            user.save()
            self.save_m2m()

        if self.cleaned_data["timezone"]:
            profile = UserProfile.get_for_user(user)
            profile.timezone = self.cleaned_data["timezone"]
            profile.save()

        return user
コード例 #16
0
    def test_current_time_zone_view_post(self):
        """
        This posts to the current time zone view and checks that the
        user profile is updated
        """
        # Post new values to the current time zone page
        post_data = {
            'current_time_zone': 'Pacific/Fiji'
        }
        response = self.client.post(reverse('wagtailadmin_account_current_time_zone'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the current time zone is stored
        self.assertEqual(profile.current_time_zone, 'Pacific/Fiji')
コード例 #17
0
    def test_user_upload_another_image_removes_previous_one(self):
        response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
                                    {'avatar': self.avatar},
                                    follow=True)
        self.assertEqual(response.status_code, 200)

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
        old_avatar_path = profile.avatar.path

        # Upload a new avatar
        new_response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
                                        {'avatar': self.other_avatar},
                                        follow=True)
        self.assertEqual(new_response.status_code, 200)

        # Check old avatar doesn't exist anymore in filesystem
        with self.assertRaises(FileNotFoundError):
            open(old_avatar_path)
コード例 #18
0
    def test_change_notifications(self):
        response = self.post_form({
            'submitted_notifications': 'false',
            'approved_notifications': 'false',
            'rejected_notifications': 'true',
            'updated_comments_notifications': 'true',
        })

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the notification preferences are as submitted
        self.assertFalse(profile.submitted_notifications)
        self.assertFalse(profile.approved_notifications)
        self.assertTrue(profile.rejected_notifications)
        self.assertTrue(profile.updated_comments_notifications)
コード例 #19
0
    def test_current_time_zone_view_post(self):
        """
        This posts to the current time zone view and checks that the
        user profile is updated
        """
        # Post new values to the current time zone page
        post_data = {'current_time_zone': 'Pacific/Fiji'}
        response = self.client.post(
            reverse('wagtailadmin_account_current_time_zone'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(
            get_user_model().objects.get(pk=self.user.pk))

        # Check that the current time zone is stored
        self.assertEqual(profile.current_time_zone, 'Pacific/Fiji')
コード例 #20
0
    def test_user_upload_another_image_removes_previous_one(self):
        response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
                                    {'avatar': self.avatar},
                                    follow=True)
        self.assertEqual(response.status_code, 200)

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
        old_avatar_path = profile.avatar.path

        # Upload a new avatar
        new_response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
                                        {'avatar': self.other_avatar},
                                        follow=True)
        self.assertEqual(new_response.status_code, 200)

        # Check old avatar doesn't exist anymore in filesystem
        with self.assertRaises(FileNotFoundError):
            open(old_avatar_path)
コード例 #21
0
    def test_unset_language_preferences(self):
        profile = UserProfile.get_for_user(self.user)
        profile.preferred_language = "en"
        profile.save()

        response = self.post_form({
            "locale-preferred_language": "",
        })

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse("wagtailadmin_account"))

        # Check that the language preferences are stored
        profile.refresh_from_db()
        self.assertEqual(profile.preferred_language, "")

        # Check that the current language is assumed as English
        self.assertEqual(profile.get_preferred_language(), "en")
コード例 #22
0
    def __init__(self, *args, **kwargs):
        instance = kwargs.get('instance')
        initial = kwargs.get('initial')

        if instance is not None:
            if initial is None:
                initial = {}
            initial['timezone'] = UserProfile.get_for_user(instance).timezone
            kwargs['initial'] = initial

        super().__init__(*args, **kwargs)

        if self.password_enabled:
            if self.password_required:
                self.fields['password1'].help_text = mark_safe(password_validators_help_text_html())
                self.fields['password1'].required = True
                self.fields['password2'].required = True
        else:
            del self.fields['password1']
            del self.fields['password2']
コード例 #23
0
    def test_user_upload_another_image_removes_previous_one(self):
        profile = UserProfile.get_for_user(self.user)
        profile.avatar = self.avatar
        profile.save()

        old_avatar_path = profile.avatar.path

        # Upload a new avatar
        response = self.post_form({
            'avatar-avatar': SimpleUploadedFile('other.png', self.other_avatar.file.getvalue())
        })
        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        # Check the avatar was changed
        profile.refresh_from_db()
        self.assertIn('other.png', profile.avatar.url)

        # Check old avatar doesn't exist anymore in filesystem
        with self.assertRaises(FileNotFoundError):
            open(old_avatar_path)
コード例 #24
0
    def test_language_preferences_view_post(self):
        """
        This posts to the language preferences view and checks that the
        user profile is updated
        """
        # Post new values to the language preferences page
        post_data = {
            'preferred_language': 'es'
        }
        response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the language preferences are stored
        self.assertEqual(profile.preferred_language, 'es')

        # check that the updated language preference is now indicated in HTML header
        response = self.client.get(reverse('wagtailadmin_home'))
        self.assertContains(response, '<html class="no-js" lang="es">')
コード例 #25
0
    def test_language_preferences_view_post(self):
        """
        This posts to the language preferences view and checks that the
        user profile is updated
        """
        # Post new values to the language preferences page
        post_data = {
            'preferred_language': 'es'
        }
        response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the language preferences are stored
        self.assertEqual(profile.preferred_language, 'es')

        # check that the updated language preference is now indicated in HTML header
        response = self.client.get(reverse('wagtailadmin_home'))
        self.assertContains(response, '<html class="no-js" lang="es" dir="ltr">')
コード例 #26
0
    def test_notification_preferences_view_post(self):
        """
        This posts to the notification preferences view and checks that the
        user's profile is updated
        """
        # Post new values to the notification preferences page
        post_data = {
            'submitted_notifications': 'false',
            'approved_notifications': 'false',
            'rejected_notifications': 'true',
        }
        response = self.client.post(reverse('wagtailadmin_account_notification_preferences'), post_data)

        # Check that the user was redirected to the account page
        self.assertRedirects(response, reverse('wagtailadmin_account'))

        profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))

        # Check that the notification preferences are as submitted
        self.assertFalse(profile.submitted_notifications)
        self.assertFalse(profile.approved_notifications)
        self.assertTrue(profile.rejected_notifications)
コード例 #27
0
ファイル: wagtailuserbar.py プロジェクト: jams2/wagtail
def wagtailuserbar(context, position="bottom-right"):
    # Find request object
    try:
        request = context["request"]
    except KeyError:
        return ""

    # Don't render without a user because we can't check their permissions
    try:
        user = request.user
    except AttributeError:
        return ""

    # Don't render if user doesn't have permission to access the admin area
    if not user.has_perm("wagtailadmin.access_admin"):
        return ""

    # Render the userbar using the user's preferred admin language
    userprofile = UserProfile.get_for_user(user)
    with translation.override(userprofile.get_preferred_language()):
        page = get_page_instance(context)

        try:
            revision_id = request.revision_id
        except AttributeError:
            revision_id = None

        if page and page.id:
            if revision_id:
                items = [
                    AdminItem(),
                    ExplorePageItem(
                        PageRevision.objects.get(id=revision_id).page),
                    EditPageItem(
                        PageRevision.objects.get(id=revision_id).page),
                    ApproveModerationEditPageItem(
                        PageRevision.objects.get(id=revision_id)),
                    RejectModerationEditPageItem(
                        PageRevision.objects.get(id=revision_id)),
                ]
            else:
                # Not a revision
                items = [
                    AdminItem(),
                    ExplorePageItem(Page.objects.get(id=page.id)),
                    EditPageItem(Page.objects.get(id=page.id)),
                    AddPageItem(Page.objects.get(id=page.id)),
                ]
        else:
            # Not a page.
            items = [AdminItem()]

        for fn in hooks.get_hooks("construct_wagtail_userbar"):
            fn(request, items)

        # Render the items
        rendered_items = [item.render(request) for item in items]

        # Remove any unrendered items
        rendered_items = [item for item in rendered_items if item]

        # Render the userbar items
        return render_to_string(
            "wagtailadmin/userbar/base.html",
            {
                "request": request,
                "items": rendered_items,
                "position": position,
                "page": page,
                "revision_id": revision_id,
            },
        )
コード例 #28
0
ファイル: account.py プロジェクト: jams2/wagtail
def account(request):
    # Fetch the user and profile objects once and pass into each panel
    # We need to use the same instances for all forms so they don't overwrite each other
    user = request.user
    profile = UserProfile.get_for_user(user)

    # Panels
    panels = [
        NameEmailSettingsPanel(request, user, profile),
        AvatarSettingsPanel(request, user, profile),
        NotificationsSettingsPanel(request, user, profile),
        LocaleSettingsPanel(request, user, profile),
        ChangePasswordPanel(request, user, profile),
    ]
    for fn in hooks.get_hooks("register_account_settings_panel"):
        panel = fn(request, user, profile)
        if panel and panel.is_active():
            panels.append(panel)

    panels = [panel for panel in panels if panel.is_active()]

    # Get tabs and order them
    tabs = list({panel.tab for panel in panels})
    tabs.sort(key=lambda tab: tab.order)

    # Get dict of tabs to ordered panels
    panels_by_tab = OrderedDict([(tab, []) for tab in tabs])
    for panel in panels:
        panels_by_tab[panel.tab].append(panel)
    for tab, tab_panels in panels_by_tab.items():
        tab_panels.sort(key=lambda panel: panel.order)

    panel_forms = [panel.get_form() for panel in panels]

    if request.method == "POST":

        if all(form.is_valid() or not form.is_bound for form in panel_forms):
            with transaction.atomic():
                for form in panel_forms:
                    if form.is_bound:
                        form.save()

            log(user, "wagtail.edit")

            # Prevent a password change from logging this user out
            update_session_auth_hash(request, user)

            # Override the language when creating the success message
            # If the user has changed their language in this request, the message should
            # be in the new language, not the existing one
            with override(profile.get_preferred_language()):
                messages.success(
                    request,
                    _("Your account settings have been changed successfully!"))

            return redirect("wagtailadmin_account")

    media = Media()
    for form in panel_forms:
        media += form.media

    # Menu items
    menu_items = []
    for fn in hooks.get_hooks("register_account_menu_item"):
        item = fn(request)
        if item:
            menu_items.append(item)

    return TemplateResponse(
        request,
        "wagtailadmin/account/account.html",
        {
            "panels_by_tab": panels_by_tab,
            "menu_items": menu_items,
            "media": media,
        },
    )
コード例 #29
0
def send_notification(page_revision_id, notification, excluded_user_id):
    # Get revision
    revision = PageRevision.objects.get(id=page_revision_id)

    # Get list of recipients
    if notification == 'submitted':
        # Get list of publishers
        include_superusers = getattr(
            settings, 'WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS', True)
        recipients = users_with_page_permission(revision.page, 'publish',
                                                include_superusers)
    elif notification in ['rejected', 'approved']:
        # Get submitter
        recipients = [revision.user]
    else:
        return False

    # Get list of email addresses
    email_recipients = [
        recipient for recipient in recipients
        if recipient.email and recipient.pk != excluded_user_id
        and getattr(UserProfile.get_for_user(recipient), notification +
                    '_notifications')
    ]

    # Return if there are no email addresses
    if not email_recipients:
        return True

    # Get template
    template_subject = 'wagtailadmin/notifications/' + notification + '_subject.txt'
    template_text = 'wagtailadmin/notifications/' + notification + '.txt'
    template_html = 'wagtailadmin/notifications/' + notification + '.html'

    # Common context to template
    context = {
        "revision": revision,
        "settings": settings,
    }

    # Send emails
    sent_count = 0
    for recipient in email_recipients:
        try:
            # update context with this recipient
            context["user"] = recipient

            # Translate text to the recipient language settings
            with override(
                    recipient.wagtail_userprofile.get_preferred_language()):
                # Get email subject and content
                email_subject = render_to_string(template_subject,
                                                 context).strip()
                email_content = render_to_string(template_text,
                                                 context).strip()

            kwargs = {}
            if getattr(settings, 'WAGTAILADMIN_NOTIFICATION_USE_HTML', False):
                kwargs['html_message'] = render_to_string(
                    template_html, context)

            # Send email
            send_mail(email_subject, email_content, [recipient.email],
                      **kwargs)
            sent_count += 1
        except Exception:
            logger.exception("Failed to send notification email '%s' to %s",
                             email_subject, recipient.email)

    return sent_count == len(email_recipients)
コード例 #30
0
ファイル: utils.py プロジェクト: BertrandBordage/wagtail
def send_notification(page_revision_id, notification, excluded_user_id):
    # Get revision
    revision = PageRevision.objects.get(id=page_revision_id)

    # Get list of recipients
    if notification == 'submitted':
        # Get list of publishers
        include_superusers = getattr(settings, 'WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS', True)
        recipients = users_with_page_permission(revision.page, 'publish', include_superusers)
    elif notification in ['rejected', 'approved']:
        # Get submitter
        recipients = [revision.user]
    else:
        return False

    # Get list of email addresses
    email_recipients = [
        recipient for recipient in recipients
        if recipient.email and recipient.pk != excluded_user_id and getattr(
            UserProfile.get_for_user(recipient),
            notification + '_notifications'
        )
    ]

    # Return if there are no email addresses
    if not email_recipients:
        return True

    # Get template
    template_subject = 'wagtailadmin/notifications/' + notification + '_subject.txt'
    template_text = 'wagtailadmin/notifications/' + notification + '.txt'
    template_html = 'wagtailadmin/notifications/' + notification + '.html'

    # Common context to template
    context = {
        "revision": revision,
        "settings": settings,
    }

    # Send emails
    sent_count = 0
    for recipient in email_recipients:
        try:
            # update context with this recipient
            context["user"] = recipient

            # Translate text to the recipient language settings
            with override(recipient.wagtail_userprofile.get_preferred_language()):
                # Get email subject and content
                email_subject = render_to_string(template_subject, context).strip()
                email_content = render_to_string(template_text, context).strip()

            kwargs = {}
            if getattr(settings, 'WAGTAILADMIN_NOTIFICATION_USE_HTML', False):
                kwargs['html_message'] = render_to_string(template_html, context)

            # Send email
            send_mail(email_subject, email_content, [recipient.email], **kwargs)
            sent_count += 1
        except Exception:
            logger.exception(
                "Failed to send notification email '%s' to %s",
                email_subject, recipient.email
            )

    return sent_count == len(email_recipients)
コード例 #31
0
ファイル: mail.py プロジェクト: tnir/wagtail
def send_notification(recipient_users, notification, extra_context):
    # Get list of email addresses
    email_recipients = [
        recipient for recipient in recipient_users
        if recipient.is_active and recipient.email
        and getattr(UserProfile.get_for_user(recipient), notification +
                    "_notifications")
    ]

    # Return if there are no email addresses
    if not email_recipients:
        return True

    # Get template
    template_subject = "wagtailadmin/notifications/" + notification + "_subject.txt"
    template_text = "wagtailadmin/notifications/" + notification + ".txt"
    template_html = "wagtailadmin/notifications/" + notification + ".html"

    # Common context to template
    context = {
        "settings": settings,
    }
    context.update(extra_context)

    connection = get_connection()

    with OpenedConnection(connection) as open_connection:

        # Send emails
        sent_count = 0
        for recipient in email_recipients:
            # update context with this recipient
            context["user"] = recipient

            # Translate text to the recipient language settings
            with override(
                    recipient.wagtail_userprofile.get_preferred_language()):
                # Get email subject and content
                email_subject = render_to_string(template_subject,
                                                 context).strip()
                email_content = render_to_string(template_text,
                                                 context).strip()

            kwargs = {}
            if getattr(settings, "WAGTAILADMIN_NOTIFICATION_USE_HTML", False):
                kwargs["html_message"] = render_to_string(
                    template_html, context)

            try:
                # Send email
                send_mail(
                    email_subject,
                    email_content,
                    [recipient.email],
                    connection=open_connection,
                    **kwargs,
                )
                sent_count += 1
            except Exception:
                logger.exception(
                    "Failed to send notification email '%s' to %s",
                    email_subject,
                    recipient.email,
                )

    return sent_count == len(email_recipients)