How to download all emails using FETCH over IMAP using pycurl

I'm trying to get all the emails in the IMAP directory using pycurl.

For example this way I get a list of directories:

import pycurl
import certifi

with open('mail.txt', 'wb') as f:
    c = pycurl.Curl()
    c.setopt(pycurl.CAINFO, certifi.where())
    c.setopt(c.URL, 'imaps://imap.example.com/')
    c.setopt(c.USERPWD, '[email protected]:password')
    c.setopt(c.WRITEDATA, f)
    c.perform()
    c.close()

Next, I need to get all the emails from each directory. This is done using the command FETCH 1:* With curl the command I need looks like this:

curl imaps://imap.example.com/ --user "[email protected]:password" -X "FETCH 1:* (BODY[TEXT])" --ssl --verbose

As far as I understand, the -X parameter in pycurl is POSTFIELDS

It turns out that the request of the above command with pycurl will be look like this:

with open('mail.txt', 'wb') as f:
    c = pycurl.Curl()
    c.setopt(pycurl.CAINFO, certifi.where())
    c.setopt(c.URL, 'imaps://imap.example.com/INBOX')
    c.setopt(c.USERPWD, '[email protected]:password')
    c.setopt(c.POSTFIELDS, 'FETCH 1:* (BODY[TEXT])')
    c.setopt(c.WRITEDATA, f)
    c.perform()
    c.close()

But this command does not work, and returns the same list of directories. If anyone has had a similar experience, please tell me what I'm doing wrong.

Author: Roman Isakov, 2020-08-08

1 answers

I found the answer to my own question. According to the libcurl API documentation, the -X parameter is not POSTFIELDS but CUSTOMREQUEST https://curl.haxx.se/libcurl/c/curl_easy_setopt.html

That is, the final code will look like this:

with open('mail.txt', 'wb') as f:
    c = pycurl.Curl()
    c.setopt(pycurl.CAINFO, certifi.where())
    c.setopt(c.URL, 'imaps://imap.example.com/INBOX')
    c.setopt(c.USERPWD, '[email protected]:password')
    c.setopt(c.CUSTOMREQUEST, 'FETCH 1:* (BODY[TEXT])')
    c.setopt(c.WRITEDATA, f)
    c.perform()
    c.close()

Another thing is that curl only returns email headers. It returns the message body itself, only when {[4] is enabled]} And then, it does not write to a file, but simply prints to the terminal

 0
Author: Roman Isakov, 2020-08-08 12:07:52