Example #1
0
    def send(self, to=[], *args, **kwargs):
        """
        Sends a notification email to users. Note the use of str formatting.
        """
        # format the body text to include all kwargs
        email_body = self.body.format(**kwargs)

        # form the html template and it's context into a html str
        html_template = get_template(self.template)
        html_context = Context({'obj': self, 'settings': settings})
        html_context.update(kwargs)
        html_content = html_template.render(html_context)

        # initiates the email message and attaches the html alternative
        email_msg = EmailMultiAlternatives(
            subject=self.subject,
            body=email_body,
            from_email=settings.FROM_EMAIL,
            to=to
        )
        email_msg.attach_alternative(html_content, "text/html")

        # if the send fails return false
        try:
            if settings.DEBUG:
                print email_msg.message()
            else:
                email_msg.send(fail_silently=False)
            return True
        except:
            return False
Example #2
0
File: tests.py Project: 6ft/django
    def test_encoding(self):
        """
        Regression for #12791 - Encode body correctly with other encodings
        than utf-8
        """
        email = EmailMessage('Subject', 'Firstname Sürname is a great guy.', '*****@*****.**', ['*****@*****.**'])
        email.encoding = 'iso-8859-1'
        message = email.message()
        self.assertMessageHasHeaders(message, {
            ('MIME-Version', '1.0'),
            ('Content-Type', 'text/plain; charset="iso-8859-1"'),
            ('Content-Transfer-Encoding', 'quoted-printable'),
            ('Subject', 'Subject'),
            ('From', '*****@*****.**'),
            ('To', '*****@*****.**')})
        self.assertEqual(message.get_payload(), 'Firstname S=FCrname is a great guy.')

        # Make sure MIME attachments also works correctly with other encodings than utf-8
        text_content = 'Firstname Sürname is a great guy.'
        html_content = '<p>Firstname Sürname is a <strong>great</strong> guy.</p>'
        msg = EmailMultiAlternatives('Subject', text_content, '*****@*****.**', ['*****@*****.**'])
        msg.encoding = 'iso-8859-1'
        msg.attach_alternative(html_content, "text/html")
        payload0 = msg.message().get_payload(0)
        self.assertMessageHasHeaders(payload0, {
            ('MIME-Version', '1.0'),
            ('Content-Type', 'text/plain; charset="iso-8859-1"'),
            ('Content-Transfer-Encoding', 'quoted-printable')})
        self.assertTrue(payload0.as_bytes().endswith(b'\n\nFirstname S=FCrname is a great guy.'))
        payload1 = msg.message().get_payload(1)
        self.assertMessageHasHeaders(payload1, {
            ('MIME-Version', '1.0'),
            ('Content-Type', 'text/html; charset="iso-8859-1"'),
            ('Content-Transfer-Encoding', 'quoted-printable')})
        self.assertTrue(payload1.as_bytes().endswith(b'\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>'))
Example #3
0
    def test_encoding(self):
        """
        Regression for #12791 - Encode body correctly with other encodings
        than utf-8
        """
        email = EmailMessage("Subject", "Firstname Sürname is a great guy.", "*****@*****.**", ["*****@*****.**"])
        email.encoding = "iso-8859-1"
        message = email.message()
        self.assertTrue(
            message.as_string().startswith(
                'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: [email protected]\nTo: [email protected]'
            )
        )
        self.assertEqual(message.get_payload(), "Firstname S=FCrname is a great guy.")

        # Make sure MIME attachments also works correctly with other encodings than utf-8
        text_content = "Firstname Sürname is a great guy."
        html_content = "<p>Firstname Sürname is a <strong>great</strong> guy.</p>"
        msg = EmailMultiAlternatives("Subject", text_content, "*****@*****.**", ["*****@*****.**"])
        msg.encoding = "iso-8859-1"
        msg.attach_alternative(html_content, "text/html")
        self.assertEqual(
            msg.message().get_payload(0).as_string(),
            'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nFirstname S=FCrname is a great guy.',
        )
        self.assertEqual(
            msg.message().get_payload(1).as_string(),
            'Content-Type: text/html; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>',
        )
Example #4
0
File: tests.py Project: 6ft/django
 def test_safe_mime_multipart(self):
     """
     Make sure headers can be set with a different encoding than utf-8 in
     SafeMIMEMultipart as well
     """
     headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"}
     subject, from_email, to = 'hello', '*****@*****.**', '"Sürname, Firstname" <*****@*****.**>'
     text_content = 'This is an important message.'
     html_content = '<p>This is an <strong>important</strong> message.</p>'
     msg = EmailMultiAlternatives('Message from Firstname Sürname', text_content, from_email, [to], headers=headers)
     msg.attach_alternative(html_content, "text/html")
     msg.encoding = 'iso-8859-1'
     self.assertEqual(msg.message()['To'], '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <*****@*****.**>')
     self.assertEqual(msg.message()['Subject'], '=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=')
Example #5
0
 def test_safe_mime_multipart(self):
     """
     Make sure headers can be set with a different encoding than utf-8 in
     SafeMIMEMultipart as well
     """
     headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"}
     subject, from_email, to = "hello", "*****@*****.**", '"Sürname, Firstname" <*****@*****.**>'
     text_content = "This is an important message."
     html_content = "<p>This is an <strong>important</strong> message.</p>"
     msg = EmailMultiAlternatives("Message from Firstname Sürname", text_content, from_email, [to], headers=headers)
     msg.attach_alternative(html_content, "text/html")
     msg.encoding = "iso-8859-1"
     self.assertEqual(msg.message()["To"], "=?iso-8859-1?q?S=FCrname=2C_Firstname?= <*****@*****.**>")
     self.assertEqual(msg.message()["Subject"].encode(), u"=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=")
def request_feedback_email(to_email, connector_name, link):
    subject, from_email, to = "I'd like to make better introductions for you", '%s via introduction.es <*****@*****.**>' % connector_name, to_email
    text_content = "%s wants to know how the introduction went.\n\nDid it lead to something already or is it still building?\n%s\n-%s" % (connector_name, link, connector_name)
    html_content = "<p>%s want's to know how the introduction went.</p><p>Did it lead to something already or is it still building?</p><p><a href=\"%s\">%s</a></p><p>-%s" % (connector_name, link, link, connector_name)
    msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
    msg.attach_alternative(html_content, "text/html")
    logger.debug("trying to send message to %s about %s " % (msg.to, msg.subject))
    logger.debug(msg.message())
    try:
        msg.send()
    except Exception, error:
        logger.debug("Couldn't send the mail for %s" % error)
        logger.debug(msg.subject)
        logger.debug(msg.recipients())
        logger.debug(msg.message())
Example #7
0
    def test_image(self):
        relfilename = 'static/dummy.png'
        filename = os.path.join(os.path.dirname(__file__), relfilename)
        imagefile = ImageFile(open(filename, 'rb'), name=relfilename)
        template = get_template('image.html', using='post_office')
        body = template.render({'imgsrc': imagefile})
        self.assertHTMLEqual(body, """
<h3>Testing image attachments</h3>
<img src="cid:f5c66340b8af7dc946cd25d84fdf8c90" width="200" />
""")
        subject = "[Django Post-Office unit tests] attached image"
        msg = EmailMultiAlternatives(subject, body, to=['*****@*****.**'])
        template.attach_related(msg)
        # this message can be send by email
        parts = msg.message().walk()
        part = next(parts)
        self.assertIsInstance(part, SafeMIMEMultipart)
        part = next(parts)
        self.assertIsInstance(part, SafeMIMEText)
        self.assertEqual(part.get_payload(), body)
        part = next(parts)
        self.assertIsInstance(part, MIMEImage)
        self.assertEqual(part.get_content_type(), 'image/png')
        self.assertEqual(part['Content-Disposition'], 'inline; filename="f5c66340b8af7dc946cd25d84fdf8c90"')
        if six.PY3:
            # self.assertEqual(part.get_content_disposition(), 'inline') uncomment after dropping support for Python-3.4
            self.assertEqual(part.get_filename(), 'f5c66340b8af7dc946cd25d84fdf8c90')
        self.assertEqual(part['Content-ID'], '<f5c66340b8af7dc946cd25d84fdf8c90>')
Example #8
0
 def test_mixed(self):
     body = "Testing mixed text and html attachments"
     html, attached_images = render_to_string('image.html', {'imgsrc': 'dummy.png'}, using='post_office')
     subject = "[django-SHOP unit tests] attached image"
     msg = EmailMultiAlternatives(subject, body, to=['*****@*****.**'])
     msg.attach_alternative(html, 'text/html')
     for attachment in attached_images:
         msg.attach(attachment)
     msg.mixed_subtype = 'related'
     # this message can be send by email
     parts = msg.message().walk()
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEMultipart)
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEMultipart)
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEText)
     self.assertEqual(part.get_content_type(), 'text/plain')
     self.assertHTMLEqual(part.get_payload(), body)
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEText)
     self.assertEqual(part.get_content_type(), 'text/html')
     self.assertHTMLEqual(part.get_payload(), html)
     part = next(parts)
     self.assertIsInstance(part, MIMEImage)
     self.assertEqual(part.get_content_type(), 'image/png')
Example #9
0
    def test_html(self):
        template = get_template('image.html', using='post_office')
        body = template.render({'imgsrc': 'dummy.png'})
        self.assertHTMLEqual(body, """
<h3>Testing image attachments</h3>
<img src="cid:f5c66340b8af7dc946cd25d84fdf8c90" width="200" />
""")
        subject = "[Django Post-Office unit tests] attached image"
        msg = EmailMultiAlternatives(subject, body, to=['*****@*****.**'])
        template.attach_related(msg)
        msg.content_subtype = 'html'
        self.assertEqual(msg.mixed_subtype, 'related')
        # this message can be send by email
        parts = msg.message().walk()
        part = next(parts)
        self.assertIsInstance(part, SafeMIMEMultipart)
        part = next(parts)
        self.assertIsInstance(part, SafeMIMEText)
        self.assertHTMLEqual(part.get_payload(), body)
        part = next(parts)
        self.assertIsInstance(part, MIMEImage)
        self.assertEqual(part.get_content_type(), 'image/png')
        self.assertEqual(part['Content-Disposition'], 'inline; filename="f5c66340b8af7dc946cd25d84fdf8c90"')
        if six.PY3:
            # self.assertEqual(part.get_content_disposition(), 'inline') uncomment after dropping support for Python-3.4
            self.assertEqual(part.get_filename(), 'f5c66340b8af7dc946cd25d84fdf8c90')
        self.assertEqual(part['Content-ID'], '<f5c66340b8af7dc946cd25d84fdf8c90>')
Example #10
0
    def mime_message(self):
        from ..utils import replace_cid_and_change_headers

        html, text, inline_headers = replace_cid_and_change_headers(
            self.body,
            self.original_message_id
        )

        email = EmailMultiAlternatives(
            self.subject,
            text,  # stripped from html
            self.send_from.to_header(),
            to=self.to,
            bcc=self.bcc,
            headers={}
        )

        email.attach_alternative(html, mimetype='text/html')
        email_message = email.message()

        try:
            add_attachments_to_email(self, email_message, inline_headers)
        except IOError:
            raise

        return email_message
Example #11
0
    def _send_email(self, subject, body, comm):
        """Send the message as an email"""

        from_addr = self.get_mail_id()
        cc_addrs = self.get_other_emails()
        from_email = '%s@%s' % (from_addr, settings.MAILGUN_SERVER_NAME)
        msg = EmailMultiAlternatives(
            subject=subject,
            body=body,
            from_email=from_email,
            to=[self.email],
            bcc=cc_addrs + ['*****@*****.**'],
            headers={
                'Cc': ','.join(cc_addrs),
                'X-Mailgun-Variables': {'comm_id': comm.pk}
            }
        )
        msg.attach_alternative(linebreaks(escape(body)), 'text/html')
        # atach all files from the latest communication
        for file_ in comm.files.all():
            name = file_.name()
            content = file_.ffile.read()
            mimetype, _ = mimetypes.guess_type(name)
            if mimetype and mimetype.startswith('text/'):
                enc = chardet.detect(content)['encoding']
                content = content.decode(enc)
            msg.attach(name, content)

        msg.send(fail_silently=False)

        # update communication
        comm.set_raw_email(msg.message())
        comm.delivered = 'email'
Example #12
0
def create_msg(delivery, mail_account, email, exception=False, test=False, ):

    """ did - Delivery id """
    did = get_div(delivery=delivery)
    headers = {'X-Delivery-id': did}
    """ eid - Email id """
    eid = get_eid(email=email.now_email)
    headers['X-Email-id'] = get_eid(email=email.now_email)
    """ mid - Message id """
    headers['X-Message-id'] = get_mid(div=did, eid=eid)
    """ Reply-To + Return-Path """
    headers['Return-Path'] = mail_account.get_return_path_subscribe
    headers['Reply-To'] = mail_account.get_return_path_subscribe

    message_kwargs = {
        'subject': u'test - {}'.format(delivery.subject) if test else delivery.subject,
        'body': strip_tags(parsing(value=delivery.html, key=email.key, ), ),
        'headers': headers,
        'from_email': formataddr((u'Интернет магаизн Keksik', mail_account.email)),
        'to': [mail_account.email if exception else email.now_email.email, ],
    }

    message = EmailMultiAlternatives(**message_kwargs)
    message.attach_alternative(parsing(value=delivery.html, key=email.key, ), 'text/html')

    return message.message()
Example #13
0
 def test_attachments(self):
     """Regression test for #9367"""
     headers = {
         "Date": "Fri, 09 Nov 2001 01:08:47 -0000",
         "Message-ID": "foo"
     }
     subject, from_email, to = 'hello', '*****@*****.**', '*****@*****.**'
     text_content = 'This is an important message.'
     html_content = '<p>This is an <strong>important</strong> message.</p>'
     msg = EmailMultiAlternatives(subject,
                                  text_content,
                                  from_email, [to],
                                  headers=headers)
     msg.attach_alternative(html_content, "text/html")
     msg.attach("an attachment.pdf",
                b"%PDF-1.4.%...",
                mimetype="application/pdf")
     msg_bytes = msg.message().as_bytes()
     message = message_from_bytes(msg_bytes)
     self.assertTrue(message.is_multipart())
     self.assertEqual(message.get_content_type(), 'multipart/mixed')
     self.assertEqual(message.get_default_type(), 'text/plain')
     payload = message.get_payload()
     self.assertEqual(payload[0].get_content_type(),
                      'multipart/alternative')
     self.assertEqual(payload[1].get_content_type(), 'application/pdf')
Example #14
0
    def test_image(self):
        relfilename = 'static/dummy.png'
        filename = os.path.join(os.path.dirname(__file__), relfilename)
        imagefile = ImageFile(open(filename, 'rb'), name=relfilename)
        template = get_template('image.html', using='post_office')
        body = template.render({'imgsrc': imagefile})
        self.assertHTMLEqual(
            body, """
<h3>Testing image attachments</h3>
<img src="cid:f5c66340b8af7dc946cd25d84fdf8c90" width="200" />
""")
        subject = "[Django Post-Office unit tests] attached image"
        msg = EmailMultiAlternatives(subject, body, to=['*****@*****.**'])
        template.attach_related(msg)
        # this message can be send by email
        parts = msg.message().walk()
        part = next(parts)
        self.assertIsInstance(part, SafeMIMEMultipart)
        part = next(parts)
        self.assertIsInstance(part, SafeMIMEText)
        self.assertEqual(part.get_payload(), body)
        part = next(parts)
        self.assertIsInstance(part, MIMEImage)
        self.assertEqual(part.get_content_type(), 'image/png')
        self.assertEqual(
            part['Content-Disposition'],
            'inline; filename="f5c66340b8af7dc946cd25d84fdf8c90"')
        self.assertEqual(part.get_content_disposition(), 'inline')
        self.assertEqual(part.get_filename(),
                         'f5c66340b8af7dc946cd25d84fdf8c90')
        self.assertEqual(part['Content-ID'],
                         '<f5c66340b8af7dc946cd25d84fdf8c90>')
Example #15
0
File: send.py Project: wcirillo/ten
 def message(self):
     """ Calls django's message method and then cleans up the header context.
     so that the CC'd addresses do not appear in the TO list (and the TO list
     remains unique.
     """
     msg = EmailMultiAlternatives.message(self)
     return process_message(msg)
Example #16
0
def initialise_email(bookmark, campaign_source):
    campaign_name = "monthly alert %s" % date.today().strftime("%Y-%m-%d")
    email_id = "/email/%s/%s/%s" % (campaign_name, campaign_source,
                                    bookmark.id)
    if isinstance(bookmark, NCSOConcessionBookmark):
        subject_prefix = "Your update about "
    else:
        subject_prefix = "Your monthly update about "
    msg = EmailMultiAlternatives(
        truncate_subject(subject_prefix, bookmark.name),
        "...placeholder...",
        settings.DEFAULT_FROM_EMAIL,
        [bookmark.user.email],
    )
    metadata = {
        "subject": msg.subject,
        "campaign_name": campaign_name,
        "campaign_source": campaign_source,
        "email_id": email_id,
    }
    msg.metadata = metadata
    msg.qs = ga_tracking_qs(metadata)
    # Set the message id now, so we can reuse it
    msg.extra_headers = {"message-id": msg.message()["message-id"]}
    return msg
Example #17
0
 def test_mixed(self):
     body = "Testing mixed text and html attachments"
     html, attached_images = render_to_string('image.html',
                                              {'imgsrc': 'dummy.png'},
                                              using='post_office')
     subject = "[django-SHOP unit tests] attached image"
     msg = EmailMultiAlternatives(subject, body, to=['*****@*****.**'])
     msg.attach_alternative(html, 'text/html')
     for attachment in attached_images:
         msg.attach(attachment)
     msg.mixed_subtype = 'related'
     # this message can be send by email
     parts = msg.message().walk()
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEMultipart)
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEMultipart)
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEText)
     self.assertEqual(part.get_content_type(), 'text/plain')
     self.assertHTMLEqual(part.get_payload(), body)
     part = next(parts)
     self.assertIsInstance(part, SafeMIMEText)
     self.assertEqual(part.get_content_type(), 'text/html')
     self.assertHTMLEqual(part.get_payload(), html)
     part = next(parts)
     self.assertIsInstance(part, MIMEImage)
     self.assertEqual(part.get_content_type(), 'image/png')
Example #18
0
    def send_service_email_bilingual(self,
                                     context,
                                     from_mailbox,
                                     to,
                                     cc,
                                     in_reply_to_message=None,
                                     reply_to_address=None):
        subject = build_subject(self.bilingual_subject, context)
        email_message = EmailMultiAlternatives(
            from_email=from_mailbox.from_email,
            to=to,
            cc=cc,
            subject=subject,
            body=self.render_plain_bilingual(context),
            reply_to=reply_to_address)
        email_message.attach_alternative(self.render_html_bilingual(context),
                                         'text/html')

        if in_reply_to_message:
            in_reply_to_message.reply(
                email_message
            )  # sets in-reply-to header & records this outgoing message and sends it
        else:
            email_message.send()
            from_mailbox.record_outgoing_message(
                email.message_from_string(email_message.message().as_string()))
Example #19
0
def send_email(recipient, subject, template, ctx, type, from_email='noreply', reply_to=None, to_email=None):
    """ To send emails to admin account set recipient=None """
    # TODO: generate unsubscribe link with hash (page with confirmation); default place for it in base template
    context = project_settings()
    context.update(ctx)
    context['recipient'] = recipient
    html = render_to_string(template, context)

    # TODO: convert html to text
    # TODO: replace <a href="url">text</a> with 'text url', no GA tracking in it
    text = html

    name = str(recipient.user_id) if recipient else 'grakon'
    hash = hashlib.md5(name+' '+str(datetime.now())).hexdigest()[:20]

    params = urlencode({'mh': hash, 'utm_campaign': type, 'utm_medium': 'email', 'utm_source': 'main'})

    xml = fromstring(html)
    for a in xml.findall('.//a'):
        url = a.get('href')
        if url.startswith(settings.URL_PREFIX):
            # If hash is inside url - move it to the end of the newly generated link
            if '#' in url:
                start, end = url.split('#')
                url = start + ('&' if '?' in url else '?') + params + '#' + end
            else:
                url += ('&' if '?' in url else '?') + params

        a.set('href', url)

    img1x1 = xml.find(".//img[@id='img1x1']")
    if img1x1 is not None:
        img1x1.set('src', img1x1.get('src')+'?mh='+hash)

    html = tostring(xml)

    from_str = u'%s <%s>' % settings.EMAILS[from_email]
    if to_email is None:
        to_email = recipient.user.email if recipient else settings.ADMIN_EMAIL
    # TODO: check that email has appropriate format (like no dot at the end)

    headers = {}
    if reply_to:
        headers['Reply-To'] = reply_to

    msg = EmailMultiAlternatives(subject, text, from_str, [to_email], headers=headers)
    msg.attach_alternative(html, "text/html")

    message = msg.message().as_string()

    # TODO: set priority
    email = Email(recipient=recipient, hash=hash, type=type, raw_msg=message, from_email=from_email,
            to_email=to_email, priority=0)
    email.save()

    send_email_task(email) # TODO: run it in celery (use select_related)
Example #20
0
    def send_email(self,
                   user,
                   from_email,
                   reply_to_email,
                   to_person,
                   subject,
                   html_content=None,
                   text_content=None,
                   attachments=[]):
        """
        @param attachments a list of MIMEBase objects
        """
        total_emails_sent = 0
        total_emails_failed = 0
        to_email = "{} {} <{}>".format(to_person.first_name,
                                       to_person.last_name, to_person.email)
        headers = {}
        if reply_to_email:
            headers['Reply-To'] = reply_to_email
        email_message = EmailMultiAlternatives(subject,
                                               text_content,
                                               from_email, [to_email],
                                               headers=headers)
        if html_content:
            email_message.attach_alternative(html_content, "text/html")
            email_message.mixed_subtype = 'related'

        # attachements
        for attachment in attachments:
            email_message.attach(attachment)

        # Record the email
        email_record = EmailRecord(
            subject=subject,
            message=email_message.message(),
            from_email=from_email,
            to_email=to_person.email,
            recipient=to_person,
            sender=user,
        )
        email_record.save()

        # Send
        try:
            email_message.send(fail_silently=False)
            email_record.status = 'sent'
            email_record.save()
            total_emails_sent += 1
        except SMTPException:
            email_record.statis = 'failed'
            email_record.save()
            total_emails_failed += 1
        return total_emails_sent
Example #21
0
    def test_encoding(self):
        """
        Regression for #12791 - Encode body correctly with other encodings
        than utf-8
        """
        email = EmailMessage('Subject', 'Firstname Sürname is a great guy.',
                             '*****@*****.**', ['*****@*****.**'])
        email.encoding = 'iso-8859-1'
        message = email.message()
        self.assertMessageHasHeaders(
            message, {('MIME-Version', '1.0'),
                      ('Content-Type', 'text/plain; charset="iso-8859-1"'),
                      ('Content-Transfer-Encoding', 'quoted-printable'),
                      ('Subject', 'Subject'), ('From', '*****@*****.**'),
                      ('To', '*****@*****.**')})
        self.assertEqual(message.get_payload(),
                         'Firstname S=FCrname is a great guy.')

        # Make sure MIME attachments also works correctly with other encodings than utf-8
        text_content = 'Firstname Sürname is a great guy.'
        html_content = '<p>Firstname Sürname is a <strong>great</strong> guy.</p>'
        msg = EmailMultiAlternatives('Subject', text_content,
                                     '*****@*****.**', ['*****@*****.**'])
        msg.encoding = 'iso-8859-1'
        msg.attach_alternative(html_content, "text/html")
        payload0 = msg.message().get_payload(0)
        self.assertMessageHasHeaders(
            payload0, {('MIME-Version', '1.0'),
                       ('Content-Type', 'text/plain; charset="iso-8859-1"'),
                       ('Content-Transfer-Encoding', 'quoted-printable')})
        self.assertTrue(payload0.as_bytes().endswith(
            b'\n\nFirstname S=FCrname is a great guy.'))
        payload1 = msg.message().get_payload(1)
        self.assertMessageHasHeaders(
            payload1, {('MIME-Version', '1.0'),
                       ('Content-Type', 'text/html; charset="iso-8859-1"'),
                       ('Content-Transfer-Encoding', 'quoted-printable')})
        self.assertTrue(payload1.as_bytes().endswith(
            b'\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>')
                        )
Example #22
0
    def create_msg(self, ):
        message_kwargs = {
            'from_email': formataddr(
                (u'Интернет магаизн Keksik', self.get_sender_email()), ),
            'to': [self.recipient.email, ],
            'headers': self.headers,
            'subject': u'test - {}'.format(self.subject) if self.test else self.subject,
            'body': strip_tags(self.body_finished, ),
        }

        message = EmailMultiAlternatives(**message_kwargs)
        message.attach_alternative(content=self.body_finished, mimetype='text/html', )

        return message.message()
Example #23
0
def send_mail(from_email: str, to: dict, subject: str, body: str, ):

    message = EmailMultiAlternatives(from_email=from_email, to=to, subject=subject, body=body, )

    connection_params = {'local_hostname': 'mail-proxy.keksik.com.ua', }

    try:
        connection = SMTP_SSL(
            host=settings.SEND_SMS_MAIL_ACCOUNT['server_smtp'],
            port=settings.SEND_SMS_MAIL_ACCOUNT['port_smtp'],
            **connection_params)

        if settings.SEND_SMS_MAIL_ACCOUNT['username'] \
                and settings.SEND_SMS_MAIL_ACCOUNT['password']:
            connection.login(
                settings.SEND_SMS_MAIL_ACCOUNT['username'],
                settings.SEND_SMS_MAIL_ACCOUNT['password'],
            )
            connection.ehlo()

    except (SMTPException, SMTPServerDisconnected) as e:
        logger.error('Exception(SMTPException, SMTPServerDisconnected): %s' % e)
        return False

    except socket.error as e:
        logger.info('Exception(socket.error): %s' % e)
        return False

    try:
        # (Python3) msg --> convert to bytes
        connection.sendmail(from_addr=formataddr(('Asterisk Keksik', '*****@*****.**',), ),
                            to_addrs=[formataddr(('Менеджер магазина Keksik', '*****@*****.**',), ), ],
                            msg=message.message().as_string().encode(), )
        connection.quit()

        # Если мы письмо отправили то возвращаем True
        return True

    except SMTPSenderRefused as e:
        logger.info('SMTPSenderRefused: %s' % e)

    except SMTPDataError as e:
        logger.info('SMTPDataError: %s| messages: %s| smtp_code: %s| smtp_error: %s| args: %s' %
                    (e, e.message, e.smtp_code, e.smtp_error, e.args), )

    except Exception as e:
        logger.info('Exception1: %s' % e)

    # Если письмо не ушло то возвращаем False
    return False
Example #24
0
    def create_msg(self, ):
        message_kwargs = {
            'from_email': formataddr(
                (u'Интернет магаизн Keksik', self.get_sender_email()), ),
            'to': [self.recipient.email, ],
            'headers': self.headers,
            'subject': u'test - {}'.format(self.subject) if self.test else self.subject,
            'body': strip_tags(self.body_finished, ),
        }

        message = EmailMultiAlternatives(**message_kwargs)
        message.attach_alternative(content=self.body_finished, mimetype='text/html', )

        return message.message()
Example #25
0
 def test_safe_mime_multipart(self):
     """
     Make sure headers can be set with a different encoding than utf-8 in
     SafeMIMEMultipart as well
     """
     headers = {
         "Date": "Fri, 09 Nov 2001 01:08:47 -0000",
         "Message-ID": "foo"
     }
     from_email, to = '*****@*****.**', '"Sürname, Firstname" <*****@*****.**>'
     text_content = 'This is an important message.'
     html_content = '<p>This is an <strong>important</strong> message.</p>'
     msg = EmailMultiAlternatives('Message from Firstname Sürname',
                                  text_content,
                                  from_email, [to],
                                  headers=headers)
     msg.attach_alternative(html_content, "text/html")
     msg.encoding = 'iso-8859-1'
     self.assertEqual(
         msg.message()['To'],
         '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <*****@*****.**>')
     self.assertEqual(msg.message()['Subject'],
                      '=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=')
Example #26
0
    def get_email_bytes(self, context, recipients=None):
        if recipients is None:
            if context.get('request'):
                recipients = [context['request'].user.email]

        content = self.get_email_content(context, preview=True)
        email = EmailMultiAlternatives(
            content.subject, content.text,
            settings.DEFAULT_FROM_EMAIL, recipients
        )
        email.attach_alternative(
            content.html,
            "text/html"
        )
        return email.message().as_bytes()
Example #27
0
    def send_delayed_email(self, comm, **kwargs):
        """Send the message as an email"""

        from_email, _ = EmailAddress.objects.get_or_create(
            email=self.get_request_email(), )

        body = self.render_msg_body(comm=comm,
                                    reply_link=True,
                                    switch=kwargs.get('switch'),
                                    appeal=kwargs.get('appeal'))

        email_comm = EmailCommunication.objects.create(
            communication=comm,
            sent_datetime=timezone.now(),
            from_email=from_email,
        )
        email_comm.to_emails.add(self.email)
        email_comm.cc_emails.set(self.cc_emails.all())

        # if we are using celery email, we want to not use it here, and use the
        # celery email backend directly.  Otherwise just use the default email backend
        backend = getattr(settings, 'CELERY_EMAIL_BACKEND',
                          settings.EMAIL_BACKEND)
        with get_connection(backend) as email_connection:
            msg = EmailMultiAlternatives(
                subject=comm.subject,
                body=body,
                from_email=str(from_email),
                to=[str(self.email)],
                cc=[
                    str(e) for e in self.cc_emails.all() if e.status == 'good'
                ],
                bcc=['*****@*****.**'],
                headers={
                    'X-Mailgun-Variables': {
                        'email_id': email_comm.pk
                    },
                },
                connection=email_connection,
            )
            msg.attach_alternative(linebreaks(escape(body)), 'text/html')
            # atach all files from the latest communication
            comm.attach_files_to_email(msg)

            msg.send(fail_silently=False)

        email_comm.set_raw_email(msg.message())
Example #28
0
    def _send_email(self, comm, **kwargs):
        """Send the message as an email"""

        from_addr = self.get_mail_id()
        from_email, _ = EmailAddress.objects.get_or_create(
            email='%s@%s' % (from_addr, settings.MAILGUN_SERVER_NAME), )

        context = {
            'request': self,
            'show_all_comms': kwargs.get('show_all_comms'),
            'reply_link': self.get_agency_reply_link(self.email.email),
        }
        body = render_to_string(
            'text/foia/request_email.txt',
            context,
        )

        self.status = self._sent_status(
            kwargs.get('appeal'),
            kwargs.get('thanks'),
        )

        email_comm = EmailCommunication.objects.create(
            communication=comm,
            sent_datetime=datetime.now(),
            from_email=from_email,
        )
        email_comm.to_emails.add(self.email)
        email_comm.cc_emails.set(self.cc_emails.all())
        msg = EmailMultiAlternatives(subject=comm.subject,
                                     body=body,
                                     from_email=str(from_email),
                                     to=[str(self.email)],
                                     cc=[str(e) for e in self.cc_emails.all()],
                                     bcc=['*****@*****.**'],
                                     headers={
                                         'X-Mailgun-Variables': {
                                             'email_id': email_comm.pk
                                         },
                                     })
        msg.attach_alternative(linebreaks(escape(body)), 'text/html')
        # atach all files from the latest communication
        comm.attach_files(msg)

        msg.send(fail_silently=False)

        email_comm.set_raw_email(msg.message())
Example #29
0
    def _send_email(self, comm, **kwargs):
        """Send the message as an email"""

        from_email, _ = EmailAddress.objects.get_or_create(
            email=self.get_request_email(),
        )

        body = self.render_msg_body(
            comm=comm,
            reply_link=True,
            switch=kwargs.get('switch'),
            appeal=kwargs.get('appeal')
        )

        self.status = self._sent_status(
            kwargs.get('appeal'),
            kwargs.get('thanks'),
        )

        email_comm = EmailCommunication.objects.create(
            communication=comm,
            sent_datetime=timezone.now(),
            from_email=from_email,
        )
        email_comm.to_emails.add(self.email)
        email_comm.cc_emails.set(self.cc_emails.all())
        msg = EmailMultiAlternatives(
            subject=comm.subject,
            body=body,
            from_email=str(from_email),
            to=[str(self.email)],
            cc=[str(e) for e in self.cc_emails.all() if e.status == 'good'],
            bcc=['*****@*****.**'],
            headers={
                'X-Mailgun-Variables': {
                    'email_id': email_comm.pk
                },
            }
        )
        msg.attach_alternative(linebreaks(escape(body)), 'text/html')
        # atach all files from the latest communication
        comm.attach_files_to_email(msg)

        msg.send(fail_silently=False)

        email_comm.set_raw_email(msg.message())
Example #30
0
 def test_attachments(self):
     """Regression test for #9367"""
     headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"}
     subject, from_email, to = "hello", "*****@*****.**", "*****@*****.**"
     text_content = "This is an important message."
     html_content = "<p>This is an <strong>important</strong> message.</p>"
     msg = EmailMultiAlternatives(subject, text_content, from_email, [to], headers=headers)
     msg.attach_alternative(html_content, "text/html")
     msg.attach("an attachment.pdf", "%PDF-1.4.%...", mimetype="application/pdf")
     msg_str = msg.message().as_string()
     message = email.message_from_string(msg_str)
     self.assertTrue(message.is_multipart())
     self.assertEqual(message.get_content_type(), "multipart/mixed")
     self.assertEqual(message.get_default_type(), "text/plain")
     payload = message.get_payload()
     self.assertEqual(payload[0].get_content_type(), "multipart/alternative")
     self.assertEqual(payload[1].get_content_type(), "application/pdf")
Example #31
0
File: tests.py Project: 6ft/django
 def test_attachments(self):
     """Regression test for #9367"""
     headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"}
     subject, from_email, to = 'hello', '*****@*****.**', '*****@*****.**'
     text_content = 'This is an important message.'
     html_content = '<p>This is an <strong>important</strong> message.</p>'
     msg = EmailMultiAlternatives(subject, text_content, from_email, [to], headers=headers)
     msg.attach_alternative(html_content, "text/html")
     msg.attach("an attachment.pdf", b"%PDF-1.4.%...", mimetype="application/pdf")
     msg_bytes = msg.message().as_bytes()
     message = message_from_bytes(msg_bytes)
     self.assertTrue(message.is_multipart())
     self.assertEqual(message.get_content_type(), 'multipart/mixed')
     self.assertEqual(message.get_default_type(), 'text/plain')
     payload = message.get_payload()
     self.assertEqual(payload[0].get_content_type(), 'multipart/alternative')
     self.assertEqual(payload[1].get_content_type(), 'application/pdf')
Example #32
0
def test_newsletter(request, pk):
    newsletter = get_object_or_404(models.Newsletter, pk=pk)
    if request.method == 'POST':
        form = forms.TestEmailForm(request.POST)
    else:
        form = forms.TestEmailForm()

    if request.method == 'POST':
        if form.is_valid():
            address = form.cleaned_data['email']
            subscriptions_url = request.build_absolute_uri(reverse(view_home))
            subject = "[Test] {}".format(newsletter.subject)
            html_content, attachments = newsletter.render(
                '', True, subscriptions_url)

            h = html2text.HTML2Text()
            h.ignore_images = True
            text_content = h.handle(html_content)
            from_email = getattr(settings, 'HEMRES_FROM_ADDRESS',
                                 '*****@*****.**')

            msg = EmailMultiAlternatives(subject=subject,
                                         body=text_content,
                                         from_email=from_email,
                                         to=[address])
            msg.attach_alternative(html_content, "text/html")
            msg.mixed_subtype = 'related'
            for a in attachments:
                msg.attach(a)

            if getattr(settings, 'SKIP_EMAIL', False):
                return HttpResponse(msg.message().as_string(),
                                    content_type="message")
            else:
                msg.send()
                content_type = ContentType.objects.get_for_model(
                    newsletter.__class__)
                return redirect(
                    reverse('admin:%s_%s_changelist' %
                            (content_type.app_label, content_type.model)))

    return render(request, 'hemres/test_newsletter.html', {
        'form': form,
        'nieuwsbrief': str(newsletter)
    })
Example #33
0
    def test_encoding(self):
        """
        Regression for #12791 - Encode body correctly with other encodings
        than utf-8
        """
        email = EmailMessage('Subject', 'Firstname Sürname is a great guy.', '*****@*****.**', ['*****@*****.**'])
        email.encoding = 'iso-8859-1'
        message = email.message()
        self.assertTrue(message.as_string().startswith('Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: [email protected]\nTo: [email protected]'))
        self.assertEqual(message.get_payload(), 'Firstname S=FCrname is a great guy.')

        # Make sure MIME attachments also works correctly with other encodings than utf-8
        text_content = 'Firstname Sürname is a great guy.'
        html_content = '<p>Firstname Sürname is a <strong>great</strong> guy.</p>'
        msg = EmailMultiAlternatives('Subject', text_content, '*****@*****.**', ['*****@*****.**'])
        msg.encoding = 'iso-8859-1'
        msg.attach_alternative(html_content, "text/html")
        self.assertEqual(msg.message().get_payload(0).as_string(), 'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nFirstname S=FCrname is a great guy.')
        self.assertEqual(msg.message().get_payload(1).as_string(), 'Content-Type: text/html; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>')
Example #34
0
    def create_message(self, mail_address, encoding="utf-8",):
        # TODO: encoding depends on to.email domain actually
        message_id = uuid.uuid1().hex

        EmailMultiAlternatives.encoding = encoding

        message = EmailMultiAlternatives(
            subject=self.subject,
            body=self.rendered_message(mail_address),
            from_email=self.sender.address,
            to=[mail_address.email],            # list of tuple
            headers={'Message-ID': message_id},
        )

        if self.html:
            message.attach_alternative(
                self.rendered_html(mail_address), "text/html")

        return message.message()
Example #35
0
def make_email_with_campaign(bookmark, campaign_source):
    campaign_name = "monthly alert %s" % date.today().strftime("%Y-%m-%d")
    email_id = "/email/%s/%s/%s" % (campaign_name, campaign_source,
                                    bookmark.id)
    subject_prefix = 'Your monthly update about '
    msg = EmailMultiAlternatives(
        truncate_subject(subject_prefix, bookmark.name),
        "This email is only available in HTML", settings.SUPPORT_EMAIL,
        [bookmark.user.email])
    metadata = {
        "subject": msg.subject,
        "campaign_name": campaign_name,
        "campaign_source": campaign_source,
        "email_id": email_id
    }
    msg.metadata = metadata
    msg.qs = ga_tracking_qs(metadata)
    # Set the message id now, so we can reuse it
    msg.extra_headers = {'message-id': msg.message()['message-id']}
    return msg
Example #36
0
    def send_email(self, user, from_email, reply_to_email, to_person, subject, html_content = None, text_content = None, attachments = []):
        """
        @param attachments a list of MIMEBase objects
        """
        total_emails_sent  = 0
        total_emails_failed = 0
        to_email = "{} {} <{}>".format(to_person.first_name, to_person.last_name, to_person.email)
        headers = {}
        if reply_to_email:
            headers['Reply-To'] = reply_to_email
        email_message = EmailMultiAlternatives(subject, text_content, from_email, [to_email], headers=headers)
        if html_content:
            email_message.attach_alternative(html_content, "text/html")
            email_message.mixed_subtype = 'related'

        # attachements
        for attachment in attachments:
            email_message.attach(attachment)

        # Record the email
        email_record = EmailRecord(
            subject=subject,
            message = email_message.message(),
            from_email = from_email,
            to_email = to_person.email,
            recipient = to_person,
            sender = user,
        )
        email_record.save()

        # Send
        try:
            email_message.send(fail_silently=False)
            email_record.status = 'sent'
            email_record.save()
            total_emails_sent += 1
        except SMTPException:
            email_record.statis = 'failed'
            email_record.save()
            total_emails_failed += 1
        return total_emails_sent
Example #37
0
def create_msg(
    delivery,
    mail_account,
    email,
    exception=False,
    test=False,
):
    """ did - Delivery id """
    did = get_div(delivery=delivery)
    headers = {'X-Delivery-id': did}
    """ eid - Email id """
    eid = get_eid(email=email.now_email)
    headers['X-Email-id'] = get_eid(email=email.now_email)
    """ mid - Message id """
    headers['X-Message-id'] = get_mid(div=did, eid=eid)
    """ Reply-To + Return-Path """
    headers['Return-Path'] = mail_account.get_return_path_subscribe
    headers['Reply-To'] = mail_account.get_return_path_subscribe

    message_kwargs = {
        'subject':
        u'test - {}'.format(delivery.subject) if test else delivery.subject,
        'body': strip_tags(parsing(
            value=delivery.html,
            key=email.key,
        ), ),
        'headers': headers,
        'from_email': formataddr(
            (u'Интернет магаизн Keksik', mail_account.email)),
        'to': [
            mail_account.email if exception else email.now_email.email,
        ],
    }

    message = EmailMultiAlternatives(**message_kwargs)
    message.attach_alternative(parsing(
        value=delivery.html,
        key=email.key,
    ), 'text/html')

    return message.message()
Example #38
0
def create_greetings(from_email, to_email):
    text_template = get_template('alumni/mails/greetings.txt')
    html_template = get_template('alumni/mails/greetings.html')

    var1 = u'aaaa'
    var2 = u'bbbb'

    ctx = Context({'var1': var1, 'var2': var2})

    subject = 'Hello'

    text_content = text_template.render(Context())
    html_content = html_template.render(Context())

    msg = EmailMultiAlternatives(
        subject, text_content,
        from_email,
        [to_email])

    msg.attach_alternative(html_content, "text/html")
    return msg.message()
Example #39
0
    def create_msg(self, ):
        """ Формирование "Конечного" письма """

        from applications.delivery2.utils import remove_style_tags
        from django.utils.html import strip_tags

        self.strip_tags_body_finished = strip_tags(remove_style_tags(html=self.body_finished))

        message_kwargs = {
            'from_email': formataddr(
                (u'Интернет магазин Keksik', self.get_sender_email(), ), ),
            'to': [self.recipient.email, ],
            'headers': self.headers,
            'subject': u'test - {subject}'.format(subject=self.subject_str) if self.delivery.test_send else self.subject_str,
            'body': self.strip_tags_body_finished,
        }

        message = EmailMultiAlternatives(**message_kwargs)
        message.attach_alternative(content=self.body_finished, mimetype='text/html', )

        self.message = message.message()
Example #40
0
    def send(self, email, context, log=True):
        if self.skip(email):
            return None

        key = self.generate_key(email)
        context["key"] = key
        context["unsubscribe"] = self.unsubscribe_url(email, key)

        headers = self.headers(context["unsubscribe"])
        headers["Reply-To"] = self.reply_to

        msg = EmailMultiAlternatives(
            self.subject, self.render(self.text_tpl, context), self.frm, [email], headers=headers
        )

        if self.html_tpl:
            msg.attach_alternative(self.render(self.html_tpl, context, True), "text/html")

        self.connection.send(email, msg.message().as_string())

        if log:
            self.log_send(email)
Example #41
0
def send_html_email(subject, to, html=None, template=None, context=None,
        cc=None, bcc=None, from_email=None):
    """
    This generic HTML email sending function will before the following before
    sending:
        1) add site and static specific URLs to the template rendering context
        2) convert internal CSS to inline CSS
        3) convert the HTML to plain text for a normal body attachment
    """
    if html is None and template is None:
        raise TypeError('html or template is needed')
    if html is not None and template is not None:
        raise TypeError('only provide html or a template, not both')
    if isinstance(to, basestring):
        to = [to,]
    if isinstance(cc, basestring):
        cc = [cc,]
    if isinstance(bcc, basestring):
        bcc = [bcc,]
    if from_email is None or settings.DEBUG:
        from_email = settings.DEFAULT_FROM_EMAIL
    if template is not None:
        if context is None:
            context = {}
        context.update({
            'STATIC_URL': settings.STATIC_URL,
            'SITE_DOMAIN': settings.SITE_DOMAIN,
        })
        html = render_to_string(template, context)
    inline_html = premailer.transform(html)
    converter = html2text.HTML2Text()
    converter.ignore_images = True
    text = converter.handle(inline_html)
    msg = EmailMultiAlternatives(subject=subject, body=text,
            from_email=from_email, to=to, cc=cc, bcc=bcc)
    msg.attach_alternative(inline_html, 'text/html')
    LOGGER.info('sending email... [%s]' % msg.message().items())
    msg.send()
Example #42
0
    def mime_message(self):
        from ..utils import replace_cid_and_change_headers

        html, text, inline_headers = replace_cid_and_change_headers(
            self.body, self.original_message_id)

        email = EmailMultiAlternatives(
            self.subject,
            text,  # stripped from html
            self.send_from.to_header(),
            to=self.to,
            bcc=self.bcc,
            headers={})

        email.attach_alternative(html, mimetype='text/html')
        email_message = email.message()

        try:
            add_attachments_to_email(self, email_message, inline_headers)
        except IOError:
            raise

        return email_message
Example #43
0
    def test_email_sent(self):
        """Check if email is being sent"""

        client = Client()
        #self.url = reverse('contact_app:contact_us')

        # client.login(username='******', password='******')
        client.login(username='******', password='******')

        response = self.client.post(
            reverse('contact_app:contact_us'), {
                'subject': 'letter_subject',
                'user_text': 'test text',
                'from_email': "*****@*****.**",
                'recipient_list': ['*****@*****.**']
            })

        msg = Em.message(self).encode('utf-8')
        self.assertEqual(msg.get('subject'), 'letter_subject')
        self.assertEqual(msg.get('from_email'), '*****@*****.**')
        self.assertEqual(
            msg.get_payload(),
            'test text',
        )
Example #44
0
    def send(self, email, context, log=True):
        if self.skip(email):
            return None

        key = self.generate_key(email)
        context['key'] = key
        context['unsubscribe'] = self.unsubscribe_url(email, key)

        headers = self.headers(context['unsubscribe'])
        headers['Reply-To'] = self.reply_to

        msg = EmailMultiAlternatives(self.subject,
                                     self.render(self.text_tpl, context),
                                     self.frm, [email],
                                     headers=headers)

        if self.html_tpl:
            msg.attach_alternative(self.render(self.html_tpl, context, True),
                                   "text/html")

        self.connection.send(email, msg.message().as_string())

        if log:
            self.log_send(email)
    def handle(self, **options):
        txt_mail_template = loader.get_template("mail/overview.txt")
        html_mail_template = loader.get_template("mail/overview.html")

        image_name = None
        image_content = None
        if options["header_banner"]:
            with open(options["header_banner"], "rb") as fp:
                image_content = fp.read()
            image_name = basename(options["header_banner"])

        shared_context = {
            "image_name": image_name,
            "report_login_url": settings.SITE_URL,
            "institution": settings.NOTIFICATION_INSTITUTION
        }
        for user in User.objects.all():
            context = shared_context.copy()
            context["full_name"] = user.get_full_name() or user.username

            # XXX: this is pretty much all cannibalised from MainPageView
            roles = user.roles.select_subclasses() or [DefaultRole(user=user)]
            results = DocumentReport.objects.none()
            for role in roles:
                results |= role.filter(DocumentReport.objects.all())

            if not results:
                print("Nothing for user {0}".format(user.username))
                continue

            # Filter out anything we don't know how to show in the UI
            data_results = []
            for result in results:
                if result.data and "matches" in result.data and result.data[
                        "matches"]:
                    mm = result.data["matches"]
                    renderable_matches = [
                        cm for cm in mm["matches"]
                        if cm["rule"]["type"] in RENDERABLE_RULES
                    ]
                    if renderable_matches:
                        mm["matches"] = renderable_matches
                        data_results.append(result)

            match_counts = {s: 0 for s in list(Sensitivity)}
            for dr in data_results:
                if dr.matches:
                    match_counts[dr.matches.sensitivity] += 1
            context["matches"] = {
                k.presentation: v
                for k, v in match_counts.items()
                if k != Sensitivity.INFORMATION
            }.items()
            context["match_count"] = sum([
                v for k, v in match_counts.items()
                if k != Sensitivity.INFORMATION
            ])

            msg = EmailMultiAlternatives(
                "Der ligger uhåndterede matches i OS2datascanner",
                txt_mail_template.render(context), settings.DEFAULT_FROM_EMAIL,
                [user.email])
            msg.attach_alternative(html_mail_template.render(context),
                                   "text/html")
            if image_name and image_content:
                mime_image = MIMEImage(image_content)
                mime_image.add_header("Content-Location", image_name)
                msg.attach(mime_image)

            if options["dry_run"]:
                print(user)
                print(msg.message().as_string())
                print("--")
            else:
                try:
                    msg.send()
                except Exception as ex:
                    print(
                        "Exception occured while trying to send an email: {0}".
                        format(ex))
Example #46
0
def send_mail(
    from_email,
    to,
    subject,
    body,
):

    message = EmailMultiAlternatives(
        from_email=from_email,
        to=to,
        subject=subject,
        body=body,
    )

    connection_params = {
        'local_hostname': 'mail-proxy.keksik.com.ua',
    }

    try:
        connection = SMTP_SSL(
            host=settings.SEND_SMS_MAIL_ACCOUNT['server_smtp'],
            port=settings.SEND_SMS_MAIL_ACCOUNT['port_smtp'],
            **connection_params)

        if settings.SEND_SMS_MAIL_ACCOUNT['username'] \
                and settings.SEND_SMS_MAIL_ACCOUNT['password']:
            connection.login(
                settings.SEND_SMS_MAIL_ACCOUNT['username'],
                settings.SEND_SMS_MAIL_ACCOUNT['password'],
            )
            connection.ehlo()

    except (SMTPException, SMTPServerDisconnected) as e:
        logger.error('Exception(SMTPException, SMTPServerDisconnected): %s' %
                     e)
        return False

    except socket.error as e:
        logger.info('Exception(socket.error): %s' % e)
        return False

    try:
        # (Python3) msg --> convert to bytes
        connection.sendmail(
            from_addr=formataddr((
                'Asterisk Keksik',
                '*****@*****.**',
            ), ),
            to_addrs=[
                formataddr((
                    'Менеджер магазина Keksik',
                    '*****@*****.**',
                ), ),
            ],
            msg=message.message().as_string().encode(),
        )
        connection.quit()

        # Если мы письмо отправили то возвращаем True
        return True

    except SMTPSenderRefused as e:
        logger.info('SMTPSenderRefused: %s' % e)

    except SMTPDataError as e:
        logger.info(
            'SMTPDataError: %s| messages: %s| smtp_code: %s| smtp_error: %s| args: %s'
            % (e, e.message, e.smtp_code, e.smtp_error, e.args), )

    except Exception as e:
        logger.info('Exception1: %s' % e)

    # Если письмо не ушло то возвращаем False
    return False
Example #47
0
    def msg_with_gpg(self, site, frm, subject, text, html, payload=None, quiet=True):
        """
        :param site: Matching dict from XMPP_HOSTS.
        :param text: The text part of the message.
        :param html: The HTML part of the message.
        :param quiet: If False, raise an Exception, the default is only to log errors.
        """
        if payload is None:
            payload = json.loads(self.payload)

        gpg = settings.GPG
        signer = site.get('GPG_FINGERPRINT')
        sign = False
        encrypt = False

        recipient = payload.get('email', self.user.email)
        gpg_fingerprint = payload.get('gpg_fingerprint')

        # encrypt only if the user has a fingerprint
        if gpg_fingerprint:
            # Receive key of recipient. We don't care about the result, because user might have
            # already uploaded it.
            gpg.recv_keys(settings.GPG_KEYSERVER, gpg_fingerprint)

            # ... instead, we check if it is a known key after importing
            if gpg_fingerprint not in [k['fingerprint'] for k in gpg.list_keys()]:
                if quiet is True:
                    log.warn('%s: Unknown GPG fingerprint for %s', site['DOMAIN'], self.user.jid)
                else:
                    raise GpgFingerprintError(_("GPG key not found on keyservers."))
            else:
                encrypt = True

        elif 'gpg_key' in payload:
            # No fingerprint but a gpg_key in the payload, so import the key. This should only be
            # happening if we're using Celery.
            log.warn('Importing gpg key in msg_with_gpg()')

            imported = settings.GPG.import_keys(payload['gpg_key'])
            if not imported.fingerprints:
                if quiet is True:
                    log.warn("No imported keys: %s\ndata: %s", imported.stderr, payload['gpg_key'])
                else:
                    raise GpgKeyError(_("GPG key could not be imported."))
            else:
                gpg_fingerprint = imported.fingerprints[0]
                payload['gpg_fingerprint'] = gpg_fingerprint
                encrypt = True

                # save the payload to make sure it will always have one during confirmation
                self.payload = json.dumps(payload)
                self.save()

        # sign only if the user has fingerprint or signing is forced
        if not signer:
            log.warn('%s: No GPG key configured, not signing', site['DOMAIN'])
        elif signer not in [k['fingerprint'] for k in gpg.list_keys(True)]:
            log.warn('%s: %s: secret key not found, not signing', site['DOMAIN'], signer)
            signer = None
        elif gpg and (gpg_fingerprint or settings.FORCE_GPG_SIGNING):
            sign = True

        log.info('sign, encrypt: %s/%s', sign, encrypt)
        if not (sign or encrypt):  # shortcut if no GPG is used
            return self.msg_without_gpg(subject, frm, recipient, text, html)

        msg = EmailMultiAlternatives(subject, from_email=frm, to=[recipient])
        mime_text = MIMEText(text, _charset='utf-8')
        mime_html = MIMEText(html, _subtype='html', _charset='utf-8')
        body = MIMEMultipart(_subtype='alternative', _subparts=[mime_text, mime_html])

        if sign and not encrypt:  # only sign the message
            signed_body = gpg.sign(body.as_string(), keyid=signer, detach=True)
            if not signed_body.data:
                if quiet is True:
                   log.warn('GPG returned no data when signing')
                   log.warn(signed_body.stderr)
                   return self.msg_without_gpg(subject, frm, recipient, text, html)
                else:
                   raise GpgError("Error signing message: %s" % signed_body.stderr)

            sig = MIMEBase(_maintype='application', _subtype='pgp-signature', name='signature.asc')
            sig.set_payload(signed_body.data)
            sig.add_header('Content-Description', 'OpenPGP digital signature')
            sig.add_header('Content-Disposition', 'attachment; filename="signature.asc"')
            del sig['Content-Transfer-Encoding']

            msg.mixed_subtype = 'signed'
            msg.attach(body)
            msg.attach(sig)
            protocol = 'application/pgp-signature'
        elif encrypt:  # encrypt and (possibly) sign
            encrypted_body = gpg.encrypt(body.as_string(), [gpg_fingerprint], sign=signer,
                                         always_trust=True)
            if not encrypted_body.data:
                if quiet is True:
                    log.warn('GPG returned no data when signing/encrypting')
                    log.warn(encrypted_body.stderr)
                    return self.msg_without_gpg(subject, frm, recipient, text, html)
                else:
                   raise GpgError("Error encrypting message: %s" % encrypted_body.stderr)

            encrypted = MIMEBase(_maintype='application', _subtype='octed-stream',
                                 name='encrypted.asc')
            encrypted.set_payload(encrypted_body.data)
            encrypted.add_header('Content-Description', 'OpenPGP encrypted message')
            encrypted.add_header('Content-Disposition', 'inline; filename="encrypted.asc"')
            msg.mixed_subtype = 'encrypted'
            msg.attach(pgp_version)
            msg.attach(encrypted)
            protocol = 'application/pgp-encrypted'

        # We wrap the message() method to set Content-Type parameters (set_params())
        _msg = msg.message

        def message():
            msg = _msg()
            msg.set_param('protocol', protocol)
            return msg
        msg.message = message

        return msg
Example #48
0
def send_received_sms(*args, **kwargs):

    try:
        smses = SMS.objects.filter(direction=1, is_send=False, )
    except SMS.DoesNotExist:
        return False

    print len(smses)
    for sms in smses:

        #try:
        #    message = sms.message.encode('cp1252', 'replace')
        #except UnicodeDecodeError as e:
        #    print e
        #    message = sms.message

        sms.message = base64.b64decode(sms.message_b64).decode('utf8')

        message = u'Направление: {direction}\nОт аббонента: {from_phone_char}\nАббоненту: {to_phone_char}\n'\
                  u'Дата и Время Получения: {received_at}\nСообщение:\n{message}'\
            .format(
                direction=SMS.DIRECTION[sms.direction-1][1],
                from_phone_char=sms.from_phone_char,
                to_phone_char=sms.to_phone_char,
                received_at=sms.received_at,
                message=sms.message,
            )

        message_kwargs = {
            'from_email': formataddr((u'Телефонная станция Asterisk Keksik', '*****@*****.**', ), ),
            'to': [formataddr((u'Менеджер магазина Keksik', '*****@*****.**', ), ), ],
            #'headers': self.headers,
            'subject': u'Направение SMS: {direction} | от аббонента: {from_phone_char} | к аббоненту: {to_phone_char} | дата и время получения сообщения: {received_at}'\
                .format(
                    direction=SMS.DIRECTION[sms.direction-1][1],
                    from_phone_char=sms.from_phone_char,
                    to_phone_char=sms.to_phone_char,
                    received_at=sms.received_at,
                ),
            'body': message,
        }
        message = EmailMultiAlternatives(**message_kwargs)

        connection_params = {'local_hostname': 'mail-proxy.keksik.com.ua', }

        try:
            connection = SMTP_SSL(
                host=proj.settings.SEND_SMS_MAIL_ACCOUNT['server_smtp'],
                port=proj.settings.SEND_SMS_MAIL_ACCOUNT['port_smtp'],
                **connection_params)

            if proj.settings.SEND_SMS_MAIL_ACCOUNT['username']\
                    and proj.settings.SEND_SMS_MAIL_ACCOUNT['password']:
                connection.login(
                    proj.settings.SEND_SMS_MAIL_ACCOUNT['username'],
                    proj.settings.SEND_SMS_MAIL_ACCOUNT['password'],
                )
                connection.ehlo()

        except (SMTPException, SMTPServerDisconnected) as e:
            print('Exception(SMTPException, SMTPServerDisconnected): ', e)
            return False

        except socket.error as e:
            print('Exception(socket.error): ', e)
            return False

        try:
            connection.sendmail(
                from_addr=formataddr((u'Asterisk Keksik', '*****@*****.**', ), ),
                to_addrs=[formataddr((u'Менеджер магазина Keksik', '*****@*****.**', ), ), ],
                msg=message.message().as_string(), )
            connection.quit()

        except SMTPSenderRefused as e:
            print('SMTPSenderRefused: ', e)

        except SMTPDataError as e:
            print('SMTPDataError: ', e, ' messages: ', e.message, ' smtp_code: ', e.smtp_code, 'smtp_error: ', e.smtp_error, ' args: ', e.args)

        except Exception as e:
            print('Exception1: ', e)

        sms.task_id = None
        sms.is_send = True
        sms.send_at = timezone.now()
        sms.save(skip_super_save=True, )

    return True, timezone.now(), '__name__: {0}'.format(str(__name__))
def send_email(to_email, subject, template, ctx, campaign='',
               from_email=settings.DEFAULT_FROM_EMAIL, reply_to=settings.DEFAULT_FROM_EMAIL):
    # TODO: generate unsubscribe link with hash (page with confirmation); default place for it in base template
    context = {
        'URL_PREFIX': settings.URL_PREFIX,
        'STATIC_URL': settings.STATIC_URL,
    }
    context.update(ctx)
    html = render_to_string(template, context)

    # TODO: convert html to text
    # TODO: replace <a href="url">text</a> with 'text (url)', no GA tracking in it
    text = html

    # Generate a unique hash used to track email opening
    hash = hashlib.md5(to_email+' '+str(timezone.now())).hexdigest()[:20]

    # GET parameters added to all internal urls
    data = {settings.HASH_GET_PARAMETER: hash}

    if settings.USE_EMAIL_GA and campaign:
        data['utm_campaign'] = campaign
        data['utm_medium'] = settings.EMAIL_GA_MEDUIM

    params = urlencode(data)

    # Add tracking GET parameters to all internal urls
    xml = BeautifulSoup(html, 'lxml')
    for a in xml.find_all('a'):
        url = a.get('href', '')
        if url.startswith(settings.URL_PREFIX):
            # If hash is inside url - move it to the end of the newly generated link
            if '#' in url:
                start, end = url.split('#')
                url = start + ('&' if '?' in url else '?') + params + '#' + end
            else:
                url += ('&' if '?' in url else '?') + params

        a['href'] = url

    # TODO: set redirects to track external links (optional - controlled by setting)

    # TODO: remove <html> and <body> tags
    html = str(xml)

    # Include 1x1 image for tracking email opening
    if settings.EMAIL_OPEN_TRACKING:
        html += '<img src="%s%s?%s=%s" width="1" height="1" />' % (
                settings.URL_PREFIX, reverse('img1x1'),
                settings.HASH_GET_PARAMETER, hash)

    #from_str = u'%s <%s>' % (from_name, from_email)
    # TODO: check that email has an appropriate format (like no dot at the end)

    headers = {}
    if reply_to:
        headers['Reply-To'] = reply_to

    # Generate email message with html and text
    msg = EmailMultiAlternatives(subject, text, from_email, [to_email], headers=headers)
    msg.attach_alternative(html, 'text/html')

    message = msg.message().as_string()

    email = Email(hash=hash, campaign=campaign, raw_msg=message,
                  from_email=from_email, to_email=to_email)
    email.save()

    email.send() # TODO: run it in celery (use select_related)
Example #50
0
    def msg_with_gpg(self,
                     site,
                     frm,
                     subject,
                     text,
                     html,
                     payload=None,
                     quiet=True):
        """
        :param site: Matching dict from XMPP_HOSTS.
        :param text: The text part of the message.
        :param html: The HTML part of the message.
        :param quiet: If False, raise an Exception, the default is only to log errors.
        """
        if payload is None:
            payload = json.loads(self.payload)

        gpg = settings.GPG
        signer = site.get('GPG_FINGERPRINT')
        sign = False
        encrypt = False

        recipient = payload.get('email', self.user.email)
        gpg_fingerprint = payload.get('gpg_fingerprint')

        # encrypt only if the user has a fingerprint
        if gpg_fingerprint:
            # Receive key of recipient. We don't care about the result, because user might have
            # already uploaded it.
            gpg.recv_keys(settings.GPG_KEYSERVER, gpg_fingerprint)

            # ... instead, we check if it is a known key after importing
            if gpg_fingerprint not in [
                    k['fingerprint'] for k in gpg.list_keys()
            ]:
                if quiet is True:
                    log.warn('%s: Unknown GPG fingerprint for %s',
                             site['DOMAIN'], self.user.jid)
                else:
                    raise GpgFingerprintError(
                        _("GPG key not found on keyservers."))
            else:
                encrypt = True

        elif 'gpg_key' in payload:
            # No fingerprint but a gpg_key in the payload, so import the key. This should only be
            # happening if we're using Celery.
            log.warn('Importing gpg key in msg_with_gpg()')

            imported = settings.GPG.import_keys(payload['gpg_key'])
            if not imported.fingerprints:
                if quiet is True:
                    log.warn("No imported keys: %s\ndata: %s", imported.stderr,
                             payload['gpg_key'])
                else:
                    raise GpgKeyError(_("GPG key could not be imported."))
            else:
                gpg_fingerprint = imported.fingerprints[0]
                payload['gpg_fingerprint'] = gpg_fingerprint
                encrypt = True

                # save the payload to make sure it will always have one during confirmation
                self.payload = json.dumps(payload)
                self.save()

        # sign only if the user has fingerprint or signing is forced
        if not signer:
            log.warn('%s: No GPG key configured, not signing', site['DOMAIN'])
        elif signer not in [k['fingerprint'] for k in gpg.list_keys(True)]:
            log.warn('%s: %s: secret key not found, not signing',
                     site['DOMAIN'], signer)
            signer = None
        elif gpg and (gpg_fingerprint or settings.FORCE_GPG_SIGNING):
            sign = True

        log.info('sign, encrypt: %s/%s', sign, encrypt)
        if not (sign or encrypt):  # shortcut if no GPG is used
            return self.msg_without_gpg(subject, frm, recipient, text, html)

        msg = EmailMultiAlternatives(subject, from_email=frm, to=[recipient])
        mime_text = MIMEText(text, _charset='utf-8')
        mime_html = MIMEText(html, _subtype='html', _charset='utf-8')
        body = MIMEMultipart(_subtype='alternative',
                             _subparts=[mime_text, mime_html])

        if sign and not encrypt:  # only sign the message
            signed_body = gpg.sign(body.as_string(), keyid=signer, detach=True)
            if not signed_body.data:
                if quiet is True:
                    log.warn('GPG returned no data when signing')
                    log.warn(signed_body.stderr)
                    return self.msg_without_gpg(subject, frm, recipient, text,
                                                html)
                else:
                    raise GpgError("Error signing message: %s" %
                                   signed_body.stderr)

            sig = MIMEBase(_maintype='application',
                           _subtype='pgp-signature',
                           name='signature.asc')
            sig.set_payload(signed_body.data)
            sig.add_header('Content-Description', 'OpenPGP digital signature')
            sig.add_header('Content-Disposition',
                           'attachment; filename="signature.asc"')
            del sig['Content-Transfer-Encoding']

            msg.mixed_subtype = 'signed'
            msg.attach(body)
            msg.attach(sig)
            protocol = 'application/pgp-signature'
        elif encrypt:  # encrypt and (possibly) sign
            encrypted_body = gpg.encrypt(body.as_string(), [gpg_fingerprint],
                                         sign=signer,
                                         always_trust=True)
            if not encrypted_body.data:
                if quiet is True:
                    log.warn('GPG returned no data when signing/encrypting')
                    log.warn(encrypted_body.stderr)
                    return self.msg_without_gpg(subject, frm, recipient, text,
                                                html)
                else:
                    raise GpgError("Error encrypting message: %s" %
                                   encrypted_body.stderr)

            encrypted = MIMEBase(_maintype='application',
                                 _subtype='octed-stream',
                                 name='encrypted.asc')
            encrypted.set_payload(encrypted_body.data)
            encrypted.add_header('Content-Description',
                                 'OpenPGP encrypted message')
            encrypted.add_header('Content-Disposition',
                                 'inline; filename="encrypted.asc"')
            msg.mixed_subtype = 'encrypted'
            msg.attach(pgp_version)
            msg.attach(encrypted)
            protocol = 'application/pgp-encrypted'

        # We wrap the message() method to set Content-Type parameters (set_params())
        _msg = msg.message

        def message():
            msg = _msg()
            msg.set_param('protocol', protocol)
            return msg

        msg.message = message

        return msg
Example #51
0
def send_email(to_email,
               subject,
               template,
               ctx,
               campaign='',
               from_email=settings.DEFAULT_FROM_EMAIL,
               reply_to=settings.DEFAULT_FROM_EMAIL):
    # TODO: generate unsubscribe link with hash (page with confirmation); default place for it in base template
    context = {
        'URL_PREFIX': settings.URL_PREFIX,
        'STATIC_URL': settings.STATIC_URL,
    }
    context.update(ctx)
    html = render_to_string(template, context)

    # TODO: convert html to text
    # TODO: replace <a href="url">text</a> with 'text (url)', no GA tracking in it
    text = html

    # Generate a unique hash used to track email opening
    hash = hashlib.md5(to_email + ' ' + str(timezone.now())).hexdigest()[:20]

    # GET parameters added to all internal urls
    data = {settings.HASH_GET_PARAMETER: hash}

    if settings.USE_EMAIL_GA and campaign:
        data['utm_campaign'] = campaign
        data['utm_medium'] = settings.EMAIL_GA_MEDUIM

    params = urlencode(data)

    # Add tracking GET parameters to all internal urls
    xml = BeautifulSoup(html, 'lxml')
    for a in xml.find_all('a'):
        url = a.get('href', '')
        if url.startswith(settings.URL_PREFIX):
            # If hash is inside url - move it to the end of the newly generated link
            if '#' in url:
                start, end = url.split('#')
                url = start + ('&' if '?' in url else '?') + params + '#' + end
            else:
                url += ('&' if '?' in url else '?') + params

        a['href'] = url

    # TODO: set redirects to track external links (optional - controlled by setting)

    # TODO: remove <html> and <body> tags
    html = str(xml)

    # Include 1x1 image for tracking email opening
    if settings.EMAIL_OPEN_TRACKING:
        html += '<img src="%s%s?%s=%s" width="1" height="1" />' % (
            settings.URL_PREFIX, reverse('img1x1'),
            settings.HASH_GET_PARAMETER, hash)

    #from_str = u'%s <%s>' % (from_name, from_email)
    # TODO: check that email has an appropriate format (like no dot at the end)

    headers = {}
    if reply_to:
        headers['Reply-To'] = reply_to

    # Generate email message with html and text
    msg = EmailMultiAlternatives(subject,
                                 text,
                                 from_email, [to_email],
                                 headers=headers)
    msg.attach_alternative(html, 'text/html')

    message = msg.message().as_string()

    email = Email(hash=hash,
                  campaign=campaign,
                  raw_msg=message,
                  from_email=from_email,
                  to_email=to_email)
    email.save()

    email.send()  # TODO: run it in celery (use select_related)
Example #52
0
def send_msg(**kwargs):
    session = kwargs['session']
    session_id = session.session_key
    compose = session['compose']
    email_field = session['email_field']
    total_emails = len(session['csv'])
    recipient = kwargs['row'][session['email_field']]

    ctx = Context(kwargs['row'])
    subject = Template(compose['subject']).render(ctx)
    txt_msg = Template(compose['txt_msg']).render(ctx)
    html_msg = Template(compose['html_msg']).render(ctx)
    msg = EmailMultiAlternatives(subject, txt_msg, compose['sender'],
                                 [recipient])
    msg.attach_alternative(html_msg, 'text/html')

    job = rq.get_current_job()
    job.meta['session_id'] = session_id
    job.save_meta()

    if kwargs['mode'] == 'google':
        msg_str = msg.message().as_string()
        raw_msg = base64.urlsafe_b64encode(msg_str.encode()).decode()

        response = requests.post(
            'https://www.googleapis.com/gmail/v1/users/me/messages/send',
            json={'raw': raw_msg},
            headers={
                'Authorization':
                'Bearer {0}'.format(session['smtp']['access_token']),
                'Content-Type':
                'application/json'
            })
        if not response.ok:
            status = response.content.decode()
            return status
    else:
        smtp = session['smtp']
        connection = {
            'host': smtp['host'],
            'port': smtp['port'],
            'username': smtp['username'],
            'password': smtp['password'],
            'use_tls': smtp['use_tls'],
        }

        msg.connection = get_connection(**connection)
        try:
            msg.send()
        except Exception as ex:
            status = ex.strerror
            return status

    idx = kwargs['idx']
    total_emails = len(session['csv'])

    status = _('{0}% sent.'.format((idx + 1) / total_emails * 100)) + '\r\n'
    status += _('Sent mail to {0}'.format(recipient)) + '\r\n'

    if idx + 1 == total_emails:
        queue_name = os.path.basename(settings.BASE_DIR)
        queue = django_rq.get_queue(queue_name)
        queue.enqueue(delete_session, session_id)
        status = True
    return status
Example #53
0
    def _send_email(self, show_all_comms=True):
        """Send an email of the request to its email address"""
        # self.email should be set before calling this method
        from muckrock.foia.tasks import send_fax

        from_addr = 'fax' if self.email.endswith(
            'faxaway.com') else self.get_mail_id()
        law_name = self.jurisdiction.get_law_name()
        if self.tracking_id:
            subject = 'RE: %s Request #%s' % (law_name, self.tracking_id)
        elif self.communications.count() > 1:
            subject = 'RE: %s Request: %s' % (law_name, self.title)
        else:
            subject = '%s Request: %s' % (law_name, self.title)

        # get last comm to set delivered and raw_email
        comm = self.communications.reverse()[0]

        if from_addr == 'fax':
            subject = 'MR#%s-%s - %s' % (self.pk, comm.pk, subject)
        # max database size
        subject = subject[:255]

        cc_addrs = self.get_other_emails()
        from_email = '%s@%s' % (from_addr, settings.MAILGUN_SERVER_NAME)
        # pylint:disable=attribute-defined-outside-init
        self.reverse_communications = self.communications.reverse()
        body = render_to_string('text/foia/request_email.txt', {
            'request': self,
            'show_all_comms': show_all_comms
        })
        body = unidecode(body) if from_addr == 'fax' else body
        msg = EmailMultiAlternatives(subject=subject,
                                     body=body,
                                     from_email=from_email,
                                     to=[self.email],
                                     bcc=cc_addrs +
                                     ['*****@*****.**'],
                                     headers={
                                         'Cc': ','.join(cc_addrs),
                                         'X-Mailgun-Variables': {
                                             'comm_id': comm.pk
                                         }
                                     })
        if from_addr != 'fax':
            msg.attach_alternative(linebreaks(escape(body)), 'text/html')
        # atach all files from the latest communication
        for file_ in self.communications.reverse()[0].files.all():
            msg.attach(file_.name(), file_.ffile.read())
        if from_addr == 'fax':
            send_fax.apply_async(args=[msg])
        else:
            msg.send(fail_silently=False)

        # update communication
        comm.set_raw_email(msg.message())
        comm.delivered = 'fax' if self.email.endswith(
            'faxaway.com') else 'email'
        comm.subject = subject
        comm.save()

        # unblock incoming messages if we send one out
        self.block_incoming = False
        self.save()