コード例 #1
0
    def test_connection_kwargs_overrides_settings(self):
        connection = get_connection('anymail.backends.mailgun.MailgunBackend')
        self.assertEqual(connection.api_key, 'api_key_from_settings')

        connection = get_connection('anymail.backends.mailgun.MailgunBackend',
                                    api_key='api_key_from_kwargs')
        self.assertEqual(connection.api_key, 'api_key_from_kwargs')
コード例 #2
0
ファイル: tests.py プロジェクト: 6ft/django
    def test_file_sessions(self):
        """Make sure opening a connection creates a new file"""
        msg = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], headers={'From': '*****@*****.**'})
        connection = mail.get_connection()
        connection.send_messages([msg])

        self.assertEqual(len(os.listdir(self.tmp_dir)), 1)
        with open(os.path.join(self.tmp_dir, os.listdir(self.tmp_dir)[0]), 'rb') as fp:
            message = message_from_binary_file(fp)
        self.assertEqual(message.get_content_type(), 'text/plain')
        self.assertEqual(message.get('subject'), 'Subject')
        self.assertEqual(message.get('from'), '*****@*****.**')
        self.assertEqual(message.get('to'), '*****@*****.**')

        connection2 = mail.get_connection()
        connection2.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        connection.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        msg.connection = mail.get_connection()
        self.assertTrue(connection.open())
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)

        connection.close()
コード例 #3
0
ファイル: tests.py プロジェクト: jdunck/django-old
    def test_file_sessions(self):
        """Make sure opening a connection creates a new file"""
        msg = EmailMessage(
            "Subject", "Content", "*****@*****.**", ["*****@*****.**"], headers={"From": "*****@*****.**"}
        )
        connection = mail.get_connection()
        connection.send_messages([msg])

        self.assertEqual(len(os.listdir(self.tmp_dir)), 1)
        message = email.message_from_file(open(os.path.join(self.tmp_dir, os.listdir(self.tmp_dir)[0])))
        self.assertEqual(message.get_content_type(), "text/plain")
        self.assertEqual(message.get("subject"), "Subject")
        self.assertEqual(message.get("from"), "*****@*****.**")
        self.assertEqual(message.get("to"), "*****@*****.**")

        connection2 = mail.get_connection()
        connection2.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        connection.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        msg.connection = mail.get_connection()
        self.assertTrue(connection.open())
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)
コード例 #4
0
ファイル: send_email.py プロジェクト: grnet/heallink
 def send_email(self, args, options):
     if options['file_back_end']:
         backend = get_connection(FILEBASED_BACKEND,
                                  file_path=options['file_back_end'])
     elif options['console_back_end']:
         backend = get_connection(CONSOLE_BACKEND)
     else:
         backend = get_connection(SMTP_BACKEND)
     
     passwords = defaultdict(lambda: '')
     if os.path.isfile(options['passwords_file']):
         with open(options['passwords_file'], 'r') as passwords_file:
             p_reader = csv.reader(passwords_file)
             for row in p_reader:
                 passwords[row[-2]] = row[-1]
     message_template = None
     if os.path.isfile(options['message_file']):
         with open(options['message_file'], 'r') as message_file:
             message_template = Template(message_file.read().decode('utf-8'))
     if options['all']:
         users = User.objects.all()
     elif options['input_file']:
         with open(options['input_file'], 'r') as usernames_file:
             usernames = [x.rstrip() for x in usernames_file.readlines()]
             users = User.objects.filter(username__in=usernames)
     else:
         users = User.objects.filter(username__in=args)
     for user in users:
         message = self.make_invite(user,
                                    {'password': passwords[user.username]},
                                    message_template)
         send_mail(options['subject'], message,
                   options['from'],
                   [user.email], fail_silently=False,
                   connection=backend)
コード例 #5
0
ファイル: tests.py プロジェクト: jdunck/django-old
    def test_connection_arg(self):
        """Test connection argument to send_mail(), et. al."""
        mail.outbox = []

        # Send using non-default connection
        connection = mail.get_connection("regressiontests.mail.custombackend.EmailBackend")
        send_mail("Subject", "Content", "*****@*****.**", ["*****@*****.**"], connection=connection)
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 1)
        self.assertEqual(connection.test_outbox[0].subject, "Subject")

        connection = mail.get_connection("regressiontests.mail.custombackend.EmailBackend")
        send_mass_mail(
            [
                ("Subject1", "Content1", "*****@*****.**", ["*****@*****.**"]),
                ("Subject2", "Content2", "*****@*****.**", ["*****@*****.**"]),
            ],
            connection=connection,
        )
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 2)
        self.assertEqual(connection.test_outbox[0].subject, "Subject1")
        self.assertEqual(connection.test_outbox[1].subject, "Subject2")

        connection = mail.get_connection("regressiontests.mail.custombackend.EmailBackend")
        mail_admins("Admin message", "Content", connection=connection)
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 1)
        self.assertEqual(connection.test_outbox[0].subject, "[Django] Admin message")

        connection = mail.get_connection("regressiontests.mail.custombackend.EmailBackend")
        mail_managers("Manager message", "Content", connection=connection)
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 1)
        self.assertEqual(connection.test_outbox[0].subject, "[Django] Manager message")
コード例 #6
0
    def test_connection_kwargs_overrides_settings(self):
        """Can override settings file in get_connection"""
        backend = get_connection()
        self.assertEqual(backend.sample_setting, 'setting_from_settings')

        backend = get_connection(sample_setting='setting_from_kwargs')
        self.assertEqual(backend.sample_setting, 'setting_from_kwargs')
コード例 #7
0
ファイル: email.py プロジェクト: xkmato/casepro
def send_raw_email(recipients, subject, text, html):
    """
    Sends and multi-part (text and optionally HTML) email to a list of users or email addresses
    """
    to_addresses = []
    for recipient in recipients:
        if isinstance(recipient, User):
            to_addresses.append(recipient.email)
        elif isinstance(recipient, six.string_types):
            to_addresses.append(recipient)
        else:  # pragma: no cover
            raise ValueError("Email recipients must users or email addresses")

    from_address = getattr(settings, 'DEFAULT_FROM_EMAIL', '*****@*****.**')

    if getattr(settings, 'SEND_EMAILS', False):
        # send individual messages so as to not leak users email addresses, but use bulk send operation for speed
        messages = []
        for to_address in to_addresses:
            message = EmailMultiAlternatives(subject, text, from_email=from_address, to=[to_address])
            if html:
                message.attach_alternative(html, "text/html")
            messages.append(message)

        get_connection().send_messages(messages)
    else:  # pragma: no cover
        print("FAKE SENDING this email to %s:" % ", ".join(to_addresses))
        print("--------------------------------------- text -----------------------------------------")
        print(text)
        if html:
            print("--------------------------------------- html -----------------------------------------")
            print(html)
コード例 #8
0
ファイル: tests.py プロジェクト: BioDesignRealWorld/django
    def test_email_msg_uses_crlf(self):
        """#23063 -- Test that RFC-compliant messages are sent over SMTP."""
        send = SMTP.send
        try:
            smtp_messages = []

            def mock_send(self, s):
                smtp_messages.append(s)
                return send(self, s)

            SMTP.send = mock_send

            email = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'])
            mail.get_connection().send_messages([email])

            # Find the actual message
            msg = None
            for i, m in enumerate(smtp_messages):
                if m[:4] == 'data':
                    msg = smtp_messages[i + 1]
                    break

            self.assertTrue(msg)

            if PY3:
                msg = msg.decode('utf-8')
            # Ensure that the message only contains CRLF and not combinations of CRLF, LF, and CR.
            msg = msg.replace('\r\n', '')
            self.assertNotIn('\r', msg)
            self.assertNotIn('\n', msg)

        finally:
            SMTP.send = send
コード例 #9
0
ファイル: models.py プロジェクト: caads/feitec
    def save(self, *args, **kwargs):
        super(Projeto, self).save(*args, **kwargs)
    ## ENVIA 1 EMAIL SOMENTE SE FOI APROVADO O CADASTRO ##
        if self.situacao == 'Aprovado' and self.enviar == 'Enviar':
           enviar = User.objects.get(username__iexact=self.criador)
           subject = 'Projeto Feitec'
           message = 'O projeto %s foi será no \nBloco: %s \nSala: %s' %(self.nomeProj,self.blocoProj,self.salaProj)
           from_email = ''#email remetente
           connection = get_connection(username = '', password ='')#email e senha de conexão
           send_email = EmailMessage(subject, message , from_email, [enviar.email], connection = connection)
           send_email.content_subtype = "html"
           send_email.send()


        if (self.situacao == 'Aprovado' or self.situacao == 'Reprovado') and self.enviar == 'Pendente':
            enviar = User.objects.get(username__iexact=self.criador)
            subject = 'Projeto Feitec'
            message = 'O projeto %s foi %s!' %(self.nomeProj,self.situacao)
            from_email = ''#email remetente
            connection = get_connection(username = '', password ='')#email e senha de conexão
            send_email = EmailMessage(subject, message , from_email, [enviar.email], connection = connection)
            send_email.content_subtype = "html"
            send_email.send()

        if self.situacao == 'Enviado':
            enviar = User.objects.get(username__iexact=self.criador)
            subject = 'Projeto Feitec'
            message = 'O projeto %s foi enviado com sucesso.  Aguarde a avaliação do próprio' %(self.nomeProj)
            from_email = ''#email remetente
            connection = get_connection(username = '', password ='')#email e senha de conexão
            send_email = EmailMessage(subject, message , from_email, [enviar.email], connection = connection)
            send_email.content_subtype = "html"
            send_email.send()
コード例 #10
0
ファイル: tests.py プロジェクト: 6ft/django
    def test_connection_arg(self):
        """Test connection argument to send_mail(), et. al."""
        mail.outbox = []

        # Send using non-default connection
        connection = mail.get_connection('mail.custombackend.EmailBackend')
        send_mail('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], connection=connection)
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 1)
        self.assertEqual(connection.test_outbox[0].subject, 'Subject')

        connection = mail.get_connection('mail.custombackend.EmailBackend')
        send_mass_mail([
            ('Subject1', 'Content1', '*****@*****.**', ['*****@*****.**']),
            ('Subject2', 'Content2', '*****@*****.**', ['*****@*****.**']),
        ], connection=connection)
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 2)
        self.assertEqual(connection.test_outbox[0].subject, 'Subject1')
        self.assertEqual(connection.test_outbox[1].subject, 'Subject2')

        connection = mail.get_connection('mail.custombackend.EmailBackend')
        mail_admins('Admin message', 'Content', connection=connection)
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 1)
        self.assertEqual(connection.test_outbox[0].subject, '[Django] Admin message')

        connection = mail.get_connection('mail.custombackend.EmailBackend')
        mail_managers('Manager message', 'Content', connection=connection)
        self.assertEqual(mail.outbox, [])
        self.assertEqual(len(connection.test_outbox), 1)
        self.assertEqual(connection.test_outbox[0].subject, '[Django] Manager message')
コード例 #11
0
 def test_missing_api_key(self):
     with self.assertRaises(AnymailConfigurationError) as cm:
         mail.get_connection()  # this init's SparkPost without actually trying to send anything
     errmsg = str(cm.exception)
     # Make sure the error mentions the different places to set the key
     self.assertRegex(errmsg, r'\bSPARKPOST_API_KEY\b')
     self.assertRegex(errmsg, r'\bANYMAIL_SPARKPOST_API_KEY\b')
コード例 #12
0
ファイル: tests.py プロジェクト: MaxPresman/django
 def test_message_cc_header(self):
     """
     Regression test for #7722
     """
     email = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], cc=['*****@*****.**'])
     mail.get_connection().send_messages([email])
     message = self.get_the_message()
     self.assertStartsWith(message.as_string(), b'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: [email protected]\nTo: [email protected]\nCc: [email protected]\nDate: ')
コード例 #13
0
 def test_missing_setting(self):
     """Settings without defaults must be provided"""
     with self.assertRaises(AnymailConfigurationError) as cm:
         get_connection()
     self.assertIsInstance(cm.exception, ImproperlyConfigured)  # Django consistency
     errmsg = str(cm.exception)
     self.assertRegex(errmsg, r'\bTEST_SAMPLE_SETTING\b')
     self.assertRegex(errmsg, r'\bANYMAIL_TEST_SAMPLE_SETTING\b')
コード例 #14
0
ファイル: engine.py プロジェクト: SkAZi/django-mailer-2
def send_all(block_size=500, backend=None):
    """
    Send all non-deferred messages in the queue.

    A lock file is used to ensure that this process can not be started again
    while it is already running.

    The ``block_size`` argument allows for queued messages to be iterated in
    blocks, allowing new prioritised messages to be inserted during iteration
    of a large number of queued messages.

    """
    lock = FileLock(LOCK_PATH)

    logger.debug("Acquiring lock...")
    try:
        # lockfile has a bug dealing with a negative LOCK_WAIT_TIMEOUT (which
        # is the default if it's not provided) systems which use a LinkFileLock
        # so ensure that it is never a negative number.
        lock.acquire(settings.LOCK_WAIT_TIMEOUT or 0)
        #lock.acquire(settings.LOCK_WAIT_TIMEOUT)
    except AlreadyLocked:
        logger.debug("Lock already in place. Exiting.")
        return
    except LockTimeout:
        logger.debug("Waiting for the lock timed out. Exiting.")
        return
    logger.debug("Lock acquired.")

    start_time = time.time()

    sent = deferred = skipped = 0

    try:
        if constants.EMAIL_BACKEND_SUPPORT:
            connection = get_connection(backend=backend)
        else:
            connection = get_connection()
        blacklist = models.Blacklist.objects.values_list('email', flat=True)
        connection.open()
        for message in _message_queue(block_size):
            try:
                result = send_queued_message(message, smtp_connection=connection,
                                  blacklist=blacklist)
            except Exception, e:
                result = constants.RESULT_FAILED
                logger.error(e)
            
            if result == constants.RESULT_SENT:
                sent += 1
            elif result == constants.RESULT_FAILED:
                deferred += 1
            elif result == constants.RESULT_SKIPPED:
                skipped += 1
        connection.close()
コード例 #15
0
    def test_username_password_kwargs_overrides(self):
        # Additional checks for username and password, which are special-cased
        # because of Django core mail function defaults.
        connection = get_connection('anymail.backends.sendgrid.SendGridBackend')
        self.assertEqual(connection.username, 'username_from_settings')
        self.assertEqual(connection.password, 'password_from_settings')

        connection = get_connection('anymail.backends.sendgrid.SendGridBackend',
                                    username='******', password='******')
        self.assertEqual(connection.username, 'username_from_kwargs')
        self.assertEqual(connection.password, 'password_from_kwargs')
コード例 #16
0
ファイル: engine.py プロジェクト: mbroten/django-mailer-2
def send_all(block_size=500, backend=None):
    """
    Send all non-deferred messages in the queue.

    A lock file is used to ensure that this process can not be started again
    while it is already running.

    The ``block_size`` argument allows for queued messages to be iterated in
    blocks, allowing new prioritised messages to be inserted during iteration
    of a large number of queued messages.

    """
    logger.debug("Acquiring lock...")
    try:
        lock = LockFile(LOCK_PATH)
    except LockError:
        logger.debug("Lock already in place. Exiting.")
        return
    logger.debug("Lock acquired.")

    start_time = time.time()

    sent = deferred = skipped = 0

    try:
        if constants.EMAIL_BACKEND_SUPPORT:
            connection = get_connection(backend=backend)
        else:
            connection = get_connection()
        blacklist = models.Blacklist.objects.values_list('email', flat=True)
        connection.open()
        for message in _message_queue(block_size):
            result = send_queued_message(message, smtp_connection=connection,
                                  blacklist=blacklist)
            if result == constants.RESULT_SENT:
                sent += 1
            elif result == constants.RESULT_FAILED:
                deferred += 1
            elif result == constants.RESULT_SKIPPED:
                skipped += 1
        connection.close()
    finally:
        logger.debug("Releasing lock...")
        lock.close()
        logger.debug("Lock released.")

    logger.debug("")
    if sent or deferred or skipped:
        log = logger.warning
    else:
        log = logger.info
    log("%s sent, %s deferred, %s skipped." % (sent, deferred, skipped))
    logger.debug("Completed in %.2f seconds." % (time.time() - start_time))
コード例 #17
0
    def test_username_password_kwargs_overrides(self):
        """Overrides for 'username' and 'password' should work like other overrides"""
        # These are special-cased because of default args in Django core mail functions.
        # (Use the SendGrid v2 backend, which has settings named 'username' and 'password'.)
        backend = get_connection('anymail.backends.sendgrid_v2.EmailBackend')
        self.assertEqual(backend.username, 'username_from_settings')
        self.assertEqual(backend.password, 'password_from_settings')

        backend = get_connection('anymail.backends.sendgrid_v2.EmailBackend',
                                 username='******', password='******')
        self.assertEqual(backend.username, 'username_from_kwargs')
        self.assertEqual(backend.password, 'password_from_kwargs')
コード例 #18
0
ファイル: utils.py プロジェクト: czlee/tabbycat
def send_mail_to_adjs(round):
    tournament = round.tournament
    draw = round.debate_set_with_prefetches(speakers=False, divisions=False).all()
    use_codes = use_team_code_names(tournament, False)

    subject = Template(tournament.pref('adj_email_subject_line'))
    body = Template(tournament.pref('adj_email_message'))
    messages = []

    adj_position_names = {
        AdjudicatorAllocation.POSITION_CHAIR: _("the chair"),
        AdjudicatorAllocation.POSITION_ONLY: _("the only"),
        AdjudicatorAllocation.POSITION_PANELLIST: _("a panellist"),
        AdjudicatorAllocation.POSITION_TRAINEE: _("a trainee"),
    }

    def _assemble_panel(adjs):
        adj_string = []
        for adj, pos in adjs:
            adj_string.append("%s (%s)" % (adj.name, adj_position_names[pos]))

        return ", ".join(adj_string)

    for debate in draw:
        matchup = debate.matchup_codes if use_codes else debate.matchup
        context = {
            'ROUND': round.name,
            'VENUE': debate.venue.display_name if debate.venue is not None else _("TBA"),
            'PANEL': _assemble_panel(debate.adjudicators.with_positions()),
            'DRAW': matchup
        }

        for adj, pos in debate.adjudicators.with_positions():
            if adj.email is None:
                continue

            context_user = context.copy()
            context_user['USER'] = adj.name
            context_user['POSITION'] = adj_position_names[pos]

            messages.append(TournamentEmailMessage(subject, body, tournament, round, SentMessageRecord.EVENT_TYPE_DRAW, adj, context_user))

    try:
        get_connection().send_messages(messages)
    except SMTPException:
        logger.exception("Failed to send adjudicator e-mails")
        raise
    except ConnectionError:
        logger.exception("Connection error sending adjudicator e-mails")
        raise
    else:
        SentMessageRecord.objects.bulk_create([message.as_sent_record() for message in messages])
コード例 #19
0
ファイル: mail.py プロジェクト: busla/safetyvalve
 def send(self, retries=0):
     if self.to == []:
         logging.warn('No recipients set for email "%s"' % self.subject)
     global connection
     if connection is None:
         connection = mail.get_connection()  # Use default email connection
     try:
         connection.send_messages([self])
     except smtplib.SMTPServerDisconnected as e:
         if retries == connect_retires_max:
             raise e
         connection = mail.get_connection()  # Use default email connection
         self.send(retries + 1)
コード例 #20
0
def daily_update(experiment, debug=False, round_data=None, **kwargs):
    """
    Triggered by round_ended_handler in experiment/lighterprints/signals.py, uses experiment.current_round_data if not
    explicitly set which assumes that the experiment has *not* advanced to the next round yet.
    """
    all_messages = None
    with transaction.atomic():
        round_data = experiment.current_round_data if round_data is None else round_data
        logger.debug("sending summary emails to %s for round %s", experiment, round_data)
        group_scores = GroupScores(experiment, round_data=round_data, groups=list(experiment.groups))
        all_messages = list(group_scores.generate_daily_update_messages())
    if not debug and all_messages:
        logger.debug("sending %s generated emails for lighter footprints", len(all_messages))
        mail.get_connection().send_messages(all_messages)
コード例 #21
0
ファイル: utils.py プロジェクト: NorthStar/moocng
def send_mass_mail_wrapper(subject, message, recipients, html_content=False):
    mails = []
    content = message
    if html_content:
        content = ""
    for to in recipients:
        email = EmailMultiAlternatives(subject, content, settings.DEFAULT_FROM_EMAIL, [to])
        if html_content:
            email.attach_alternative(message, "text/html")
        mails.append(email)
    try:
        get_connection().send_messages(mails)
    except IOError as ex:
        logger.error('The massive email "%s" to %s could not be sent because of %s' % (subject, recipients, str(ex)))
コード例 #22
0
ファイル: tasks.py プロジェクト: waylybaye/weil
def send_message(message_id):
    message = Message.objects.get(id=message_id)
    if not message:
        return

    msg = EmailMultiAlternatives(
        subject=message.subject,
        body=message.content,
        from_email=message.sender,
        to=message.to,
    )

    if message.html_content:
        msg.attach_alternative(message.html_content, "text/html")

    mailbox = message.mailbox

    if mailbox.type == MailBoxType.SMTP:
        backend = "django.core.mail.backends.smtp.EmailBackend"
        connection = get_connection(
            backend=backend,
            host=mailbox.smtp_host,
            port=int(mailbox.smtp_port),
            username=mailbox.smtp_username,
            password=mailbox.smtp_password,
            use_tls=mailbox.smtp_use_tls
        )
    elif mailbox.type == MailBoxType.SES:
        backend = "django_ses.SESBackend"
        extra = {}
        if mailbox.enable_dkim and mailbox.dkim_key:
            extra['dkim_domain'] = str(mailbox.domain)
            extra['dkim_key'] = str(mailbox.dkim_key.replace('\r', ''))

        connection = get_connection(
            backend,
            aws_access_key=mailbox.aws_access_key,
            aws_secret_key=mailbox.aws_access_secret_key, **extra)

    else:
        return

    msg.connection = connection

    msg.send(fail_silently=False)

    message.is_sent = True
    message.sent_at = datetime.now()
    message.save()
コード例 #23
0
ファイル: tests.py プロジェクト: 6ft/django
 def test_custom_backend(self):
     """Test custom backend defined in this suite."""
     conn = mail.get_connection('mail.custombackend.EmailBackend')
     self.assertTrue(hasattr(conn, 'test_outbox'))
     email = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], headers={'From': '*****@*****.**'})
     conn.send_messages([email])
     self.assertEqual(len(conn.test_outbox), 1)
コード例 #24
0
ファイル: tests.py プロジェクト: 6ft/django
 def test_send_unicode(self):
     email = EmailMessage('Chère maman', 'Je t\'aime très fort', '*****@*****.**', ['*****@*****.**'])
     num_sent = mail.get_connection().send_messages([email])
     self.assertEqual(num_sent, 1)
     message = self.get_the_message()
     self.assertEqual(message["subject"], '=?utf-8?q?Ch=C3=A8re_maman?=')
     self.assertEqual(force_text(message.get_payload(decode=True)), 'Je t\'aime très fort')
コード例 #25
0
ファイル: models.py プロジェクト: thingdeux/sccs_construction
def sendMailToContacts(name, html, text):
    # Get a list of all of the current contactees
    contacts = ContactEmail.objects.all()
    email_addresses = []
    # Build E-Mail
    subject = str(name) + " has requested a Quote on SCCS"
    text_message = text
    html_message = html
    from_addr = "*****@*****.**"

    # Create List of e-mail addresses
    for address in contacts:
        email_addresses.append(address.email)

    try:
        # Get django e-mail settings
        connection = mail.get_connection()
        # Open E-Mail server connection
        connection.open()
        # Append RAW Text
        email_message = EmailMultiAlternatives(subject, text_message,
                                               from_addr, email_addresses,
                                               connection=connection)
        # Append HTML
        email_message.attach_alternative(html_message, "text/html")
        # Send Message
        email_message.send()

        connection.close()
    except Exception as err:
        connection.close()
        log(err)
コード例 #26
0
ファイル: tests.py プロジェクト: 6ft/django
 def test_message_cc_header(self):
     """
     Regression test for #7722
     """
     email = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], cc=['*****@*****.**'])
     mail.get_connection().send_messages([email])
     message = self.get_the_message()
     self.assertMessageHasHeaders(message, {
         ('MIME-Version', '1.0'),
         ('Content-Type', 'text/plain; charset="utf-8"'),
         ('Content-Transfer-Encoding', '7bit'),
         ('Subject', 'Subject'),
         ('From', '*****@*****.**'),
         ('To', '*****@*****.**'),
         ('Cc', '*****@*****.**')})
     self.assertIn('\nDate: ', message.as_string())
コード例 #27
0
ファイル: tests.py プロジェクト: 6ft/django
 def test_arbitrary_keyword(self):
     """
     Make sure that get_connection() accepts arbitrary keyword that might be
     used with custom backends.
     """
     c = mail.get_connection(fail_silently=True, foo='bar')
     self.assertTrue(c.fail_silently)
コード例 #28
0
ファイル: admin.py プロジェクト: koirikivi/fi.pycon.org
    def send_bill(self, request, queryset):
        for registration in queryset:
            if registration.billed:
                self.message_user(
                    request,
                    'Some of the selected registrations have '
                    'already been billed'
                )
                return

            if not registration.bill_text:
                self.message_user(
                    request,
                    'Some of the selected registration do not have bill text')
                return

        smtp_connection = get_connection()

        for registration in queryset:
            registration.bill_date = date.today()
            self.send_message(
                smtp_connection,
                'Invoice for PyCon Finland %s' % settings.YEAR,
                registration.bill_text,
                registration,
            )
            registration.billed = True
            registration.save()
コード例 #29
0
ファイル: admin.py プロジェクト: koirikivi/fi.pycon.org
    def send_payment_notification(self, request, queryset):
        for registration in queryset:
            if not registration.billed:
                self.message_user(
                    request,
                    'Some of the selected registrations '
                    'have not been billed yet'
                )
                return

            if registration.paid:
                self.message_user(
                    request,
                    'Some of the selected registrations '
                    'have paid'
                )

        smtp_connection = get_connection()

        for registration in queryset:
            self.send_message(
                smtp_connection,
                'Payment notification for PyCon Finland %s' % settings.YEAR,
                registration.notify_text,
                registration,
            )
            registration.notified_date = date.today()
            registration.save()
コード例 #30
0
ファイル: mailer.py プロジェクト: lambdamusic/testproject
def genericEmailAnnouncement(subject = "", body="", sender="", distribution_list=None, ):
	"""	
	provides a bunch of default values for testing purposes
	==> sends a test email to myself
	
	"""

	if not subject:
		subject = "See what's new with LiquidQuotes.com"
	
	if not body:
		body = 'Here is another message'
		
	if not sender:
		sender = "Liquid Quotes <*****@*****.**>"
		
	if not distribution_list:
		distribution_list = ['*****@*****.**']


	connection = mail.get_connection()
	connection.open()
	
	for emailAddress in distribution_list:

		print >> sys.stderr, "Emailing %s" % emailAddress

		try:	
			email1 = mail.EmailMessage(subject, body, sender, 		                          [emailAddress], connection=connection)
			email1.send()
		except:
			print "Error with %s" % emailAddress
コード例 #31
0
def send_mosaico_email(
    code,
    subject,
    from_email,
    recipients,
    recipient_type="to",
    bindings=None,
    connection=None,
    backend=None,
    fail_silently=False,
    preferences_link=True,
    reply_to=None,
    attachments=None,
):
    """Send an email from a Mosaico template

    :param code: the code identifying the Mosaico template
    :param subject: the subject line of the email
    :param from_email: the address from which the email is to be sent
    :param recipients: a list of recipients to which the email will be send; alternatively, a single address
    :param bindings: a dictionary of replacements variables and their target values in the Mosaico template
    :param connection: an optional email server connection to use to send the emails
    :param backend: if no connection is given, an optional mail backend to use to send the emails
    :param fail_silently: whether any error should be raised, or just be ignored; by default it will raise
    :param gen_connection_params_function: a function that takes a recipient and generates connection params
    """
    try:
        iter(recipients)
    except TypeError:
        recipients = [recipients]

    if recipient_type not in ["to", "cc", "bcc"]:
        raise ValueError("`recipient_type` must be to, cc or bcc")

    if bindings is None:
        bindings = {}

    if connection is None:
        connection = get_connection(backend, fail_silently)

    if preferences_link:
        bindings["preferences_link"] = bindings["PREFERENCES_LINK"] = front_url(
            "contact"
        )
        bindings["unsubscribe_link"] = bindings["UNSUBSCRIBE_LINK"] = front_url(
            "unsubscribe"
        )

    link_bindings = {
        key: value for key, value in bindings.items() if is_front_url(value)
    }

    html_template = loader.get_template(f"mail_templates/{code}.html")
    try:
        text_template = loader.get_template(f"mail_templates/{code}.txt")
    except TemplateDoesNotExist:
        text_template = None

    with connection:
        for recipient in recipients:
            # recipient can be either a Person or an email address
            if isinstance(recipient, Person):
                if recipient.role is not None and not recipient.role.is_active:
                    continue
                connection_params = generate_token_params(recipient)
                for key, value in link_bindings.items():
                    if isinstance(value, AutoLoginUrl):
                        bindings[key] = add_params_to_urls(value, connection_params)
                bindings["MERGE_LOGIN"] = urlencode(connection_params)

            context = get_context_from_bindings(code, recipient, bindings)
            html_message = html_template.render(context=context)
            text_message = (
                text_template.render(
                    context={k: conditional_html_to_text(v) for k, v in context.items()}
                )
                if text_template
                else generate_plain_text(html_message)
            )

            email = EmailMultiAlternatives(
                subject=subject,
                body=text_message,
                from_email=from_email,
                reply_to=reply_to,
                connection=connection,
                **{
                    recipient_type: [
                        recipient.email if isinstance(recipient, Person) else recipient
                    ]
                },
            )
            email.attach_alternative(html_message, "text/html")
            if attachments is not None:
                for attachment in attachments:
                    if isinstance(attachment, MIMEBase):
                        email.attach(attachment)
                    elif isinstance(attachment, dict):
                        email.attach(**attachment)
                    else:
                        email.attach(*attachment)
            email.send(fail_silently=fail_silently)
コード例 #32
0
def send_batch_emails(emails):
    connection = mail.get_connection()
    connection.send_messages(emails)
コード例 #33
0
ファイル: views.py プロジェクト: alpha1693/Bouncer
def register(request):

    registered = False

    # If it's a HTTP POST, we'll process the form data.
    if request.method == 'POST':
        # Attempt to grab information from the raw form information.
        username = request.POST['username']
        email = request.POST['email']
        user_form = UserForm(data=request.POST)
        # If the form is valid...
        if user_form.is_valid():
            # Save the user's form data to the database.
            user = user_form.save()

            # Hash the password with the set_password method
            user.set_password(user.password)
            user.save()
            # Update our variable to tell the template registration was
            # successful.
            registered = True
            # START FOR DEVELOPMENT USE ONLY
            subject = 'Verify Email'
            email_body = 'Hello ' + username + ", click this <a href='http://127.0.0.1:8000/verify/" + \
                email + "'>link</a> to verify your account"
            email_from = '*****@*****.**'

            with mail.get_connection() as connection:
                mail.EmailMessage(
                    subject,
                    email_body,
                    email_from,
                    [email],
                    connection=connection,
                ).send()
            # END FOR DEVELOPMENT USE ONLY

            return HttpResponse(
                "Please check your email for a verification link for your account."
            )

        else:
            # See if we have that username or email in the db
            user_username = User.objects.filter(username=username)
            user_email = User.objects.filter(email=email)

            if user_username & user_email:
                error = "That account already exists."
            elif user_username:
                error = "That username is already taken."
            elif user_email:
                error = "That email is already in use."
            else:
                error = 'Registration credentials are not valid. Please try again.'

            return render(request, 'register.html', {
                'error': error,
                'user_form': user_form,
                'registered': registered
            })


# Not a HTTP POST, so we render our form using our ModelForm instance.
# These forms will be blank, ready for user input.
    else:
        user_form = UserForm()
    return render(request, 'register.html', {
        'user_form': user_form,
        'registered': registered
    })
コード例 #34
0
 def handle(self, *args, **options):
     connection = mail.get_connection()
     messages = self.get_emails()
     num_emails = connection.send_messages(messages)
     self.stdout.write(
         unicode(_(u'Foram enviados {0} emails\n'.format(num_emails))), )
コード例 #35
0
    def create(
        self,
        request=None,
        from_email=None,
        to=None,
        cc=None,
        bcc=None,
        reply_to=None,
        context=None,
        attachments=None,
        alternatives=None,
        fail_silently=True,
        auth_user=None,
        auth_password=None,
        connection=None,
        headers=None,
        noreply=False,
        language=None,
        subject=None,
        body=None,
    ):  # NOQA
        site = Site.objects.get_current()
        subject_template = Template(
            self.translate(
                language=language).subject if subject is None else subject)
        body_template = Template(
            self.translate(language=language).body if body is None else body)

        context = {} if context is None else context
        context = Context(context) if request is None else RequestContext(
            request, context)

        connection = connection or get_connection(
            username=auth_user,
            password=auth_password,
            fail_silently=fail_silently,
        )

        if isinstance(to, str):
            to = [to]
        elif self.default_to:
            to = self.default_to.split(",")
        if isinstance(cc, str):
            cc = [cc]
        elif self.default_cc:
            cc = self.default_cc.split(",")
        if isinstance(bcc, str):
            bcc = [bcc]
        elif self.default_bcc:
            bcc = self.default_bcc.split(",")
        if isinstance(reply_to, str):
            reply_to = [reply_to]
        elif self.default_reply_to:
            reply_to = self.default_reply_to.split(",")

        headers = headers = {} if headers is None else headers
        noreply = noreply or self.noreply
        if noreply and not reply_to and "Reply-to" not in headers:
            reply_to = ["noreply@%s" % site.domain]

        kwargs = {
            "subject": subject_template.render(context).replace("\n", ""),
            "body": body_template.render(context),
            "from_email":
            self.from_email if from_email is None else from_email,
            "to": to,
            "cc": cc,
            "bcc": bcc,
            "reply_to": reply_to,
            "headers": headers,
            "connection": connection,
            "attachments": attachments,
            "alternatives": alternatives,
        }

        email = EmailMultiAlternatives(**kwargs)
        if self.body_html:
            body_html_template = Template(
                self.translate(language=language).body_html)
            email.attach_alternative(body_html_template.render(context),
                                     "text/html")

        return email
コード例 #36
0
ファイル: signals.py プロジェクト: antonio-yves/ctrl_p
from django.db.models.signals import post_save
from django.core.mail import EmailMessage
from django.core import mail
from django.dispatch import receiver

from .models import File

from app.core.models import UUIDUser

connection = mail.get_connection()
connection.open()


def file_create_post_save(sender, instance, created, **kwargs):
    user_adm = UUIDUser.objects.filter(is_staff=True).first()
    if created:
        email_user = mail.EmailMessage(
            'Arquivo Enviado com Sucesso - Status Atual "Aguradando Impressão"',
            'Caro, %s.\n\nInformamos que o arquivo "%s" foi recebido com sucesso, logo ele será impresso e você poderá pegar o arquivo pronto na mecanografia.\n\nAtenciosamente,\n%s\n\n\n\nEssa mensagem é automática, ok? Não é pra responder esse e-mail.'
            % (instance.user.first_name, instance.name, user_adm.first_name),
            '*****@*****.**',
            [instance.user.email],
            connection=connection,
        )
        email_user.send()
        email_adm = mail.EmailMessage(
            'Novo Arquivo Aguradando Impressão',
            'O usuário %s enviou um novo arquivo para impressão.\n\nDetalhes da Solicitação:\nNome do Arquivo: %s\nQuantidade de Páginas: %i\nQuantidade de Cópias: %i\n\n\n\nEssa mensagem é automática, ok? Não é pra responder esse e-mail.'
            % (instance.user.first_name, instance.name, instance.pages,
               instance.copy),
            '*****@*****.**',
コード例 #37
0
ファイル: views.py プロジェクト: legendjslc/survey
def build_survey(request, survey_id):
    survey = Survey.objects.get(pk=survey_id)
    name = ''
    if request.method == 'POST':
        new_visitor = Visitor.objects.create(survey=survey, user=survey.user)
        data = Dicty.objects.create(name=new_visitor.pk)
        print('request.POST: ', request.POST)
        for key in request.POST:
            if key != 'csrfmiddlewaretoken':
                poll = Poll.objects.get(pk=key)

                if poll.poll_type == 'multi':
                    charchoices = CharChoice.objects.filter(
                        pk__in=request.POST.getlist(key))
                    new_visitor.choices.add(*charchoices)
                    KeyVal.objects.create(container=data,
                                          key=poll.group.name,
                                          value=str([
                                              choice.group.name
                                              for choice in charchoices
                                          ]))
                    new_visitor.collected_data = data
                    new_visitor.save()

                elif poll.poll_type == 'one':
                    choice = CharChoice.objects.get(pk=request.POST[key])
                    new_visitor.choices.add(choice)
                    KeyVal.objects.create(container=data,
                                          key=poll.group.name,
                                          value=choice.group.name)
                    new_visitor.collected_data = data
                    new_visitor.save()

                else:
                    choice, create = CharChoice.objects.get_or_create(
                        choice_text=request.POST[key],
                        poll=poll,
                        created_by_visitor=True,
                        user=survey.user)
                    new_visitor.choices.add(choice)
                    KeyVal.objects.create(container=data,
                                          key=poll.group.name,
                                          value=choice)
                    new_visitor.collected_data = data
                    new_visitor.save()

                for survey_attr in survey.surveyattribute_set.all():
                    if poll in survey_attr.polls.all():
                        if survey_attr.attr_type == 'summarize':
                            survey_attr.summarize(int(choice.choice_text))

                        if survey_attr.attr_type == 'count':
                            survey_attr.count(poll, choice)

                if poll.poll_type == 'email_now':
                    email = choice.choice_text

                if poll.poll_type == 'first_name':
                    name = choice.choice_text
        try:
            split_body = survey.welcome_letter.body.split('//')
            body = ''
            for part in split_body:
                if part == 'first_name':
                    part = name
                body += part

            send_mail(
                survey.welcome_letter.subject,
                body,
                survey.user.preferences['email_settings__email_host_user'],
                [email],
                connection=get_connection(
                    host=survey.user.preferences[
                        'email_settings__comment_notifications_enabled'],
                    port=survey.user.preferences['email_settings__email_port'],
                    password=survey.user.
                    preferences['email_settings__email_password'],
                    username=survey.user.
                    preferences['email_settings__email_host_user'],
                    use_tls=survey.user.
                    preferences['email_settings__enable_TSL']),
                fail_silently=False)
            message = ''

            if survey.notify:
                send_mail(
                    'submit notification',
                    message,
                    survey.user.preferences['email_settings__email_host_user'],
                    [survey.user.email],
                    html_message=new_visitor.print_visitor(),
                    connection=get_connection(
                        host=survey.user.preferences[
                            'email_settings__comment_notifications_enabled'],
                        port=survey.user.
                        preferences['email_settings__email_port'],
                        password=survey.user.
                        preferences['email_settings__email_password'],
                        username=survey.user.
                        preferences['email_settings__email_host_user'],
                        use_tls=survey.user.
                        preferences['email_settings__enable_TSL']),
                    fail_silently=False)
        except:
            print('email address not valid')
        return HttpResponseRedirect("/thankyou/")

    polls = Poll.objects.filter(survey=survey, first_level=True)
    context = {'survey': survey, 'polls': polls}
    return render(request, 'polls/index.html', context)
コード例 #38
0
def send_queued_message(queued_message,
                        smtp_connection=None,
                        blacklist=None,
                        log=True):
    """
    Send a queued message, returning a response code as to the action taken.

    The response codes can be found in ``django_mailer.constants``. The
    response will be either ``RESULT_SKIPPED`` for a blacklisted email,
    ``RESULT_FAILED`` for a deferred message or ``RESULT_SENT`` for a
    successful sent message.

    To allow optimizations if multiple messages are to be sent, an SMTP
    connection can be provided and a list of blacklisted email addresses.
    Otherwise an SMTP connection will be opened to send this message and the
    email recipient address checked against the ``Blacklist`` table.

    If the message recipient is blacklisted, the message will be removed from
    the queue without being sent. Otherwise, the message is attempted to be
    sent with an SMTP failure resulting in the message being flagged as
    deferred so it can be tried again later.

    By default, a log is created as to the action. Either way, the original
    message is not deleted.

    """
    message = queued_message.message
    if smtp_connection is None:
        smtp_connection = get_connection()
    opened_connection = False

    if blacklist is None:
        blacklisted = models.Blacklist.objects.filter(email=message.to_address)
    else:
        blacklisted = message.to_address in blacklist

    log_message = ''
    if blacklisted:
        logger.info("Not sending to blacklisted email: %s" %
                    message.to_address.encode("utf-8"))
        queued_message.delete()
        result = constants.RESULT_SKIPPED
    else:
        try:
            logger.info("Sending message to %s: %s" %
                        (message.to_address.encode("utf-8"),
                         message.subject.encode("utf-8")))
            opened_connection = smtp_connection.open()
            attached_message = EmailMultiAlternatives(
                message.subject,
                message.encoded_message,
                message.from_address, [message.to_address],
                connection=smtp_connection)
            if message.html_message:
                attached_message.attach_alternative(message.html_message,
                                                    "text/html")
            if message.attachment:
                for attachment in message.attachment.all():
                    attached_message.attach_file(attachment.filename)
            attached_message.send()

            # Normal django-mailer behaviour:
            #smtp_connection.connection.sendmail(message.from_address,
            #                                    [message.to_address],
            #                                    message.encoded_message)

            queued_message.delete()
            result = constants.RESULT_SENT
        except (SocketError, smtplib.SMTPSenderRefused,
                smtplib.SMTPRecipientsRefused,
                smtplib.SMTPAuthenticationError), err:
            queued_message.defer()
            logger.warning("Message to %s deferred due to failure: %s" %
                           (message.to_address.encode("utf-8"), err))
            log_message = unicode(err)
            result = constants.RESULT_FAILED
コード例 #39
0
def send_all(block_size=500, backend=None):
    """
    Send all non-deferred messages in the queue.

    A lock file is used to ensure that this process can not be started again
    while it is already running.

    The ``block_size`` argument allows for queued messages to be iterated in
    blocks, allowing new prioritised messages to be inserted during iteration
    of a large number of queued messages.

    """
    lock = FileLock(LOCK_PATH)

    logger.debug("Acquiring lock...")
    try:
        # lockfile has a bug dealing with a negative LOCK_WAIT_TIMEOUT (which
        # is the default if it's not provided) systems which use a LinkFileLock
        # so ensure that it is never a negative number.
        lock.acquire(settings.LOCK_WAIT_TIMEOUT or 0)
        #lock.acquire(settings.LOCK_WAIT_TIMEOUT)
    except AlreadyLocked:
        logger.debug("Lock already in place. Exiting.")
        return
    except LockTimeout:
        logger.debug("Waiting for the lock timed out. Exiting.")
        return
    logger.debug("Lock acquired.")

    start_time = time.time()

    sent = deferred = skipped = 0

    try:
        if constants.EMAIL_BACKEND_SUPPORT:
            connection = get_connection(backend=backend)
        else:
            connection = get_connection()
        blacklist = models.Blacklist.objects.values_list('email', flat=True)
        connection.open()
        for message in _message_queue(block_size):
            result = send_queued_message(message,
                                         smtp_connection=connection,
                                         blacklist=blacklist)
            if result == constants.RESULT_SENT:
                sent += 1
            elif result == constants.RESULT_FAILED:
                deferred += 1
            elif result == constants.RESULT_SKIPPED:
                skipped += 1
        connection.close()
    finally:
        logger.debug("Releasing lock...")
        lock.release()
        logger.debug("Lock released.")

    logger.debug("")
    if deferred or skipped:
        log = logger.warning
    else:
        log = logger.info
    log("%s sent, %s deferred, %s skipped." % (sent, deferred, skipped))
    logger.debug("Completed in %.2f seconds." % (time.time() - start_time))
コード例 #40
0
ファイル: testsendmail.py プロジェクト: aledezma24/mpod
    domain = 'cimav.edu.mx'

    ######################################################################################
    #                                 ''' con base de datos '''
    ######################################################################################

    smtpconfig = Configuration.objects.get(pk=1)
    messageMailSignup = MessageMail.objects.get(pk=3)
    my_use_tls = False
    if smtpconfig.email_use_tls == 1:
        my_use_tls = True

    fail_silently = False
    connection = get_connection(host=smtpconfig.email_host,
                                port=int(smtpconfig.email_port),
                                username=smtpconfig.email_host_user,
                                password=smtpconfig.email_host_password,
                                use_tls=my_use_tls)

    htmlmessage = messageMailSignup.email_regards + " " + user.username + ",</br> " + messageMailSignup.email_message + "</br> " + messageMailSignup.email_message + "</br> " + "http://mpod.cimav.edu.mx/activate/Nzc=/4oq-9cac01d09e86d5e9d2d4"
    print htmlmessage
    send_mail(messageMailSignup.email_subject,
              htmlmessage,
              smtpconfig.email_host_user, [user.email],
              connection=connection)

    ######################################################################################
    #                                 ''' sin  base de datos '''
    ######################################################################################
    my_host = 'smtp.gmail.com'
    my_port = 587
コード例 #41
0
def get_newsletter_connection():
    return get_connection(backend=settings.NEWSLETTER_EMAIL_BACKEND)
コード例 #42
0
ファイル: core.py プロジェクト: jdruiter/djmail
def _get_real_backend():
    real_backend_path = getattr(
        settings, 'DJMAIL_REAL_BACKEND',
        'django.core.mail.backends.console.EmailBackend')
    return get_connection(backend=real_backend_path, fail_silently=False)
コード例 #43
0
ファイル: message.py プロジェクト: MariaMsu/DjangoSite
 def get_connection(self, fail_silently=False):
     from django.core.mail import get_connection
     if not self.connection:
         self.connection = get_connection(fail_silently=fail_silently)
     return self.connection
コード例 #44
0
ファイル: views.py プロジェクト: serkandikmen/Praktomat
def solution_list(request, task_id, user_id=None):
    if (user_id and not request.user.is_trainer
            and not request.user.is_superuser):
        return access_denied(request)

    task = get_object_or_404(Task, pk=task_id)
    author = get_object_or_404(User, pk=user_id) if user_id else request.user
    solutions = task.solution_set.filter(author=author).order_by('-id')
    final_solution = task.final_solution(author)

    if task.publication_date >= datetime.now() and not request.user.is_trainer:
        raise Http404

    if request.method == "POST":
        if task.expired() and not request.user.is_trainer:
            return access_denied(request)

        solution = Solution(task=task, author=author)
        formset = SolutionFormSet(request.POST,
                                  request.FILES,
                                  instance=solution)
        if formset.is_valid():
            solution.save()
            formset.save()
            run_all_checker = bool(
                User.objects.filter(id=user_id,
                                    tutorial__tutors__pk=request.user.id)
                or request.user.is_trainer)
            solution.check_solution(run_all_checker)

            if solution.accepted:
                # Send submission confirmation email
                t = loader.get_template(
                    'solutions/submission_confirmation_email.html')
                c = {
                    'protocol': request.is_secure() and "https" or "http",
                    'domain': RequestSite(request).domain,
                    'site_name': settings.SITE_NAME,
                    'solution': solution,
                }
                if user_id:
                    # in case someone else uploaded the solution, add this to the email
                    c['uploader'] = request.user
                with tempfile.NamedTemporaryFile(mode='w+') as tmp:
                    tmp.write("Content-Type: text/plain; charset=utf-8\n")
                    tmp.write(
                        "Content-Transfer-Encoding: quoted-printable\n\n")
                    tmp.write(t.render(c))
                    tmp.seek(0)
                    [signed_mail, __, __, __,
                     __] = execute_arglist([
                         "openssl", "smime", "-sign", "-signer",
                         settings.CERTIFICATE, "-inkey", settings.PRIVATE_KEY,
                         "-in", tmp.name
                     ],
                                           ".",
                                           unsafe=True)
                connection = get_connection()
                message = ConfirmationMessage(_("%s submission confirmation") %
                                              settings.SITE_NAME,
                                              signed_mail,
                                              None, [solution.author.email],
                                              connection=connection)
                if solution.author.email:
                    message.send()

            if solution.accepted or get_settings().accept_all_solutions:
                solution.final = True
                solution.save()

            return HttpResponseRedirect(
                reverse('solution_detail', args=[solution.id]))
    else:
        formset = SolutionFormSet()

    attestations = Attestation.objects.filter(
        solution__task=task, author__tutored_tutorials=request.user.tutorial)
    attestationsPublished = attestations[0].published if attestations else False

    return render(
        request, "solutions/solution_list.html", {
            "formset": formset,
            "task": task,
            "solutions": solutions,
            "final_solution": final_solution,
            "attestationsPublished": attestationsPublished,
            "author": author,
            "invisible_attestor": get_settings().invisible_attestor
        })
コード例 #45
0
ファイル: tutormail2017.py プロジェクト: tjavsi/web
def send_messages(messages, backend_type):
    from django.core.mail import get_connection

    email_backend = get_connection(backend=backend_type)

    return email_backend.send_messages(messages)
コード例 #46
0
    def handle(self, *args, **options):
        from applications.delivery.models import Delivery
        try:
            deliveryes = Delivery.objects.filter(
                delivery_test=False,
                send_test=True,
                send_general=False,
                type__in=[
                    1,
                    2,
                    3,
                ],
            )
        except Delivery.DoesNotExist:
            deliveryes = None
        else:
            from applications.delivery.models import EmailMiddleDelivery
            for delivery in deliveryes:
                # print 'delivery', delivery
                try:
                    EmailMiddleDelivery.objects.\
                        get(delivery=delivery,
                            send_test=False,
                            send_general=True,
                            updated_at__lte=delivery.updated_at, )
                except:
                    """ Создаем ссылочку на отсылку рассылки """
                    email_middle_delivery = EmailMiddleDelivery()
                    email_middle_delivery.delivery = delivery
                    email_middle_delivery.delivery_test_send = False
                    email_middle_delivery.delivery_send = True
                    email_middle_delivery.save()
                    """ Закрываем отсылку теста в самой рассылке """
                    delivery.send_general = True
                    delivery.save()
                    """ Отсылаем тестовое письмо """
                    from django.utils.html import strip_tags

                    EMAIL_USE_TLS = True
                    EMAIL_HOST = 'smtp.yandex.ru'
                    EMAIL_PORT = 587
                    EMAIL_HOST_USER = '******'
                    EMAIL_HOST_PASSWORD = ''
                    from django.core.mail import get_connection
                    backend = get_connection(
                        backend='django.core.mail.backends.smtp.EmailBackend',
                        host=EMAIL_HOST,
                        port=EMAIL_PORT,
                        username=EMAIL_HOST_USER,
                        password=EMAIL_HOST_PASSWORD,
                        use_tls=EMAIL_USE_TLS,
                        fail_silently=False,
                    )
                    from django.core.mail import EmailMultiAlternatives
                    from proj.settings import Email_MANAGER

                    from applications.authModel.models import Email
                    """ Создаем указатели на E-Mail адреса рассылки """
                    try:
                        emails = Email.objects.filter(bad_email=False, )
                    except Email.DoesNotExist:
                        emails = None
                    """ Здесь нужно помудрить с коммитом """
                    from applications.delivery.models import EmailForDelivery
                    from applications.delivery.utils import parsing
                    i = 0
                    time = 0
                    for real_email in emails:
                        i += 1
                        # if i < 125:
                        #     continue
                        email = EmailForDelivery.objects.create(
                            delivery=email_middle_delivery,
                            email=real_email,
                        )
                        """ Отсылка """
                        msg = EmailMultiAlternatives(
                            subject=delivery.subject,
                            body=strip_tags(
                                parsing(
                                    value=delivery.html,
                                    key=email.key,
                                ), ),
                            from_email='*****@*****.**',
                            to=[
                                real_email.email,
                            ],
                            connection=backend,
                        )
                        msg.attach_alternative(
                            content=parsing(
                                value=delivery.html,
                                key=email.key,
                            ),
                            mimetype="text/html",
                        )
                        msg.content_subtype = "html"
                        try:
                            msg.send(fail_silently=False, )
                        except Exception as e:
                            msg = EmailMultiAlternatives(
                                subject='Error for subject: %s' %
                                delivery.subject,
                                body=
                                'Error: %s - E-Mail: %s - real_email.pk: %d' %
                                (
                                    e,
                                    real_email.email,
                                    real_email.pk,
                                ),
                                from_email='*****@*****.**',
                                to=[
                                    '*****@*****.**',
                                ],
                                connection=backend,
                            )
                            msg.send(fail_silently=True, )
                        else:
                            print 'i: ', i, 'Pk: ', real_email.pk, ' - ', real_email.email
                            from random import randrange
                            time1 = randrange(
                                6,
                                12,
                            )
                            time2 = randrange(
                                6,
                                12,
                            )
                            time += time1 + time2
                            print 'Time1: ', time1, ' Time2: ', time2, ' Time all: ', time1 + time2, ' average time: ', time / i
                            from time import sleep
                            sleep(time1, )
                            print 'Next'
                            sleep(time2, )
コード例 #47
0
ファイル: 16854_utils.py プロジェクト: dslika/Oscar
def send_product_alerts(product):  # noqa C901 too complex
    """
    Check for notifications for this product and send email to users
    if the product is back in stock. Add a little 'hurry' note if the
    amount of in-stock items is less then the number of notifications.
    """
    stockrecords = product.stockrecords.all()
    num_stockrecords = len(stockrecords)
    if not num_stockrecords:
        return

    logger.info("Sending alerts for '%s'", product)
    alerts = ProductAlert.objects.filter(
        product_id__in=(product.id, product.parent_id),
        status=ProductAlert.ACTIVE,
    )

    # Determine 'hurry mode'
    if num_stockrecords == 1:
        num_in_stock = stockrecords[0].num_in_stock
    else:
        result = stockrecords.aggregate(max_in_stock=Max('num_in_stock'))
        num_in_stock = result['max_in_stock']

    # hurry_mode is false if num_in_stock is None
    hurry_mode = num_in_stock is not None and alerts.count() > num_in_stock

    # For backwards compability, we check if the old (non-communication-event)
    # templates exist, and use them if they do.
    # This will be removed in Oscar 2.0
    try:
        email_subject_tpl = loader.get_template('customer/alerts/emails/'
                                                'alert_subject.txt')
        email_body_tpl = loader.get_template('customer/alerts/emails/'
                                             'alert_body.txt')

        use_deprecated_templates = True
        warnings.warn(
            "Product alert notifications now use the CommunicationEvent. "
            "Move '{}' to '{}', and '{}' to '{}'".format(
                'customer/alerts/emails/alert_subject.txt',
                'customer/emails/commtype_product_alert_subject.txt',
                'customer/alerts/emails/alert_body.txt',
                'customer/emails/commtype_product_alert_body.txt',
            ),
            category=RemovedInOscar20Warning,
            stacklevel=2)

    except TemplateDoesNotExist:
        code = 'PRODUCT_ALERT'
        try:
            event_type = CommunicationEventType.objects.get(code=code)
        except CommunicationEventType.DoesNotExist:
            event_type = CommunicationEventType.objects.model(code=code)
        use_deprecated_templates = False

    messages_to_send = []
    user_messages_to_send = []
    num_notifications = 0
    selector = Selector()
    for alert in alerts:
        # Check if the product is available to this user
        strategy = selector.strategy(user=alert.user)
        data = strategy.fetch_for_product(product)
        if not data.availability.is_available_to_buy:
            continue

        ctx = {
            'alert': alert,
            'site': Site.objects.get_current(),
            'hurry': hurry_mode,
        }
        if alert.user:
            # Send a site notification
            num_notifications += 1
            subj_tpl = loader.get_template(
                'customer/alerts/message_subject.html')
            message_tpl = loader.get_template('customer/alerts/message.html')
            services.notify_user(alert.user,
                                 subj_tpl.render(ctx).strip(),
                                 body=message_tpl.render(ctx).strip())

        # Build message and add to list
        if use_deprecated_templates:
            messages = {
                'subject': email_subject_tpl.render(ctx).strip(),
                'body': email_body_tpl.render(ctx),
                'html': '',
                'sms': '',
            }
        else:
            messages = event_type.get_messages(ctx)

        if messages and messages['body']:
            if alert.user:
                user_messages_to_send.append((alert.user, messages))
            else:
                messages_to_send.append((alert.get_email_address(), messages))
        alert.close()

    # Send all messages using one SMTP connection to avoid opening lots of them
    if messages_to_send or user_messages_to_send:
        connection = mail.get_connection()
        connection.open()
        disp = Dispatcher(mail_connection=connection)
        for message in messages_to_send:
            disp.dispatch_direct_messages(*message)
        for message in user_messages_to_send:
            disp.dispatch_user_messages(*message)
        connection.close()

    logger.info("Sent %d notifications and %d messages", num_notifications,
                len(messages_to_send) + len(user_messages_to_send))
コード例 #48
0
def send_all():
    """
    Send all eligible messages in the queue.
    """
    # The actual backend to use for sending, defaulting to the Django default.
    # To make testing easier this is not stored at module level.
    EMAIL_BACKEND = getattr(settings, "MAILER_EMAIL_BACKEND",
                            "django.core.mail.backends.smtp.EmailBackend")

    acquired, lock = acquire_lock()
    if not acquired:
        return

    start_time = time.time()

    deferred = 0
    sent = 0

    try:
        for message in prioritize():
            try:
                print('MSG', message.email.host, message.email.port,
                      message.email.username)
                if message.email.connection:
                    connection = EmailBackend(host=message.email.host,
                                              port=message.email.port,
                                              username=message.email.username,
                                              password=message.email.password,
                                              use_tls=message.email.use_tls,
                                              use_ssl=message.email.use_ssl)
                else:
                    connection = get_connection(backend=EMAIL_BACKEND, )

                logging.info("sending message '{0}' to {1}".format(
                    message.subject,
                    ", ".join([str(email) for email in message.to_addresses])))
                email = message.email
                if email is not None:
                    email.connection = connection
                    if not hasattr(email, 'reply_to'):
                        # Compatability fix for EmailMessage objects
                        # pickled when running < Django 1.8 and then
                        # unpickled under Django 1.8
                        email.reply_to = []
                    ensure_message_id(email)
                    print('YYYY')
                    email.send()
                    print('XXXXs')
                    # connection can't be stored in the MessageLog
                    email.connection = None
                    message.email = email  # For the sake of MessageLog
                    MessageLog.objects.log(message, RESULT_SUCCESS)
                    sent += 1
                else:
                    logging.warning(
                        "message discarded due to failure in converting from DB. Added on '%s' with priority '%s'"
                        % (message.when_added, message.priority))  # noqa
                message.delete()

            except (socket_error, smtplib.SMTPSenderRefused,
                    smtplib.SMTPRecipientsRefused, smtplib.SMTPDataError,
                    smtplib.SMTPAuthenticationError) as err:
                message.defer()
                traceback.print_exc()
                logging.info("message deferred due to failure: %s" % err)
                MessageLog.objects.log(message,
                                       RESULT_FAILURE,
                                       log_message=str(err))
                deferred += 1
                # Get new connection, it case the connection itself has an error.

            # Check if we reached the limits for the current run
            if _limits_reached(sent, deferred):
                break

            _throttle_emails()

    finally:
        release_lock(lock)

    logging.info("")
    logging.info("%s sent; %s deferred;" % (sent, deferred))
    logging.info("done in %.2f seconds" % (time.time() - start_time))
コード例 #49
0
ファイル: email_sending.py プロジェクト: manonthemat/froide
def get_mail_connection(**kwargs):
    return get_connection(
        backend=settings.EMAIL_BACKEND,
        **kwargs
    )
コード例 #50
0
def send_HTML_email(subject,
                    recipient,
                    html_content,
                    text_content=None,
                    cc=None,
                    email_from=settings.DEFAULT_FROM_EMAIL,
                    file_attachments=None,
                    bcc=None,
                    smtp_exception_skip_list=None):
    from corehq.util.python_compatibility import soft_assert_type_text
    if isinstance(recipient, six.string_types):
        soft_assert_type_text(recipient)
    recipient = list(recipient) if not isinstance(
        recipient, six.string_types) else [recipient]

    if not isinstance(html_content, six.text_type):
        html_content = html_content.decode('utf-8')

    if not text_content:
        text_content = getattr(settings, 'NO_HTML_EMAIL_MESSAGE',
                               NO_HTML_EMAIL_MESSAGE)
    elif not isinstance(text_content, six.text_type):
        text_content = text_content.decode('utf-8')

    from_header = {'From': email_from}  # From-header
    connection = get_connection()
    msg = EmailMultiAlternatives(subject,
                                 text_content,
                                 email_from,
                                 recipient,
                                 headers=from_header,
                                 connection=connection,
                                 cc=cc,
                                 bcc=bcc)
    for file in (file_attachments or []):
        if file:
            msg.attach(file["title"], file["file_obj"].getvalue(),
                       file["mimetype"])
    msg.attach_alternative(html_content, "text/html")

    try:
        msg.send()
    except SMTPSenderRefused as e:

        if smtp_exception_skip_list and e.smtp_code in smtp_exception_skip_list:
            raise e
        else:
            error_subject = _('ERROR: Could not send "%(subject)s"') % {
                'subject': subject,
            }

            if e.smtp_code in LARGE_FILE_SIZE_ERROR_CODES:
                error_text = _('Could not send email: file size is too large.')
            else:
                error_text = e.smtp_error
            error_text = '%s\n\n%s' % (
                error_text,
                _('Please contact %(support_email)s for assistance.') % {
                    'support_email': settings.SUPPORT_EMAIL,
                },
            )

            error_msg = EmailMultiAlternatives(
                error_subject,
                error_text,
                email_from,
                recipient,
                headers=from_header,
                connection=connection,
                cc=cc,
                bcc=bcc,
            )
            error_msg.send()
コード例 #51
0
 def test_bare_setting(self):
     """ESP settings are also usually allowed at root of settings file"""
     backend = get_connection()
     self.assertEqual(backend.sample_setting, 'setting_from_bare_settings')
コード例 #52
0
def _send_email(
    campaign_key: str,
    to: List[Dict[str, str]],
    subject: str,
    headers: Dict,
    txt_body: str = "",
    html_body: str = "",
) -> None:
    """
    Sends built email message asynchronously.
    """

    messages: List = []
    records: List = []

    with transaction.atomic():

        for dest in to:
            record, _ = MessagingRecord.objects.get_or_create(
                raw_email=dest["raw_email"], campaign_key=campaign_key)

            # Lock object (database-level) while the message is sent
            record = MessagingRecord.objects.select_for_update().get(
                pk=record.pk)
            # If an email for this campaign was already sent to this user, skip recipient
            if record.sent_at:
                record.save()  # release DB lock
                continue

            records.append(record)

            email_message = mail.EmailMultiAlternatives(
                subject=subject,
                body=txt_body,
                to=[dest["recipient"]],
                headers=headers,
            )

            email_message.attach_alternative(html_body, "text/html")
            messages.append(email_message)

        connection = None
        try:
            connection = mail.get_connection()
            connection.open()
            connection.send_messages(messages)

            for record in records:
                record.sent_at = timezone.now()
                record.save()

        except Exception as e:
            # Handle exceptions gracefully to avoid breaking the entire task for all teams
            # but make sure they're tracked on Sentry.
            capture_exception(e)
        finally:
            # ensure that connection has been closed
            try:
                connection.close()  # type: ignore
            except Exception:
                pass
コード例 #53
0
 def get_connection(self):
     return get_connection('bandit.backends.smtp.LogOnlySMTPBackend')
コード例 #54
0
    def _flush(self, **kwargs):
        if len(self.messages) == 0:
            return
        kwargs = dict({
            'request': None,
            'form': None,
            'fail_silently': False,
        }, **kwargs)
        request = kwargs.pop('request', None)
        form = kwargs.pop('form', None)
        self.connection = kwargs.get('connection', self.connection)
        self.connection = self.connection or mail.get_connection(**kwargs)

        try:
            # raise SMTPDataError(code=123, msg='Test error')
            if hasattr(self.ioc, 'before_sending'):
                self.ioc.before_sending()
            result = self.connection.send_messages(self.messages)
            if hasattr(self.ioc, 'success'):
                self.ioc.success()
            self.messages = []
            return result
        except (SMTPDataError, SMTPServerDisconnected, SMTPRecipientsRefused,
                SMTPSenderRefused, gaierror, ConnectionError) as e:
            if isinstance(e, SMTPDataError):
                title = e.smtp_code
                trans_msg = 'Error "%(err_type)s" "%(code)s" "%(msg)s" while sending email.'
                trans_params = {
                    'err_type': e.__class__.__name__,
                    'code': e.smtp_code,
                    'msg': e.smtp_error,
                }
            if isinstance(e, SMTPServerDisconnected):
                self.connection = mail.get_connection(**kwargs)
                title = 'SMTP server disconnected'
                trans_msg = 'Error "%(err_type)s" "%(msg)s" while sending email.'
                trans_params = {
                    'err_type': e.__class__.__name__,
                    'code': 1,
                    'msg': str(e),
                }
            else:
                title = e.errno
                trans_msg = 'Error "%(err_type)s" "%(code)s" "%(msg)s" while the transmission attempt.'
                trans_params = {
                    'err_type': e.__class__.__name__,
                    'code': e.errno,
                    'msg': e.strerror,
                }
            msg = _(trans_msg) % trans_params
            raise_error = self.ioc.error(
                **trans_params) if hasattr(self.ioc, 'error') else True
            if form is not None:
                form.add_error(None, msg)
            elif request is not None:
                if is_ajax(request):
                    raise ImmediateJsonResponse({
                        'view': 'alert_error',
                        'title': title,
                        'message': msg
                    })
                else:
                    messages.error(request, msg)
            elif raise_error:
                raise e
コード例 #55
0
def sendmail(request):
    current_user = request.user
    users = User.objects.all()
    customer = Customer.objects.all()
    campaign = Campaign.objects.all()
    email = Email.objects.all()
    campaigns = Campaign.objects.filter(my_customer=current_user.id)
    campmaildata = Campaign.objects.filter(camp_emails=current_user.id)
    emails = Email.objects.filter(my_customer=current_user.id)
    print(campmaildata)

    pi = Customer.objects.get(pk=current_user.id)

    if request.method == "POST" and request.FILES['file']:

        job = request.POST.get('job')
        message = request.POST.get('message')
        subject = ""
        file_names = ""
        getid = ""

        for e in Campaign.objects.filter(id=job):
            subject = e.email_subject
            getid = e.camp_emails.id

        print(getid)

        for f in Email.objects.filter(id=getid):
            file_names = f.upload_file

        from_email = settings.EMAIL_HOST_USER
        file = request.FILES['file']
        file_name = default_storage.save(file.name, file)
        df_file = pd.read_csv(file_names)
        # print(df_file)
        connection = mail.get_connection()
        connection.open()

        df = pd.DataFrame(df_file)

        list = df['Email'].tolist()

        email = mail.EmailMessage(subject,
                                  message,
                                  from_email,
                                  bcc=list,
                                  connection=connection)

        file = default_storage.open(file_name)
        file_url = default_storage.url(file_name)
        email.attach(file_url, file.read())
        connection.send_messages([email])

        messages.success(request, "Email sent Successfully")

        connection.close()
        return redirect('/customer')

    context = {
        'campaign': campaign,
        'email': email,
        'customer': customer,
        'current_user': current_user,
        'campaigns': campaigns,
        'emails': emails,
    }
    return render(request, 'sendmail.html', context)
コード例 #56
0
 def test_anymail_setting(self):
     """ESP settings usually come from ANYMAIL settings dict"""
     backend = get_connection()
     self.assertEqual(backend.sample_setting,
                      'setting_from_anymail_settings')
コード例 #57
0
 def connection(self):
     return get_connection(backend=self.email_backend, fail_silently=True)
コード例 #58
0
def send_mail(subject, email_body, user_to=None, email_to=None, email_from=None, reply_to=None,
              email_type_preference_check=None):
    """Sends email with a lot of defaults.

    The function will check if user's email is valid based on bounce info. The function will also check email
    preferences of destinataries of the email. Parameters user_to and email_to are mutually exclusive, if one is set,
    other should be None.

    Args:
        subject (str): subject of the email.
        email_body (str): body of the email.
        user_to (Union[User, List[User]]): a User object or a list of User objects to send the email to. If user_to
            is set, email_to should be None.
        email_to (Union[str, List[str]]): a string representing an email address or a list of strings representing
            email addresses who to send the email to.  If email_to is set, user_to should be None.
        email_from (str): email string that shows up as sender. The default value is DEFAULT_FROM_EMAIL in config.
        reply_to (str): cemail string that will be added as a "Reply-To" header to all mails being sent.
        email_type_preference_check (str): name of EmailPreferenceType that users should have enabled for the email to
            be sent. If set to None, no checks will be carried out.

    Returns:
        (bool): True if all emails were sent successfully, False otherwise.
    """

    assert bool(user_to) != bool(email_to), "One of parameters user_to and email_to should be set, but not both"

    if email_from is None:
        email_from = settings.DEFAULT_FROM_EMAIL

    if user_to:
        user_to = _ensure_list(user_to)
        email_to = []
        for user in user_to:

            # Check that user has preference enabled for that type of email
            email_type_enabled = user.profile.email_type_enabled(email_type_preference_check) \
                if email_type_preference_check is not None else True

            # Check if user's email is valid for delivery and add the correct email address to the list of email_to
            if user.profile.email_is_valid() and email_type_enabled:
                email_to.append(user.profile.get_email_for_delivery())

        # If all users have invalid emails or failed preference check, send no emails
        if len(email_to) == 0:
            return False

    if email_to:
        email_to = _ensure_list(email_to)

    if settings.ALLOWED_EMAILS:  # for testing purposes, so we don't accidentally send emails to users
        email_to = [email for email in email_to if email in settings.ALLOWED_EMAILS]

    try:
        emails = tuple(((settings.EMAIL_SUBJECT_PREFIX + subject, email_body, email_from, [email])
                        for email in email_to))

        # Replicating send_mass_mail functionality and adding reply-to header if requires
        connection = get_connection(username=None, password=None, fail_silently=False)
        headers = None
        if reply_to:
            headers = {'Reply-To': reply_to}
        messages = [EmailMessage(subject, message, sender, recipient, headers=headers)
                    for subject, message, sender, recipient in emails]

        connection.send_messages(messages)
        return True

    except Exception:
        return False
コード例 #59
0
 def refuse(self, *args, **kwargs):
     # Send notification.
     connection = mail.get_connection()
     emails = [self.email_refuse]
     connection.send_messages(emails)
コード例 #60
0
ファイル: tasks.py プロジェクト: wanduow/edx-platform
def _send_course_email(entry_id, email_id, to_list, global_email_context,
                       subtask_status):
    """
    Performs the email sending task.

    Sends an email to a list of recipients.

    Inputs are:
      * `entry_id`: id of the InstructorTask object to which progress should be recorded.
      * `email_id`: id of the CourseEmail model that is to be emailed.
      * `to_list`: list of recipients.  Each is represented as a dict with the following keys:
        - 'profile__name': full name of User.
        - 'email': email address of User.
        - 'pk': primary key of User model.
      * `global_email_context`: dict containing values that are unique for this email but the same
        for all recipients of this email.  This dict is to be used to fill in slots in email
        template.  It does not include 'name' and 'email', which will be provided by the to_list.
      * `subtask_status` : object of class SubtaskStatus representing current status.

    Sends to all addresses contained in to_list that are not also in the Optout table.
    Emails are sent multi-part, in both plain text and html.

    Returns a tuple of two values:
      * First value is a SubtaskStatus object which represents current progress at the end of this call.

      * Second value is an exception returned by the innards of the method, indicating a fatal error.
        In this case, the number of recipients that were not sent have already been added to the
        'failed' count above.
    """
    # Get information from current task's request:
    parent_task_id = InstructorTask.objects.get(pk=entry_id).task_id
    task_id = subtask_status.task_id
    total_recipients = len(to_list)
    recipient_num = 0
    total_recipients_successful = 0
    total_recipients_failed = 0
    recipients_info = Counter()

    log.info(
        "BulkEmail ==> Task: %s, SubTask: %s, EmailId: %s, TotalRecipients: %s",
        parent_task_id, task_id, email_id, total_recipients)

    try:
        course_email = CourseEmail.objects.get(id=email_id)
    except CourseEmail.DoesNotExist as exc:
        log.exception(
            "BulkEmail ==> Task: %s, SubTask: %s, EmailId: %s, Could not find email to send.",
            parent_task_id, task_id, email_id)
        raise

    # Exclude optouts (if not a retry):
    # Note that we don't have to do the optout logic at all if this is a retry,
    # because we have presumably already performed the optout logic on the first
    # attempt.  Anyone on the to_list on a retry has already passed the filter
    # that existed at that time, and we don't need to keep checking for changes
    # in the Optout list.
    if subtask_status.get_retry_count() == 0:
        to_list, num_optout = _filter_optouts_from_recipients(
            to_list, course_email.course_id)
        subtask_status.increment(skipped=num_optout)

    course_title = global_email_context['course_title']
    subject = "[" + course_title + "] " + course_email.subject

    # use the email from address in the CourseEmail, if it is present, otherwise compute it
    from_addr = course_email.from_addr if course_email.from_addr else \
        _get_source_address(course_email.course_id, course_title)

    # use the CourseEmailTemplate that was associated with the CourseEmail
    course_email_template = course_email.get_template()
    try:
        connection = get_connection()
        connection.open()

        # Define context values to use in all course emails:
        email_context = {'name': '', 'email': ''}
        email_context.update(global_email_context)

        while to_list:
            # Update context with user-specific values from the user at the end of the list.
            # At the end of processing this user, they will be popped off of the to_list.
            # That way, the to_list will always contain the recipients remaining to be emailed.
            # This is convenient for retries, which will need to send to those who haven't
            # yet been emailed, but not send to those who have already been sent to.
            recipient_num += 1
            current_recipient = to_list[-1]
            email = current_recipient['email']
            email_context['email'] = email
            email_context['name'] = current_recipient['profile__name']
            email_context['user_id'] = current_recipient['pk']
            email_context['course_id'] = course_email.course_id

            # Construct message content using templates and context:
            plaintext_msg = course_email_template.render_plaintext(
                course_email.text_message, email_context)
            html_msg = course_email_template.render_htmltext(
                course_email.html_message, email_context)

            # Create email:
            email_msg = EmailMultiAlternatives(subject,
                                               plaintext_msg,
                                               from_addr, [email],
                                               connection=connection)
            email_msg.attach_alternative(html_msg, 'text/html')

            # Throttle if we have gotten the rate limiter.  This is not very high-tech,
            # but if a task has been retried for rate-limiting reasons, then we sleep
            # for a period of time between all emails within this task.  Choice of
            # the value depends on the number of workers that might be sending email in
            # parallel, and what the SES throttle rate is.
            if subtask_status.retried_nomax > 0:
                sleep(settings.BULK_EMAIL_RETRY_DELAY_BETWEEN_SENDS)

            try:
                log.info(
                    "BulkEmail ==> Task: %s, SubTask: %s, EmailId: %s, Recipient num: %s/%s, \
                    Recipient name: %s, Email address: %s", parent_task_id,
                    task_id, email_id, recipient_num, total_recipients,
                    current_recipient['profile__name'], email)
                with dog_stats_api.timer(
                        'course_email.single_send.time.overall',
                        tags=[_statsd_tag(course_title)]):
                    connection.send_messages([email_msg])

            except SMTPDataError as exc:
                # According to SMTP spec, we'll retry error codes in the 4xx range.  5xx range indicates hard failure.
                total_recipients_failed += 1
                log.error(
                    "BulkEmail ==> Status: Failed(SMTPDataError), Task: %s, SubTask: %s, EmailId: %s, \
                    Recipient num: %s/%s, Email address: %s", parent_task_id,
                    task_id, email_id, recipient_num, total_recipients, email)
                if exc.smtp_code >= 400 and exc.smtp_code < 500:
                    # This will cause the outer handler to catch the exception and retry the entire task.
                    raise exc
                else:
                    # This will fall through and not retry the message.
                    log.warning(
                        'BulkEmail ==> Task: %s, SubTask: %s, EmailId: %s, Recipient num: %s/%s, \
                        Email not delivered to %s due to error %s',
                        parent_task_id, task_id, email_id, recipient_num,
                        total_recipients, email, exc.smtp_error)
                    dog_stats_api.increment('course_email.error',
                                            tags=[_statsd_tag(course_title)])
                    subtask_status.increment(failed=1)

            except SINGLE_EMAIL_FAILURE_ERRORS as exc:
                # This will fall through and not retry the message.
                total_recipients_failed += 1
                log.error(
                    "BulkEmail ==> Status: Failed(SINGLE_EMAIL_FAILURE_ERRORS), Task: %s, SubTask: %s, \
                    EmailId: %s, Recipient num: %s/%s, Email address: %s, Exception: %s",
                    parent_task_id, task_id, email_id, recipient_num,
                    total_recipients, email, exc)
                dog_stats_api.increment('course_email.error',
                                        tags=[_statsd_tag(course_title)])
                subtask_status.increment(failed=1)

            else:
                total_recipients_successful += 1
                log.info(
                    "BulkEmail ==> Status: Success, Task: %s, SubTask: %s, EmailId: %s, \
                    Recipient num: %s/%s, Email address: %s,", parent_task_id,
                    task_id, email_id, recipient_num, total_recipients, email)
                dog_stats_api.increment('course_email.sent',
                                        tags=[_statsd_tag(course_title)])
                if settings.BULK_EMAIL_LOG_SENT_EMAILS:
                    log.info('Email with id %s sent to %s', email_id, email)
                else:
                    log.debug('Email with id %s sent to %s', email_id, email)
                subtask_status.increment(succeeded=1)

            # Pop the user that was emailed off the end of the list only once they have
            # successfully been processed.  (That way, if there were a failure that
            # needed to be retried, the user is still on the list.)
            recipients_info[email] += 1
            to_list.pop()

        log.info(
            "BulkEmail ==> Task: %s, SubTask: %s, EmailId: %s, Total Successful Recipients: %s/%s, \
            Failed Recipients: %s/%s", parent_task_id, task_id, email_id,
            total_recipients_successful, total_recipients,
            total_recipients_failed, total_recipients)
        duplicate_recipients = [
            "{0} ({1})".format(email, repetition)
            for email, repetition in recipients_info.most_common()
            if repetition > 1
        ]
        if duplicate_recipients:
            log.info(
                "BulkEmail ==> Task: %s, SubTask: %s, EmailId: %s, Total Duplicate Recipients [%s]: [%s]",
                parent_task_id, task_id, email_id, len(duplicate_recipients),
                ', '.join(duplicate_recipients))

    except INFINITE_RETRY_ERRORS as exc:
        dog_stats_api.increment('course_email.infinite_retry',
                                tags=[_statsd_tag(course_title)])
        # Increment the "retried_nomax" counter, update other counters with progress to date,
        # and set the state to RETRY:
        subtask_status.increment(retried_nomax=1, state=RETRY)
        return _submit_for_retry(entry_id,
                                 email_id,
                                 to_list,
                                 global_email_context,
                                 exc,
                                 subtask_status,
                                 skip_retry_max=True)

    except LIMITED_RETRY_ERRORS as exc:
        # Errors caught here cause the email to be retried.  The entire task is actually retried
        # without popping the current recipient off of the existing list.
        # Errors caught are those that indicate a temporary condition that might succeed on retry.
        dog_stats_api.increment('course_email.limited_retry',
                                tags=[_statsd_tag(course_title)])
        # Increment the "retried_withmax" counter, update other counters with progress to date,
        # and set the state to RETRY:
        subtask_status.increment(retried_withmax=1, state=RETRY)
        return _submit_for_retry(entry_id,
                                 email_id,
                                 to_list,
                                 global_email_context,
                                 exc,
                                 subtask_status,
                                 skip_retry_max=False)

    except BULK_EMAIL_FAILURE_ERRORS as exc:
        dog_stats_api.increment('course_email.error',
                                tags=[_statsd_tag(course_title)])
        num_pending = len(to_list)
        log.exception(
            'Task %s: email with id %d caused send_course_email task to fail with "fatal" exception.  %d emails unsent.',
            task_id, email_id, num_pending)
        # Update counters with progress to date, counting unsent emails as failures,
        # and set the state to FAILURE:
        subtask_status.increment(failed=num_pending, state=FAILURE)
        return subtask_status, exc

    except Exception as exc:
        # Errors caught here cause the email to be retried.  The entire task is actually retried
        # without popping the current recipient off of the existing list.
        # These are unexpected errors.  Since they might be due to a temporary condition that might
        # succeed on retry, we give them a retry.
        dog_stats_api.increment('course_email.limited_retry',
                                tags=[_statsd_tag(course_title)])
        log.exception(
            'Task %s: email with id %d caused send_course_email task to fail with unexpected exception.  Generating retry.',
            task_id, email_id)
        # Increment the "retried_withmax" counter, update other counters with progress to date,
        # and set the state to RETRY:
        subtask_status.increment(retried_withmax=1, state=RETRY)
        return _submit_for_retry(entry_id,
                                 email_id,
                                 to_list,
                                 global_email_context,
                                 exc,
                                 subtask_status,
                                 skip_retry_max=False)

    else:
        # All went well.  Update counters with progress to date,
        # and set the state to SUCCESS:
        subtask_status.increment(state=SUCCESS)
        # Successful completion is marked by an exception value of None.
        return subtask_status, None
    finally:
        # Clean up at the end.
        connection.close()