2. IMAP

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. Methods

Table 74. 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.3. Usage

Listing 457. 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: <[email protected]>
# X-Original-To: [email protected]
# Delivered-To: [email protected]
# 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: <[email protected]>
# X-Mailer: mail (GNU Mailutils 3.4)
# Message-Id: <[email protected]ternal>
# Date: Thu, 23 May 2019 07:36:17 +0000 (UTC)
# From: root <[email protected]>
#
# hello
# ------------------------------

2.4. Case Study for Gmail IMAP

Listing 458. 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')
# status: OK
# result: [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()