Python django.conf.settings.ADMINS Examples

The following are 30 code examples for showing how to use django.conf.settings.ADMINS(). These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.

You may check out the related API usage on the sidebar.

You may also want to check out all available functions/classes of the module django.conf.settings , or try the search function .

Example 1
Project: opencraft   Author: open-craft   File: openedx_monitoring.py    License: GNU Affero General Public License v3.0 6 votes vote down vote up
def _set_email_alerts(self, alert_policy):
        """
        Set up email alerts.
        We add emails here but never remove them - that must be done manually (or the monitor deleted)
        in order to reduce the chance of bugs or misconfigurations accidentally suppressing monitors.
        """
        emails_to_monitor = set([email for name, email in settings.ADMINS] + self.additional_monitoring_emails)
        if emails_to_monitor:
            emails_current = set(
                NewRelicEmailNotificationChannel.objects.filter(
                    new_relic_alert_policies__id=alert_policy.id
                ).values_list('email', flat=True)
            )
            emails_to_add = list(emails_to_monitor - emails_current)
            if emails_to_add:
                self.logger.info(
                    'Adding email(s) to policy %s: %s', alert_policy.id, ', '.join(emails_to_add)
                )
                self._add_emails(alert_policy, emails_to_add) 
Example 2
Project: opencraft   Author: open-craft   File: utilities.py    License: GNU Affero General Public License v3.0 6 votes vote down vote up
def provision_failed_email(self, reason, log=None):
        """
        Send email notifications after a server's provisioning has failed.
        This will happen once for each deployment attempt if there are many.
        It will send notifications to settings.ADMINS.
        """
        attachments = []
        if log is not None:
            log_str = "\n".join(log)
            attachments.append(("provision.log", log_str, "text/plain"))

        self._send_email(
            self.EmailSubject.PROVISION_FAILED.format(name=self.name, instance_name=self.instance.name),
            self.EmailBody.PROVISION_FAILED.format(name=self.name, instance_name=self.instance.name, reason=reason),
            self._get_exc_info(default=None),
            attachments=attachments,
            extra_recipients=[],
        ) 
Example 3
Project: urbanfootprint   Author: CalthorpeAnalytics   File: global_user.py    License: GNU General Public License v3.0 6 votes vote down vote up
def users(self, **kargs):
        """
        Here we define admin-level users based on settings.ADMINS.
        Custom users at other permission levels should be
        declared in the UserFixture of the appropriate ConfigEntity. For example,
        users with Region permission should be declared in that region's UserFixture, unless
        the user needs permission to multiple regions, in which case it should probably go here

        :param kwargs:
        :return: A list of dicts representing Users
        """
        def create_admin_dict(admin_tuple):
            first_name, last_name = admin_tuple[0].rsplit(' ', 1)
            username = first_name.lower()
            return dict(groups=[UserGroupKey.SUPERADMIN],
                        username=username,
                        # Default pw is name@uf
                        # The software should force this to be changed immediately
                        password='%s@uf' % username,
                        email=admin_tuple[1])

        return map(lambda admin_tuple: create_admin_dict(admin_tuple),
                   settings.ADMINS) 
Example 4
Project: trunk-player   Author: ScanOC   File: models.py    License: MIT License 6 votes vote down vote up
def create_profile(sender, **kwargs):
    user = kwargs["instance"]
    if kwargs["created"]:
        default_plan = Plan.objects.get(pk=Plan.DEFAULT_PK)
        up = Profile(user=user, plan=default_plan)
        up.save()
        try:
            for tg in TalkGroupAccess.objects.filter(default_group=True):
                up.talkgroup_access.add(tg)
        except OperationalError:
            pass
        try:
            new_user_email = SiteOption.objects.get(name='SEND_ADMIN_EMAIL_ON_NEW_USER')
            if new_user_email.value_boolean_or_string() == True:
                send_mail(
                      'New {} User {}'.format(settings.SITE_TITLE, user.username),
                      'New User {} {} Username {} Email {} just registered'.format(user.first_name, user.last_name, user.username, user.email),
                      settings.SERVER_EMAIL,
                      [ mail for name, mail in settings.ADMINS],
                      fail_silently=False,
                     )
        except (SiteOption.DoesNotExist, OperationalError):
            pass 
Example 5
Project: django-organice   Author: Organice   File: adapters.py    License: Apache License 2.0 6 votes vote down vote up
def confirm_email(self, request, email_address):
        """
        Give superuser privileges automagically if the email address of a
        user confirming their email is listed in ``settings.ADMINS``.
        """
        super().confirm_email(request, email_address)

        if email_address.email in ADMIN_EMAIL_ADDRESSES:
            user = email_address.user
            user.is_staff = user.is_superuser = True
            user.save()

            messages.add_message(
                request, messages.INFO,
                _('Welcome Admin! You have been given superuser privileges. '
                  'Use them with caution.')
            ) 
Example 6
Project: Django-2-Web-Development-Cookbook-Third-Edition   Author: PacktPublishing   File: checks.py    License: MIT License 6 votes vote down vote up
def settings_check(app_configs, **kwargs):
    from django.conf import settings

    errors = []

    if not settings.ADMINS:
        errors.append(Warning(
            """
The system admins are not set in the project settings
""",
            obj=settings,
            hint="""
            In order to receive notifications when new videos are
            created, define system admins in your settings, like:

            ADMINS = (
                ("Admin", "administrator@example.com"),
            )
""",
            id="viral_videos.W001"))

    return errors 
Example 7
Project: Django-2-Web-Development-Cookbook-Third-Edition   Author: PacktPublishing   File: checks.py    License: MIT License 6 votes vote down vote up
def settings_check(app_configs, **kwargs):
    from django.conf import settings

    errors = []

    if not settings.ADMINS:
        errors.append(Warning(
            """
The system admins are not set in the project settings
""",
            obj=settings,
            hint="""
            In order to receive notifications when new videos are
            created, define system admins in your settings, like:

            ADMINS = (
                ("Admin", "administrator@example.com"),
            )
""",
            id="viral_videos.W001"))

    return errors 
Example 8
Project: micromasters   Author: mitodl   File: test_settings.py    License: BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def test_admin_settings(self):
        """Verify that we configure email with environment variable"""

        with mock.patch.dict('os.environ', {
            **REQUIRED_SETTINGS,
            'MICROMASTERS_ADMIN_EMAIL': ''
        }, clear=True):
            settings_vars = self.reload_settings()
            self.assertFalse(settings_vars.get('ADMINS', False))

        test_admin_email = 'cuddle_bunnies@example.com'
        with mock.patch.dict('os.environ', {
            **REQUIRED_SETTINGS,
            'MICROMASTERS_ADMIN_EMAIL': test_admin_email,
        }, clear=True):
            settings_vars = self.reload_settings()
            self.assertEqual(
                (('Admins', test_admin_email),),
                settings_vars['ADMINS']
            )
        # Manually set ADMIN to our test setting and verify e-mail
        # goes where we expect
        settings.ADMINS = (('Admins', test_admin_email),)
        mail.mail_admins('Test', 'message')
        self.assertIn(test_admin_email, mail.outbox[0].to) 
Example 9
Project: Django-3-Web-Development-Cookbook-Fourth-Edition   Author: PacktPublishing   File: checks.py    License: MIT License 6 votes vote down vote up
def settings_check(app_configs, **kwargs):
    from django.conf import settings

    errors = []

    if not settings.ADMINS:
        errors.append(Warning(
            """
The system admins are not set in the project settings
""",
            obj=settings,
            hint="""
            In order to receive notifications when new videos are
            created, define system admins in your settings, like:

            ADMINS = (
                ("Admin", "administrator@example.com"),
            )
""",
            id="viral_videos.W001"))

    return errors 
Example 10
Project: Django-3-Web-Development-Cookbook-Fourth-Edition   Author: PacktPublishing   File: checks.py    License: MIT License 6 votes vote down vote up
def settings_check(app_configs, **kwargs):
    from django.conf import settings

    errors = []

    if not settings.ADMINS:
        errors.append(Warning(
            """
The system admins are not set in the project settings
""",
            obj=settings,
            hint="""
            In order to receive notifications when new videos are
            created, define system admins in your settings, like:

            ADMINS = (
                ("Admin", "administrator@example.com"),
            )
""",
            id="viral_videos.W001"))

    return errors 
Example 11
Project: Django-3-Web-Development-Cookbook-Fourth-Edition   Author: PacktPublishing   File: checks.py    License: MIT License 6 votes vote down vote up
def settings_check(app_configs, **kwargs):
    from django.conf import settings

    errors = []

    if not settings.ADMINS:
        errors.append(
            Warning(
                dedent("""
                    The system admins are not set in the project settings
                """),
                obj=settings,
                hint=dedent("""
                    In order to receive notifications when new videos are
                    created, define system admins in your settings, like:
        
                    ADMINS = (
                        ("Admin", "administrator@example.com"),
                    )
                """),
                id="viral_videos.W001",
            )
        )

    return errors 
Example 12
Project: Servo   Author: fpsw   File: error.py    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
def report(request):
    crashed = True
    if request.method == 'POST':
        form = ErrorForm(request.POST)
        if form.is_valid():
            ref = 'Error %s' % from_time()
            recipient = settings.ADMINS[0][1]
            send_mail(ref, form.cleaned_data['description'], request.user.email, [recipient])
            crashed = False
    else:
        initial = _('Browser: %s') % request.META['HTTP_USER_AGENT']
        form = ErrorForm(initial={'description': initial})

    return render(request, 'error.html', locals()) 
Example 13
Project: GTDWeb   Author: lanbing510   File: __init__.py    License: GNU General Public License v2.0 5 votes vote down vote up
def mail_admins(subject, message, fail_silently=False, connection=None,
                html_message=None):
    """Sends a message to the admins, as defined by the ADMINS setting."""
    if not settings.ADMINS:
        return
    mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
                message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS],
                connection=connection)
    if html_message:
        mail.attach_alternative(html_message, 'text/html')
    mail.send(fail_silently=fail_silently) 
Example 14
Project: django-sitemessage   Author: idlesign   File: toolbox.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def check_undelivered(to: Optional[str] = None) -> int:
    """Sends a notification email if any undelivered dispatches.

    Returns undelivered (failed) dispatches count.

    :param to: Recipient address. If not set Django ADMINS setting is used.

    """
    failed_count = Dispatch.objects.filter(dispatch_status=Dispatch.DISPATCH_STATUS_FAILED).count()

    if failed_count:
        from sitemessage.shortcuts import schedule_email
        from sitemessage.messages.email import EmailTextMessage

        if to is None:
            admins = settings.ADMINS

            if admins:
                to = list(dict(admins).values())

        if to:
            priority = 999

            register_message_types(EmailTextMessage)

            schedule_email(
                _('You have %(count)s undelivered dispatch(es) at %(url)s') % {
                    'count': failed_count,
                    'url': get_site_url(),
                },
                subject=_('[SITEMESSAGE] Undelivered dispatches'),
                to=to, priority=priority)

            send_scheduled_messages(priority=priority)

    return failed_count 
Example 15
Project: pasportaservo   Author: tejoesperanto   File: views.py    License: GNU Affero General Public License v3.0 5 votes vote down vote up
def get(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            # Only anonymous (non-authenticated) users are expected to access this page.
            return HttpResponseRedirect(self.get_authenticated_redirect_url())
        request_id = request.session.pop('restore_request_id', None)
        if request_id is None or not isinstance(request_id[1], float):
            # When the restore request ID is missing or invalid, just show the login page.
            return HttpResponseRedirect(reverse_lazy('login'))
        if datetime.now() - datetime.fromtimestamp(request_id[1]) > timedelta(hours=1):
            # When the restore request ID is expired (older than 1 hour), redirect to the login page.
            # This is to prevent abuse, when the user leaves their browser or device open and
            # a different person attempts to (mis)use the restoration request functionality...
            messages.warning(self.request, _("Something misfunctioned. Please log in again and retry."))
            return HttpResponseRedirect(reverse_lazy('login'))
        # Otherwise, send mail to admins.
        send_mail(
            '{prefix}{subject}'.format(
                prefix=settings.EMAIL_SUBJECT_PREFIX,
                subject=gettext(
                    # xgettext:python-brace-format
                    "Note to admin: User requests to reactivate their account; ref: {}."
                ).format(request_id[0])),
            "--",
            None,
            ['{} <{}>'.format(nick, addr) for nick, addr in settings.ADMINS],
            fail_silently=False)
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context) 
Example 16
Project: opencraft   Author: open-craft   File: utilities.py    License: GNU Affero General Public License v3.0 5 votes vote down vote up
def _mail_admins_with_attachment(
            subject,
            message,
            fail_silently=True,
            connection=None,
            html_message=None,
            attachments=None,
            extra_recipients: Optional[List[str]] = None,
    ):
        """
        Mimics mail_admins, but allows attaching files to the message
        """
        if not settings.ADMINS and not extra_recipients:
            return

        recipients = [a[1] for a in settings.ADMINS] + extra_recipients
        mail = EmailMultiAlternatives(
            "%s%s" % (settings.EMAIL_SUBJECT_PREFIX, subject),
            message, settings.SERVER_EMAIL, recipients,
            connection=connection
        )

        if html_message:
            mail.attach_alternative(html_message, "text/html")

        if attachments:
            for attachment_name, attachment_content, attachment_mime in attachments:
                mail.attach(attachment_name, attachment_content, attachment_mime)

        mail.send(fail_silently=fail_silently)


# Functions ##################################################################### 
Example 17
Project: opencraft   Author: open-craft   File: test_openedx_appserver.py    License: GNU Affero General Public License v3.0 5 votes vote down vote up
def test_provision_failed_email(self, mock_consul):
        """
        Tests that provision_failed sends email when called from normal program flow
        """
        additional_monitoring_emails = ['additionalmonitoring@localhost']
        failure_emails = ['provisionfailed@localhost']

        appserver = make_test_appserver()
        appserver.instance.additional_monitoring_emails = additional_monitoring_emails
        appserver.instance.provisioning_failure_notification_emails = failure_emails
        reason = "something went wrong"
        log_lines = ["log line1", "log_line2"]

        appserver.provision_failed_email(reason, log_lines)

        expected_subject = OpenEdXAppServer.EmailSubject.PROVISION_FAILED.format(
            name=appserver.name, instance_name=appserver.instance.name,
        )
        # failure_emails isn't included here because they get a different type of email (an urgent one)
        expected_recipients = [admin_tuple[1] for admin_tuple in settings.ADMINS]

        self.assertEqual(len(django_mail.outbox), 1)
        mail = django_mail.outbox[0]

        self.assertIn(expected_subject, mail.subject)
        self.assertIn(appserver.name, mail.body)
        self.assertIn(appserver.instance.name, mail.body)
        self.assertIn(reason, mail.body)
        self.assertEqual(mail.from_email, settings.SERVER_EMAIL)
        self.assertEqual(mail.to, expected_recipients)

        self.assertEqual(len(mail.attachments), 1)
        self.assertEqual(mail.attachments[0], ("provision.log", "\n".join(log_lines), "text/plain")) 
Example 18
Project: opencraft   Author: open-craft   File: test_openedx_appserver.py    License: GNU Affero General Public License v3.0 5 votes vote down vote up
def test_provision_failed_exception_email(self, mock_consul):
        """
        Tests that provision_failed sends email when called from exception handler
        """
        appserver = make_test_appserver()
        reason = "something went wrong"
        log_lines = ["log line1", "log_line2"]

        exception_message = "Something Bad happened Unexpectedly"
        exception = Exception(exception_message)
        try:
            raise exception
        except Exception:  # pylint: disable=broad-except
            appserver.provision_failed_email(reason, log_lines)

        expected_subject = OpenEdXAppServer.EmailSubject.PROVISION_FAILED.format(
            name=appserver.name, instance_name=appserver.instance.name,
        )
        expected_recipients = [admin_tuple[1] for admin_tuple in settings.ADMINS]

        self.assertEqual(len(django_mail.outbox), 1)
        mail = django_mail.outbox[0]

        self.assertIn(expected_subject, mail.subject)
        self.assertIn(appserver.name, mail.body)
        self.assertIn(appserver.instance.name, mail.body)
        self.assertIn(reason, mail.body)
        self.assertEqual(mail.from_email, settings.SERVER_EMAIL)
        self.assertEqual(mail.to, expected_recipients)

        self.assertEqual(len(mail.attachments), 2)
        self.assertEqual(mail.attachments[0], ("provision.log", "\n".join(log_lines), "text/plain"))
        name, content, mime_type = mail.attachments[1]
        self.assertEqual(name, "debug.html")
        self.assertIn(exception_message, content)
        self.assertEqual(mime_type, "text/html") 
Example 19
Project: django-easy-comment   Author: r26zhao   File: handlers.py    License: MIT License 5 votes vote down vote up
def get_recipient():
    admins = [i[0] for i in settings.ADMINS]
    app_model = settings.AUTH_USER_MODEL.split('.')
    User_model = apps.get_model(*app_model)
    recipient = User_model.objects.filter(username__in=admins)
    return recipient 
Example 20
Project: django-easy-comment   Author: r26zhao   File: handlers.py    License: MIT License 5 votes vote down vote up
def comment_handler(sender, instance, created, **kwargs):
    if created:
        recipient = ADMINS.exclude(id=instance.user.id)
        if instance.parent is not None:
            recipient = recipient.exclude(id=instance.parent.user.id)
            if recipient.count() > 0:
                notify.send(instance.user, recipient=recipient,
                            verb='回复了 %s' % instance.parent.user.username,
                            action_object=instance,
                            target=instance.content_object,
                            description=instance.content)
                if SEND_NOTIFICATION_EMAIL:
                    email_handler(*recipient)
            if not instance.user.username == instance.parent.user.username:
                notify.send(instance.user, recipient=instance.parent.user, verb='@了你',
                            action_object=instance,
                            target=instance.content_object,
                            description=instance.content)
                if SEND_NOTIFICATION_EMAIL:
                    email_handler(instance.parent.user)
        else:
            if recipient.count() > 0:
                notify.send(instance.user, recipient=recipient, verb='发表了评论',
                            action_object=instance,
                            target=instance.content_object,
                            description=instance.content)
                if SEND_NOTIFICATION_EMAIL:
                    email_handler(*recipient) 
Example 21
Project: trunk-player   Author: ScanOC   File: views.py    License: MIT License 5 votes vote down vote up
def form_valid(self, form):
        try:
            update_unit_email = SiteOption.objects.get(name='SEND_ADMIN_EMAIL_ON_UNIT_NAME')
            if update_unit_email.value_boolean_or_string() == True:
                Unit = form.save()
                send_mail(
                  'Unit ID Change',
                  'User {} updated unit ID {} Now {}'.format(self.request.user, Unit.dec_id, Unit.description),
                  settings.SERVER_EMAIL,
                  [ mail for name, mail in settings.ADMINS],
                  fail_silently=False,
                )
        except SiteOption.DoesNotExist:
            pass
        return super().form_valid(form) 
Example 22
Project: intake   Author: codeforamerica   File: alerts.py    License: MIT License 5 votes vote down vote up
def send_email_to_admins(subject, message):
    """Asynchronously sends an email alert to all ADMINs in settings
    """
    tasks.send_email.delay(
        subject=subject, message=message,
        from_email=settings.MAIL_DEFAULT_SENDER,
        recipient_list=[email for name, email in settings.ADMINS]) 
Example 23
Project: luscan-devel   Author: blackye   File: __init__.py    License: GNU General Public License v2.0 5 votes vote down vote up
def mail_admins(subject, message, fail_silently=False, connection=None,
                html_message=None):
    """Sends a message to the admins, as defined by the ADMINS setting."""
    if not settings.ADMINS:
        return
    mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
                message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS],
                connection=connection)
    if html_message:
        mail.attach_alternative(html_message, 'text/html')
    mail.send(fail_silently=fail_silently) 
Example 24
Project: django_blog   Author: r26zhao   File: handlers.py    License: MIT License 5 votes vote down vote up
def get_recipient():
    admins = [i[0] for i in settings.ADMINS]
    app_model = settings.AUTH_USER_MODEL.split('.')
    user_model = apps.get_model(*app_model)
    recipient = user_model.objects.filter(username__in=admins)
    return recipient 
Example 25
Project: django_blog   Author: r26zhao   File: handlers.py    License: MIT License 5 votes vote down vote up
def comment_handler(sender, instance, created, **kwargs):
    if created:
        recipient = ADMINS.exclude(id=instance.user.id)
        if not instance.parent is None:
            recipient = recipient.exclude(id=instance.parent.user.id)
            if recipient.count() > 0:
                notify.send(instance.user, recipient=recipient,
                            verb='回复了 %s' % instance.parent.user_name,
                            action_object=instance,
                            target=instance.post,
                            description=instance.content)
                if SEND_NOTIFICATION_EMAIL:
                    email_handler.delay(user2id(*recipient))
            if not instance.user_name == instance.parent.user_name:
                notify.send(instance.user, recipient=instance.parent.user, verb='@了你',
                            action_object=instance,
                            target=instance.post,
                            description=instance.content)
                if SEND_NOTIFICATION_EMAIL:
                    email_handler.delay(user2id(instance.parent.user))
        else:
            if recipient.count() > 0:
                notify.send(instance.user, recipient=recipient, verb='发表了评论',
                            action_object=instance,
                            target=instance.post,
                            description=instance.content)
                if SEND_NOTIFICATION_EMAIL:
                    email_handler.delay(user2id(*recipient)) 
Example 26
Project: sfm-ui   Author: gwu-libraries   File: utils.py    License: MIT License 5 votes vote down vote up
def get_admin_email_addresses():
    email_addresses = []
    for _, email_address in settings.ADMINS:
        email_addresses.append(email_address)
    return email_addresses 
Example 27
Project: Kiwi   Author: kiwitcms   File: signals.py    License: GNU General Public License v2.0 5 votes vote down vote up
def notify_admins(sender, **kwargs):
    """
        Very simple signal handler which sends emails to site
        admins when a new user has been registered!

        .. warning::

            This handler isn't connected to the ``USER_REGISTERED_SIGNAL`` by default!
    """
    from django.urls import reverse
    from django.conf import settings
    from django.contrib.auth import get_user_model

    from tcms.core.utils.mailto import mailto
    from tcms.core.utils import request_host_link

    if kwargs.get('raw', False):
        return

    admin_emails = set()
    # super-users can approve others
    for super_user in get_user_model().objects.filter(is_superuser=True):
        admin_emails.add(super_user.email)
    # site admins should be able to do so as well
    for _name, email in settings.ADMINS:
        admin_emails.add(email)

    request = kwargs.get('request')
    user = kwargs.get('user')
    user_url = request_host_link(request) + reverse('admin:auth_user_change', args=[user.pk])

    mailto(
        template_name='email/user_registered/notify_admins.txt',
        recipients=list(admin_emails),
        subject=str(_('New user awaiting approval')),
        context={
            'username': user.username,
            'user_url': user_url,
        }
    ) 
Example 28
Project: Kiwi   Author: kiwitcms   File: tests.py    License: GNU General Public License v2.0 5 votes vote down vote up
def test_register_user_and_activate_by_admin(self):
        response, _user = self.assert_user_registration('plan-tester', follow=True)

        self.assertContains(
            response,
            _('Your account has been created, but you need an administrator to activate it'))

        for (name, email) in settings.ADMINS:
            self.assertContains(response,
                                '<a href="mailto:{}">{}</a>'.format(email, name),
                                html=True) 
Example 29
Project: Kiwi   Author: kiwitcms   File: views.py    License: GNU General Public License v2.0 5 votes vote down vote up
def show_messages_with_site_admins_emails_as_links(request):
        """ Show messages with site admins emails as links. """
        for name, email in settings.ADMINS:
            mailto = '<a href="mailto:{}">{}</a>'.format(email, name)
            messages.add_message(request, messages.WARNING, mailto) 
Example 30
Project: Kiwi   Author: kiwitcms   File: mailto.py    License: GNU General Public License v2.0 5 votes vote down vote up
def mailto(template_name, subject, recipients=None,  # pylint: disable=invalid-name
           context=None, cc=None):

    # make a list with recipients and filter out duplicates
    if isinstance(recipients, list):
        recipients = list(set(recipients))
    else:
        recipients = [recipients]

    # extend with the CC list
    if cc:
        recipients.extend(cc)

    # if debugging then send to ADMINS as well
    if settings.DEBUG:
        for _, admin_email in settings.ADMINS:
            recipients.append(admin_email)

    # this is a workaround to allow passing body text directly
    if template_name:
        body = render_to_string(template_name, context)
    else:
        body = context

    sender = settings.DEFAULT_FROM_EMAIL
    email_thread = threading.Thread(
        target=send_mail,
        args=(settings.EMAIL_SUBJECT_PREFIX + subject, body, sender, recipients),
        kwargs={'fail_silently': False}
    )
    # This is to tell Python not to wait for the thread to return
    email_thread.setDaemon(True)
    email_thread.start()