Chapter 15 ■ IMap
276
else:
print_summary(c, foldername)
finally:
c.logout()
def print_summary(c, foldername):
c.select_folder(foldername, readonly=True)
msgdict = c.fetch('1:*', ['BODY.PEEK[]'])
for message_id, message in list(msgdict.items()):
e = email.message_from_string(message['BODY[]'])
print(message_id, e['From'])
payload = e.get_payload()
if isinstance(payload, list):
part_content_types = [ part.get_content_type() for part in payload ]
print(' Parts:', ' '.join(part_content_types))
else:
print(' ', ' '.join(payload[:60].split()), '...')
if name == 'main':
main()
Remember that IMAP is stateful: first you use select_folder() to put yourself “inside” the given folder, and then
you can run fetch() to ask for message content. (You can later run close_folder() if you want to leave and not be
inside a given folder any more.) The range '1:*' means “the first message through the end of the mail folder,” because
message IDs—whether temporary or UIDs—are always positive integers.
The perhaps odd-looking string 'BODY.PEEK[]' is the way to ask IMAP for the “whole body” of the message. The
string 'BODY[]' means “the whole message”; inside the square brackets, as you will see, you can instead ask for just
specific parts of a message.
And PEEK indicates that you are just looking inside the message to build a summary, and that you do not want
the server to set the \Seen flag automatically on all of these messages for you and thus ruin its memory about which
messages the user has read. (This seemed to be a nice feature for me to add to a little script like this that you might run
against a real mailbox—I would not want to mark all of your messages as read!)
The dictionary that is returned maps message UIDs to dictionaries giving information about each message. As
you iterate across its keys and values, you look in each message dictionary for the 'BODY[]' key that IMAP has filled in
with the information about the message for which you asked: its full text, returned as a large string.
Using the email module that I discussed in Chapter 12, the script asks Python to grab the From: line and a bit of
the message’s content and print them to the screen as a summary. Of course, if you wanted to extend this script so that
you save the messages in a file or database instead, you could just omit the email parsing step and instead treat the
message body as a single string to be deposited in storage and parsed later.
Here is what the results look like when you run this script:
$ ./mailbox_summary.py imap.example.com brandon INBOX
Password:
2590 "Amazon.com" [email protected]
Dear Brandon, Portable Power Systems, Inc. shipped the follo ...
2469 Meetup Reminder [email protected]
Parts: text/plain text/html
2470 [email protected]
Thank you. Please note that charges will appear as "Linode.c ...