Search code examples
pythongoogle-app-enginequoted-printable

How to properly decode Quoted Printable encoding in Django HTML Template


I have a Google app engine in python form submit that POSTS text to a server, and the text gets encoded with the encoding Quoted Printables. My code for POSTing is this:

<form action={{ upload_url }} method="post" enctype="multipart/form-data">
<div class="sigle-form"><textarea name="body" rows="5"></textarea></div>
<div class="sigle-form"><input name="file" type="file" /></div>
</form>

Then the result of the fetching self.request.get('body') will be encoded with the encoding Quoted Printables. I store this in text DB.textProperty() and later sends the text to a HTML template using Django. When i write out the variable using {{ body }}, the result is written with Quoted printable encoding, and it does not seem that there is a way of decoding this in the Django HTML template. Is there any way of encoding the text in the body thats sent on another way than with Quoted Printables? If not, how to decode this encoding in the Django HTML template?

The result for submiting the text "ÅØÆ" is encoded to " xdjG ", so the sum of the Quoted Prinables are somehow added togheter as well. This happens when more than one special character are present in the encoded text. An ordinary "ø" is encoded to =F8.

EDIT: I get this problem only in production, and this thread seems to talk about the same problem.

If anyone else here on Stack Overflow are doing form submit with blobs and åæøè characters, please respond to this thread on how you have solved it!


Solution

  • Ok, after two days working with this issue i finally resolved it. Its seemingly a bug with Google App Engine that makes the encoding f'ed up in production. When in production the text is sometimes encoded with Quoted Printable encoded, and some other times encoded with base64 encoding. Weird. Here is my solution:

    postBody = self.request.get('body')    
    postBody = postBody.encode('iso-8859-1')
    DEBUG = os.environ['SERVER_SOFTWARE'].startswith('Dev')
    if DEBUG:
        r.body = postBody
    else:
        postBody += "=" * ((4 - len(postBody) % 4) % 4)
        b64 = base64.urlsafe_b64decode(postBody)
    

    Though the resulting b64 can't be stored in the data storage because it's not ascii encoded

    'ascii' codec can't decode byte 0xe5 in position 5: ordinal not in range(128)