0

I have a Django project where I am working on an email client. I've decided to use python's IMAPClient instead of standard library's imaplib for getting access to the messages. Currently, I don't make use of python's email package to encode/decode responses received from IMAPClient, and I have a feeling that I manually implement things that should be handled by email.

Example code for downloading attachment:

def download_attachment(server, msgid, index, encoding):
    # index and encoding is known from previous analysis of bodystructure
    file_content = f_fetch(server, msgid, index)
    # the below code should be handled by email's message_from_bytes 
    # and subsequent get_payload(decode = True) function
    if encoding == 'base64':
        file_content = base64.b64decode(file_content)
    elif ...
    ...
    endif
    #writing file_content to a folder
    return

def f_fetch(server, msgid, index):
    if not index:
        index = '1'
    response = server.fetch(msgid, 'BODY[' + index + ']')
    key = ('BODY[' + index + ']').encode('utf-8')
    if type(msgid) is str:
        msgid = int(msgid)
    return response[msgid][key]

So the question is, how should I rewrite this code to make use of email. Specifically, what should I do with the response from IMAPClient to pass it to email's message_from_bytes() function?

Community
  • 1
  • 1
Edgar Navasardyan
  • 4,261
  • 8
  • 58
  • 121
  • If you want to use the email package, you probably should use directly imaplib, because IMAPClient has already parsed the message. – Serge Ballesta Aug 22 '17 at 11:30
  • @Serge, so does it mean that as long as I use IMAPClient, I should forget about `email` package ? – Edgar Navasardyan Aug 22 '17 at 11:33
  • Unsure of it (the reason why it is a comment and not an answer...). I do not use IMAPClient, but I thought one of its major interests is to parse the message. If you do not need that, I'm just unsure of how you use IMAPClient, and why it is better than imaplib. Sorry not to be able to help your more... – Serge Ballesta Aug 22 '17 at 11:43
  • Ok. Thank you for this ) – Edgar Navasardyan Aug 22 '17 at 11:44

1 Answers1

1

If you wish to parse an email using the email package's message_from_bytes() function then you need to give it the entire, raw email body. To get this, fetch using the RFC822 selector like this:

fetch_data = server.fetch(msgid, ['RFC822'])
parsed = email.message_from_bytes(fetch_data[msgid][b'RFC822'])

If you're pulling individual message parts/attachments from the IMAP server, then the server is effectively doing the parsing work for you and you don't need to use the email package's parser.

Menno Smits
  • 2,074
  • 1
  • 13
  • 12
  • Do I understand correctly that if my message contains some heavy attachment, say, a video file, then `RFC822` will download it all. So, if all the user wants to see is just the `plain text/HTML` of the message and the names of the attachment, then it's not optimal to download `RFC822`. – Edgar Navasardyan Aug 23 '17 at 07:31