2.2. IMAP

2.2.1. Connection

  • imaplib.IMAP4(host, port), If port is omitted, the standard IMAP4 port (143) is used.

  • imaplib.IMAP4_SSL(host, port), if port is omitted, the standard IMAP4-over-SSL port (993)

2.2.2. Methods

Table 2.11. python

Method

Arguments

Description

IMAP4.append()

mailbox, flags, date_time, message

Append message to named mailbox

IMAP4.check()

Checkpoint mailbox on server

IMAP4.close()

Close currently selected mailbox

IMAP4.copy()

message_set, new_mailbox

Copy message_set messages onto end of new_mailbox

IMAP4.create()

name

Create new mailbox

IMAP4.delete(name)

Delete mailbox

IMAP4.expunge()

Permanently remove deleted items from selected mailbox

IMAP4.fetch()

message_set, message_parts

Fetch (parts of) messages. message_parts should be a string of message part names enclosed within parentheses, eg: (UID BODY[TEXT])

IMAP4.list()

directory=None, pattern=None

List mailbox names in directory matching pattern

IMAP4.login()

user, password

Identify the client using a plaintext password

IMAP4.logout()

Shutdown connection to server

IMAP4.recent()

Prompt server for an update

IMAP4.rename()

oldmailbox, newmailbox

Rename mailbox named oldmailbox to newmailbox

IMAP4.search()

charset=None, criterion[, ...]

Search mailbox for matching messages. charset may be None, in which case no CHARSET will be specified in the request to the server

IMAP4.select()

mailbox='IMAP', readonly=False

Select a mailbox. The default mailbox is INBOX. If the readonly flag is set, modifications to the mailbox are not allowed

2.2.3. Usage

Code 2.55. Usage
import imaplib


IMAP4_HOST = 'localhost'
IMAP4_PORT = 993
IMAP4_USER = 'myusername'
IMAP4_PASS = 'mypassword'
IMAP4_MAILBOX = 'INBOX'


imap = imaplib.IMAP4_SSL(
    host=IMAP4_HOST,
    port=IMAP4_PORT)

imap.login(
    user=IMAP4_USER,
    password=IMAP4_PASS)

imap.select(
    mailbox=IMAP4_MAILBOX,
    readonly=False)

result = imap.search(None, 'ALL')
messages = result[1][0].split()

for msgid in messages:
    status, data = imap.fetch(msgid, '(RFC822)')
    mail = data[0][1].decode()

    print(mail)
    print('-' * 30)


imap.close()
imap.logout()

"""
Return-Path: <root@ip-172-31-5-83.eu-central-1.compute.internal>
X-Original-To: upload@localhost
Delivered-To: upload@localhost
Received: by ip-172-31-5-83.eu-central-1.compute.internal (Postfix, from userid 0)
	id 2481544BD5; Thu, 23 May 2019 07:36:17 +0000 (UTC)
Subject: test
To: <upload@localhost>
X-Mailer: mail (GNU Mailutils 3.4)
Message-Id: <20190523073617.2481544BD5@ip-172-31-5-83.eu-central-1.compute.internal>
Date: Thu, 23 May 2019 07:36:17 +0000 (UTC)
From: root <root@ip-172-31-5-83.eu-central-1.compute.internal>

hello
------------------------------
"""

2.2.4. Case Study for Gmail IMAP

Code 2.56. Case Study for Gmail IMAP
import imaplib
import email
from pprint import pprint
from quopri import decodestring
from datetime import datetime


# Gmail requires to generate One-Time App Password
# https://security.google.com/settings/security/apppasswords
IMAP4_HOST = 'imap.gmail.com'
IMAP4_PORT = 993
IMAP4_USER = 'myusername'
IMAP4_PASS = 'mypassword'
IMAP4_MAILBOX = 'INBOX'


imap = imaplib.IMAP4_SSL(
    host=IMAP4_HOST,
    port=IMAP4_PORT)

imap.login(
    user=IMAP4_USER,
    password=IMAP4_PASS)

imap.select(
    mailbox=IMAP4_MAILBOX,
    readonly=False)


def get_str(text):
    return decodestring(text).decode()


def get_date(text):
    try:
        return datetime.strptime(headers['Date'], '%a, %d %b %Y %H:%M:%S %z')
    except ValueError:
        return text


def get_body(msg):
    type = msg.get_content_maintype()

    if type == 'multipart':
        for part in msg.get_payload():
            if part.get_content_maintype() == 'text':
                return part.get_payload(decode=True).decode('utf-8')

    elif type == 'text':
        return msg.get_payload(decode=True).decode('utf-8')


status, result = imap.search(None, 'ALL')
# Variable `status` is OK
# Variable `result` is [b'1 2 3 4 ...']
messages = result[1][0].split()

for msgid in messages:
    status, data = imap.fetch(msgid, '(RFC822)')
    mail = data[0][1].decode()
    mail = email.message_from_string(mail)

    headers = dict(mail._headers)
    mail = {
        'to': get_str(headers['To']),
        'sender': get_str(headers['From']),
        'subject': get_str(headers['Subject']),
        'date': get_date(headers['Date']),
        'body': get_body(mail)
    }
    pprint(mail)

imap.close()
imap.logout()