Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to handle Unicode in message body using API #78

Closed
jdotjdot opened this issue Jan 3, 2017 · 4 comments
Closed

Unable to handle Unicode in message body using API #78

jdotjdot opened this issue Jan 3, 2017 · 4 comments

Comments

@jdotjdot
Copy link

jdotjdot commented Jan 3, 2017

Sorry to be leaving you so many issues!

Looks like there's now an issue when sending messages at least with unicode characters in the body. The message I am sending usings django.template.Template to render a template to a string and then submit it as the message HTML body.

This problem goes away if you temporarily set sys.setdefaultencoding('utf8') (which you obviously shouldn't be doing).

Here is the traceback:

/Users/../utils/emails.pyc in send_html_email(subject, from_email, to_emails, reply_to, text_body, html_body, headers, tag, metadata, subaccount, attachments, send_in, extra_params, bcc)
    128             setattr(msg, key, value)
    129
--> 130     msg.send()
    131
    132

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/django/core/mail/message.pyc in send(self, fail_silently)
    340             # send to.
    341             return 0
--> 342         return self.get_connection(fail_silently).send_messages([self])
    343
    344     def attach(self, filename=None, content=None, mimetype=None):

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/django.pyc in send_messages(self, email_messages)
     55             client_created = self.open()
     56             prepared_messages = [self.prepare_message(message) for message in email_messages]
---> 57             response = self.client.emails.send_batch(*prepared_messages, TrackOpens=self.get_option('TRACK_OPENS'))
     58             msg_count = len(response)
     59             if client_created:

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in send_batch(self, *emails, **extra)
    322         :param extra: dictionary with extra arguments for every message in the batch.
    323         """
--> 324         return self.EmailBatch(*emails).send(**extra)
    325
    326     # NOTE. The following methods are included here to expose better interface without need to import relevant classes.

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in send(self, **extra)
    242         :rtype: `list`
    243         """
--> 244         emails = self.as_dict(**extra)
    245         responses = [self._manager._send_batch(*batch) for batch in chunks(emails, self.MAX_SIZE)]
    246         return sum(responses, [])

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in as_dict(self, **extra)
    220         :return: List of dictionaries.
    221         """
--> 222         return [self._construct_email(email, **extra) for email in self.emails]
    223
    224     def _construct_email(self, email, **extra):

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in _construct_email(self, email, **extra)
    229             email = Email(manager=self._manager, **email)
    230         elif isinstance(email, (MIMEText, MIMEMultipart)):
--> 231             email = Email.from_mime(email, self._manager)
    232         elif not isinstance(email, Email):
    233             raise ValueError

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in from_mime(cls, message, manager)
    178         """
    179         if isinstance(message, MIMEMultipart):
--> 180             text, html, attachments = deconstruct_multipart(message)
    181         else:
    182             text, html, attachments = message.get_payload(decode=True).decode(), None, []

/Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in deconstruct_multipart(message)
     85             text = part.get_payload(decode=True).decode()
     86         elif content_type == 'text/html':
---> 87             html = part.get_payload(decode=True).decode()
     88         elif content_type != 'multipart/alternative':
     89             attachments.append(part)

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 3495: ordinal not in range(128)

I'm currently getting around this with the following context manager, but obviously this cannot be the case long-term:

@contextlib.contextmanager
def set_default_encoding(encoding='ascii'):
    """\
    Temporarily set the default encoding within the span of the context.

    NOTE: Using `sys.setdefaultencoding()` is HIGHLY DISCOURAGED and this context
    manager should only be used when working with third party libraries that incorrectly
    handle unicode/strings/bytestrings and cannot easily be patched, updated, or worked around.
    """
    import sys
    reload(sys)
    original_encoding = sys.getdefaultencoding()
    sys.setdefaultencoding(encoding)
    yield
    sys.setdefaultencoding(original_encoding)
@Stranger6667
Copy link
Owner

Hello! No problem! :)
Could you, please, show what is the exact string, what was passed to Django's send_mail? I mean html_message argument

@Stranger6667
Copy link
Owner

Ah, I found the problem. I'll submit a fix today

@Stranger6667
Copy link
Owner

0.6.2 is on PyPI :) Thank you for the bug report

@Stranger6667
Copy link
Owner

@jdotjdot
If the problem persists, please, let me know :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants