Esempio n. 1
0
    def _build_sg_mail(self, email):
        mail = Mail()
        from_name, from_email = rfc822.parseaddr(email.from_email)
        # Python sendgrid client should improve
        # sendgrid/helpers/mail/mail.py:164
        if not from_name:
            from_name = None
        mail.set_from(Email(from_email, from_name))
        mail.set_subject(email.subject)

        personalization = Personalization()
        for e in email.to:
            personalization.add_to(Email(e))
        for e in email.cc:
            personalization.add_cc(Email(e))
        for e in email.bcc:
            personalization.add_bcc(Email(e))
        personalization.set_subject(email.subject)
        mail.add_content(Content("text/plain", email.body))
        if isinstance(email, EmailMultiAlternatives):
            for alt in email.alternatives:
                if alt[1] == "text/html":
                    mail.add_content(Content(alt[1], alt[0]))
        elif email.content_subtype == "html":
            mail.contents = []
            mail.add_content(Content("text/plain", ' '))
            mail.add_content(Content("text/html", email.body))

        if hasattr(email, 'categories'):
            for c in email.categories:
                mail.add_category(Category(c))

        if hasattr(email, 'template_id'):
            mail.set_template_id(email.template_id)
            if hasattr(email, 'substitutions'):
                for k, v in email.substitutions.items():
                    personalization.add_substitution(Substitution(k, v))

        for k, v in email.extra_headers.items():
            mail.add_header({k: v})

        for attachment in email.attachments:
            if isinstance(attachment, MIMEBase):
                attach = Attachment()
                attach.set_filename(attachment.get_filename())
                attach.set_content(base64.b64encode(attachment.get_payload()))
                mail.add_attachment(attach)
            elif isinstance(attachment, tuple):
                attach = Attachment()
                attach.set_filename(attachment[0])
                base64_attachment = base64.b64encode(attachment[1])
                if sys.version_info >= (3, ):
                    attach.set_content(str(base64_attachment, 'utf-8'))
                else:
                    attach.set_content(base64_attachment)
                attach.set_type(attachment[2])
                mail.add_attachment(attach)

        mail.add_personalization(personalization)
        return mail.get()
Esempio n. 2
0
    def _build_sg_mail(self, email):
        mail = Mail()
        from_name, from_email = rfc822.parseaddr(email.from_email)
        # Python sendgrid client should improve
        # sendgrid/helpers/mail/mail.py:164
        if not from_name:
            from_name = None
        mail.set_from(Email(from_email, from_name))
        mail.set_subject(email.subject)

        personalization = Personalization()
        for e in email.to:
            personalization.add_to(Email(e))
        for e in email.cc:
            personalization.add_cc(Email(e))
        for e in email.bcc:
            personalization.add_bcc(Email(e))
        personalization.set_subject(email.subject)
        mail.add_content(Content("text/plain", email.body))
        if isinstance(email, EmailMultiAlternatives):
            for alt in email.alternatives:
                if alt[1] == "text/html":
                    mail.add_content(Content(alt[1], alt[0]))
        elif email.content_subtype == "html":
            mail.contents = []
            mail.add_content(Content("text/plain", ' '))
            mail.add_content(Content("text/html", email.body))

        if hasattr(email, 'categories'):
            for c in email.categories:
                mail.add_category(Category(c))

        if hasattr(email, 'template_id'):
            mail.set_template_id(email.template_id)
            if hasattr(email, 'substitutions'):
                for key, value in email.substitutions.items():
                    personalization.add_substitution(Substitution(key, value))

        # SendGrid does not support adding Reply-To as an extra
        # header, so it needs to be manually removed if it exists.
        reply_to_string = ""
        for key, value in email.extra_headers.items():
            if key.lower() == "reply-to":
                reply_to_string = value
            else:
                mail.add_header({key: value})
        # Note that if you set a "Reply-To" header *and* the reply_to
        # attribute, the header's value will be used.
        if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to:
            # SendGrid only supports setting Reply-To to a single address.
            # See https://github.com/sendgrid/sendgrid-csharp/issues/339.
            reply_to_string = email.reply_to[0]
        # Determine whether reply_to contains a name and email address, or
        # just an email address.
        if reply_to_string:
            reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string)
            if reply_to_name and reply_to_email:
                mail.set_reply_to(Email(reply_to_email, reply_to_name))
            elif reply_to_email:
                mail.set_reply_to(Email(reply_to_email))

        for attachment in email.attachments:
            if isinstance(attachment, MIMEBase):
                attach = Attachment()
                attach.set_filename(attachment.get_filename())
                attach.set_content(base64.b64encode(attachment.get_payload()))
                mail.add_attachment(attach)
            elif isinstance(attachment, tuple):
                attach = Attachment()
                attach.set_filename(attachment[0])
                base64_attachment = base64.b64encode(attachment[1])
                if sys.version_info >= (3, ):
                    attach.set_content(str(base64_attachment, 'utf-8'))
                else:
                    attach.set_content(base64_attachment)
                attach.set_type(attachment[2])
                mail.add_attachment(attach)

        mail.add_personalization(personalization)
        return mail.get()
Esempio n. 3
0
    def _build_sg_mail(self, email):
        mail = Mail()
        from_name, from_email = rfc822.parseaddr(email.from_email)
        # Python sendgrid client should improve
        # sendgrid/helpers/mail/mail.py:164
        if not from_name:
            from_name = None
        mail.set_from(Email(from_email, from_name))
        mail.set_subject(email.subject)

        personalization = Personalization()
        for e in email.to:
            personalization.add_to(Email(e))
        for e in email.cc:
            personalization.add_cc(Email(e))
        for e in email.bcc:
            personalization.add_bcc(Email(e))
        personalization.set_subject(email.subject)
        mail.add_content(Content("text/plain", email.body))
        if isinstance(email, EmailMultiAlternatives):
            for alt in email.alternatives:
                if alt[1] == "text/html":
                    mail.add_content(Content(alt[1], alt[0]))
        elif email.content_subtype == "html":
            mail.contents = []
            mail.add_content(Content("text/plain", ' '))
            mail.add_content(Content("text/html", email.body))

        if hasattr(email, 'categories'):
            for c in email.categories:
                mail.add_category(Category(c))

        if hasattr(email, 'custom_args'):
            for k, v in email.custom_args.items():
                mail.add_custom_arg(CustomArg(k, v))

        if hasattr(email, 'template_id'):
            mail.set_template_id(email.template_id)
            if hasattr(email, 'substitutions'):
                for key, value in email.substitutions.items():
                    personalization.add_substitution(Substitution(key, value))

        # SendGrid does not support adding Reply-To as an extra
        # header, so it needs to be manually removed if it exists.
        reply_to_string = ""
        for key, value in email.extra_headers.items():
            if key.lower() == "reply-to":
                reply_to_string = value
            else:
                mail.add_header({key: value})
        # Note that if you set a "Reply-To" header *and* the reply_to
        # attribute, the header's value will be used.
        if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to:
            # SendGrid only supports setting Reply-To to a single address.
            # See https://github.com/sendgrid/sendgrid-csharp/issues/339.
            reply_to_string = email.reply_to[0]
        # Determine whether reply_to contains a name and email address, or
        # just an email address.
        if reply_to_string:
            reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string)
            if reply_to_name and reply_to_email:
                mail.set_reply_to(Email(reply_to_email, reply_to_name))
            elif reply_to_email:
                mail.set_reply_to(Email(reply_to_email))

        for attachment in email.attachments:
            if isinstance(attachment, MIMEBase):
                attach = Attachment()
                attach.set_filename(attachment.get_filename())
                attach.set_content(base64.b64encode(attachment.get_payload()))
                mail.add_attachment(attach)
            elif isinstance(attachment, tuple):
                attach = Attachment()
                attach.set_filename(attachment[0])
                base64_attachment = base64.b64encode(attachment[1])
                if sys.version_info >= (3,):
                    attach.set_content(str(base64_attachment, 'utf-8'))
                else:
                    attach.set_content(base64_attachment)
                attach.set_type(attachment[2])
                mail.add_attachment(attach)

        mail.add_personalization(personalization)
        return mail.get()
Esempio n. 4
0
    def _build_sg_mail(self, email):
        mail = Mail()
        from_name, from_email = rfc822.parseaddr(email.from_email)
        # Python sendgrid client should improve
        # sendgrid/helpers/mail/mail.py:164
        if not from_name:
            from_name = None
        mail.from_email = Email(from_email, from_name)
        mail.subject = email.subject

        mail_settings = MailSettings()

        personalization = Personalization()
        for e in email.to:
            personalization.add_to(Email(e))
        for e in email.cc:
            personalization.add_cc(Email(e))
        for e in email.bcc:
            personalization.add_bcc(Email(e))
        personalization.subject = email.subject
        if email.content_subtype == "html":
            mail.add_content(Content("text/html", email.body))
        else:
            mail.add_content(Content("text/plain", email.body))
        if isinstance(email, EmailMultiAlternatives):
            for alt in email.alternatives:
                if alt[1] == "text/html":
                    mail.add_content(Content(alt[1], alt[0]))
        elif email.content_subtype == "html":
            mail.contents = []
            mail.add_content(Content("text/plain", ' '))

        if hasattr(email, 'categories'):
            for c in email.categories:
                mail.add_category(Category(c))

        if hasattr(email, 'custom_args'):
            for k, v in email.custom_args.items():
                mail.add_custom_arg(CustomArg(k, v))

        # Used to override the list management (password reset etc)
        if hasattr(email, 'bypass_list_management'):
            mail_settings.bypass_list_management = BypassListManagement(
                email.bypass_list_management)

        #Check for sandbox mode
        sandbox_mode = getattr(settings, "SENDGRID_SANDBOX", False)
        if sandbox_mode:
            sandbox_whitelist_domains = getattr(
                settings, "SENDGRID_SANDBOX_WHITELIST_DOMAINS", [])
            sandbox_whitelist = False
            for e in email.to:
                domain = e.split('@')[1]
                if domain in sandbox_whitelist_domains:
                    sandbox_whitelist = True

            if not sandbox_whitelist:
                mail_settings.sandbox_mode = SandBoxMode(sandbox_mode)

        if hasattr(email, 'template_id'):
            mail.template_id = email.template_id
            # Version 3 dynamic data  handle bars {{name}}
            if hasattr(email, 'dynamic_data'):
                personalization.dynamic_template_data = email.dynamic_data
            # Version 3 substitutions
            if hasattr(email, 'substitutions'):
                for key, value in email.substitutions.items():
                    personalization.add_substitution(Substitution(key, value))

        # SendGrid does not support adding Reply-To as an extra
        # header, so it needs to be manually removed if it exists.
        reply_to_string = ""
        for key, value in email.extra_headers.items():
            if key.lower() == "reply-to":
                reply_to_string = value
            else:
                mail.add_header({key: value})
        # Note that if you set a "Reply-To" header *and* the reply_to
        # attribute, the header's value will be used.
        if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to:
            # SendGrid only supports setting Reply-To to a single address.
            # See https://github.com/sendgrid/sendgrid-csharp/issues/339.
            reply_to_string = email.reply_to[0]
        # Determine whether reply_to contains a name and email address, or
        # just an email address.
        if reply_to_string:
            reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string)
            if reply_to_name and reply_to_email:
                mail.reply_to = Email(reply_to_email, reply_to_name)
            elif reply_to_email:
                mail.reply_to = Email(reply_to_email)

        for attachment in email.attachments:
            if isinstance(attachment, MIMEBase):
                attach = Attachment()
                attach.filename = attachment.get_filename()
                attach.content = base64.b64encode(attachment.get_payload())
                mail.add_attachment(attach)
            elif isinstance(attachment, tuple):
                attach = Attachment()
                attach.filename = attachment[0]
                base64_attachment = base64.b64encode(attachment[1])
                if sys.version_info >= (3, ):
                    attach.content = str(base64_attachment, 'utf-8')
                else:
                    attach.content = base64_attachment
                attach.type = attachment[2]
                mail.add_attachment(attach)

        mail.add_personalization(personalization)
        mail.mail_settings = mail_settings
        return mail.get()
    def _build_sg_mail(self, email):
        """Custom SG email builder that handles image attachment correctly to allow inline images. """

        ############# FROM SendGridBackend._build_sg_mail: ############################################################
        mail = Mail()
        from_name, from_email = rfc822.parseaddr(email.from_email)
        # Python sendgrid client should improve
        # sendgrid/helpers/mail/mail.py:164
        if not from_name:
            from_name = None
        mail.set_from(Email(from_email, from_name))
        mail.set_subject(email.subject)

        personalization = Personalization()
        for e in email.to:
            personalization.add_to(Email(e))
        for e in email.cc:
            personalization.add_cc(Email(e))
        for e in email.bcc:
            personalization.add_bcc(Email(e))
        personalization.set_subject(email.subject)
        mail.add_content(Content("text/plain", email.body))
        if isinstance(email, EmailMultiAlternatives):
            for alt in email.alternatives:
                if alt[1] == "text/html":
                    mail.add_content(Content(alt[1], alt[0]))
        elif email.content_subtype == "html":
            mail.contents = []
            mail.add_content(Content("text/plain", " "))
            mail.add_content(Content("text/html", email.body))

        if hasattr(email, "categories"):
            for c in email.categories:
                mail.add_category(Category(c))

        if hasattr(email, "custom_args"):
            for k, v in email.custom_args.items():
                mail.add_custom_arg(CustomArg(k, v))

        if hasattr(email, "template_id"):
            mail.set_template_id(email.template_id)
            if hasattr(email, "substitutions"):
                for key, value in email.substitutions.items():
                    personalization.add_substitution(Substitution(key, value))

        # SendGrid does not support adding Reply-To as an extra
        # header, so it needs to be manually removed if it exists.
        reply_to_string = ""
        for key, value in email.extra_headers.items():
            if key.lower() == "reply-to":
                reply_to_string = value
            else:
                mail.add_header({key: value})
        # Note that if you set a "Reply-To" header *and* the reply_to
        # attribute, the header's value will be used.
        if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to:
            # SendGrid only supports setting Reply-To to a single address.
            # See https://github.com/sendgrid/sendgrid-csharp/issues/339.
            reply_to_string = email.reply_to[0]
        # Determine whether reply_to contains a name and email address, or
        # just an email address.
        if reply_to_string:
            reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string)
            if reply_to_name and reply_to_email:
                mail.set_reply_to(Email(reply_to_email, reply_to_name))
            elif reply_to_email:
                mail.set_reply_to(Email(reply_to_email))

        ########################### CUSTOM  HANDLING OF ATTACHMENTS ####################################################
        for (index, attachment) in enumerate(email.attachments):
            if isinstance(attachment, MIMEBase):
                attach = Attachment()

                # Re-encode into base64 to avoid newlines; then send JSON-serializable utf-8 format.
                attach.set_content(
                    str(base64.b64encode(attachment.get_payload(decode=True)), "utf-8")
                )

                # Add Content-ID header to allow use of images via src="cid:..."
                content_id_values = attachment.get_all("Content-ID")
                if not content_id_values:
                    content_id = "attachment-%05d" % (index + 1)
                else:
                    content_id = content_id_values[0]
                attach.set_content_id(content_id)

                # Add filename, which is required by SendGrid for all attachments
                filename_values = attachment.get_all("Filename")
                if filename_values:
                    attach.set_filename(filename_values[0])
                else:
                    attach.set_filename(content_id)

                # Add Content-Disposition so we can use 'inline' to show images within body of email
                disposition_values = attachment.get_all("Content-Disposition")
                if disposition_values:
                    attach.set_disposition(disposition_values[0])

                mail.add_attachment(attach)
            elif isinstance(attachment, tuple):
                # Leave as is except assume we're using version 3+ of sgbackend
                attach = Attachment()
                attach.set_filename(attachment[0])
                base64_attachment = base64.b64encode(attachment[1])
                attach.set_content(str(base64_attachment, "utf-8"))
                attach.set_type(attachment[2])
                mail.add_attachment(attach)

        ############# FROM SendGridBackend._build_sg_mail: #############################################################
        mail.add_personalization(personalization)
        return mail.get()