Chapter 15 ■ IMap
273
So when you select a folder, you tell the IMAP server that all of the commands that follow—until you change
folders or exit the current one—will apply to the selected folder.
When selecting, you have the option to select the folder “read-only,” instead of selecting it in full read/write mode,
by supplying a readonly=True argument. This causes any operations that would delete or modify messages to return an
error message should you attempt them. Besides preventing you from making any mistakes when you want to leave all
of the messages intact, the fact that you are just reading can be used by the server to optimize access to the folder.
(For example, it might read-lock, but not write-lock, the actual folder storage on disk while you have it selected.)
Message Numbers vs. UIDs
IMAP provides two different ways to refer to a specific message within a folder: by a temporary message number
(which typically goes 1, 2, 3, and so forth) or by a unique identifier (UID). The difference between the two lies in their
persistence. Message numbers are assigned at the moment you select a folder over a particular connection. This means
they can be pretty and sequential, but it also means that if you revisit the same folder later, a given message might then
have a different number. For programs such as live e-mail readers or simple download scripts, this behavior (which is
the same as POP) is fine; you won’t care that the numbers might be different the next time you connect.
But a UID, by contrast, is designed to remain the same, even if you close your connection to the server and do not
reconnect again. If a message had UID 1053 today, then the same message will have UID 1053 tomorrow, and no other
message in that folder will ever have UID 1053. If you are writing a synchronization tool, this behavior is quite useful!
It will allow you to verify with 100 percent certainty that actions are being taken against the correct message. This is
one of the things that makes IMAP so much more fun to use than POP.
Note that if you return to an IMAP account and the user has, without telling you, deleted a folder and then
created a new one with the same name, then it might look to your program as though the same folder is present but
that the UID numbers are conflicting and no longer agree. Even a folder rename, if you fail to notice it, might make
you lose track of which messages in the IMAP account correspond to which messages you have already downloaded.
But it turns out that IMAP is prepared to protect you against this, and (as I’ll explain soon) provides a UIDVALIDITY
folder attribute that you can compare from one session to the next to see whether UIDs in the folder will really
correspond to the UIDs that the same messages had when you last connected.
Most IMAP commands that work with specific messages can take either message numbers or UIDs. Normally,
IMAPClient always uses UIDs and ignores the temporary message numbers assigned by IMAP. But if you want to see
the temporary numbers instead, simply instantiate IMAPClient with a use_uid=False argument, or you can even set
the value of the class’s use_uid attribute to False and True on the fly during your IMAP session.
Message Ranges
Most IMAP commands that work with messages can work with one or more messages. This can make processing far
faster if you need a whole group of messages. Instead of issuing separate commands and receiving separate responses
for each individual message, you can operate on a group of messages as a whole. This is often faster because you no
longer have to deal with a network roundtrip for every single command.
Where you would usually supply a message number, you can instead supply a comma-separated list of message
numbers. Also, if you want all messages whose numbers are in a range but you do not want to have to list all of their
numbers (or if you do not even know their numbers—maybe you want “everything starting with message one” without
having to fetch their numbers first), you can use a colon to separate the start and end message numbers. An asterisk
means “and all of the rest of the messages.” Here is an example specification:
2,4:6,20:*
It means “message 2, messages 4 through 6, and message 20 through the end of the mail folder.”