How do you decode a binary encoded mail message in Python? - python

I'm writing a Google App engine app that processes incoming mail, and here's the code I'm currently using to process mail messages:
for content_type, body in email_bodies:
#8bit bug in mail messages - see bug report here
#http://code.google.com/p/googleappengine/issues/detail?id=2383
if body.encoding == '8bit':
body.encoding = '7bit'
#test for html content
if content_type == "text/html":
#parse html result
if content_type == "text/plain":
decoded_msg_body = body.decode()
However I just got a message that was using the binary encoding scheme, and when my program tried to process the message using body.decode(), I received a UnknownEncodingError. How should this program parse the binary content type? Also, how can I imitate this message type on my local version of GAE so I can debug and test it out?
I appreciate your help,
Kevin

Rather than reinventing the wheel, you should try Python's built in email parser.
http://docs.python.org/library/email.parser.html
It's designed to handle the lifting involved in getting all sorts of different email formats into a good Python object. Use it to do the parsing, and you'll get nicely predictable objects to work with.
The email module doesn't do message sending and receiving, it just helps put them together and parse them out.

Related

File from POST Request to MIMEBase

I'm currently trying to send mails with attachments.
However, I'm currently struggling to convert the file I'm supposed to receive.
Here's my request POST:
curl --form "file=#year.txt" http://localhost:8000/
I need to know how can I extract the file year.txt from my request, and then convert it to MIMEBase, so I can send it through EmailMessage.
file = request.POST.get('file')
email = EmailMessage(
subject,
content,
None,
['random#example.com'],
)
email.attach_file(file)
That'd be something like this; however, I'm not sure the process to follow. That's why I require your help.
EmailMessage does not support passing in the Subject etc. as arguments. Instead, you need something like
from email.message import EmailMessage
email = EmailMessage()
email["subject"] = subject
email["from"] = "you#example.org" # you need to pass in a sender too
email["to"] = "random#example.com"
email.set_content(content)
email.add_attachment(file, maintype="application", subtype="octet-stream")
If you have a more specific MIME type to use than the generic application/octet-stream, by all means use that instead. In this particular case, I guess text/plain would be correct and useful, but of course, that might not be applicable more generally, and really depends on your use case and application design.
See the examples from the email module documentation for variations and details.
Getting the generated message off your system is a separate topic which is often hard for beginners. If you run this in a place where you have an outgoing email server in the local network which doesn't require authentication, you should be able to simply create an smtplib.SMTP object and pass the message to its send_message method, but many real-world deployments have complications like requiring to authenticate to a remote server. There are, of course, many existing questions about that here, so please search before you ask a new question.

WSHttpBinding: Entropy.BinarySecret role in message encryption

I am writing a simple SOAP client application in Python.
WSDL file can be found here: https://clients.nationalmailing.com.au/ServiceTest/OrderService.svc?wsdl
Unfortunately the server declared usage of wsHttpBinding in its WSDL file and I had to learn how many troubles it brings to not-.NET developers.
I have working C# code (and it is pretty simple there) and used Fiddler to capture the traffic and analyze messages. Now I know the structure to follow. Client sends 2 subsequental messages.
I managed to create and send first request and receive a response from the server. BUT second request is a way more complex. I have found a library signxml which helped me to create <Signature> structure with all the fields that should present (as per captured traffic).
But the server continues to answer with "Error 500: An error occurred when verifying security for the message."
I realized that in the first message I put just random values for the following structure:
<s:Body>
<trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:TokenType>http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/sct</trust:TokenType>
<trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
<trust:Entropy>
<trust:BinarySecret
u:Id="uuid-0649fd7a-9ae2-4f9f-964c-e3aa5d68e8cd-1"
Type="http://docs.oasis-open.org/ws-sx/ws-trust/200512/Nonce">h/MaeQVSL5Br30Hnt/SAl274flYfZVZyx2Fri9zNuEY=</trust:BinarySecret>
</trust:Entropy>
<trust:KeySize>256</trust:KeySize>
</trust:RequestSecurityToken>
</s:Body>
The value of BinarySecret is just a random string encoded with Base64. I think this should be an issue on this stage. I also do not use the same parameters from server's response.
Could anyone explain how should I use Entropy.BinarySecret - should it take part in the calculations of Signature and how it is used?
Answering my own question. Yes, the issue was in improper usage of Entropy parameter.
To sign the message you need to generate a key, it consists of two parts (client entropy and server's entropy). They get combined with P_SHA1 algorithm into a key.
To anyone who find this post in the future: for Python have a look on signxml library and section 4 of ws-trust spec.

How to send JSON payload to RabbitMQ using the web plugin?

I have a RabbitMQ 3.4.2 instance with a web management plugin installed.
When I push to the message {'operationId': 194} to the queue using Python's kombu queue package, the message is read on the other end as a dictionary.
However, when I send the message using the web console:
I get the following error on the receiving end:
operation_id = payload['operationId']
TypeError: string indices must be integers
I have tried adding a content-type header and property, with no success.
Since the reader code is the same, it means that the web sender does not mark the sent message as a JSON / dictionary payload, and therefore it is read as a string on the other end.
Any idea how to mark a message as a JSON message using the RabbitMQ web console?
I had to use content_type instead of content-type (an underscore instead of a hyphen).
This is a pretty questionable design decision, because the standard everybody knows is content-type.
You need to de-serialize the output.
import json
payload = json.loads(payload)
operation_id = payload['operationId']
In addition {'operationId': 194} is not valid JSON. Although it looks like you use double quotes in the screenshot, but make sure you replace the single quotes with double quotes.
Edit:
So you are correct, kombu should handle this. Looking at the code it's likely that the header is case-sensitive. Change the properties header from Content-Type to content-type.

How To Create a draft email?

I want to write a python that can sends data to a draft message, but NOT Send the mail directly.
Situation:
I'm a 3D animator. After done some shots, we need to send email(not internet, just in our company) to Lighting Team.
So we have some mail form, but sometimes we need to fix some words manual(version,texture..etc).
like below:
Shot Name : XXXX_seqXXX_scXXX
File Locate(hair + cloth) : please import X:\XX\XX\XX\XXX_ABC.ma
File include:
XXX_hair **(use version 1)**
XXX_cloth
ZZZ_cloth **(No texture)**
any problem please tell me.
Thanks.
Ezylryb
Question is:
Now I can write into a file, but I don't know how to open mail software(win7 Livemail) and create a new mail has these content. I'm try to use smtplib, but it will send mail directly..
Could anyone help me??
Many Thanks!!!!
Ezylryb
==============================
Finally, I write HTML code into a .html file, and a eml file with email address + Title + CC, and use os.startfile to open both files.
And I can copy/paste to draft email ^O^.
Coz we need some chinese words, so use big5 code in eml, and use qupori module to decode MIME words to Chinese words in html file.
A "draft" is a feature which your email client (in this case Win7 livemail) implements by itself. It's more or less just an email in a mailbox that the client hasn't sent yet. Mail folders like your "outbox" etc. are similar.
It's not something that Python has access to. If the mail client uses a standard mailbox format, you might be able to create the email and write it into the mailbox using mailbox module. If not, the best you can do is to write out your draft email into a file and then open that in your mail client and manually edit it.

Pipe an email to a python script

I've set up inside of my CPanel to have all emails sent to x#x.com to be piped into a python script of mine. How would I go about having any attachments saved into a specific directory on the server and perhaps see the subject/message of the email itself?
You can use the email package to process MIME-formatted email messages. Use email.parser.FeedParser to parse the message and get back an email.message.Message object:
Treat it like a dictionary to get header fields like Subject.
Use is_multipart() to check whether it is multipart and therefore might have attachments (or it might just be a plain-text + HTML message).
Use the walk() method to recursively walk over all multipart submessages. Submessages with a Content-Disposition header starting with attachment are attachments, and you can get their contents using get_payload().

Categories

Resources