26-Aug-1996 Konrad Hinsen <
[email protected]> - original version
In poplib.py you can find a class representing a POP server from
which you can read mail. The code also serves as documentation ;-)
Attention: I have never seen an official POP specification, and
I have tested this code on one machine only. Use at your own risk!
96/12/09 -- Andy Dustman <
[email protected]>
This started out as a bug fix, and turned into fairly major surgery to
accomodate a mail POPping application I am writing. I was
experimenting with Konrad Hinsen's poplib.py module, and found
that it did not work correctly on my POP server. Specifically, on
commands such as LIST or RETR, some of the first characters of the
data after the server response would be lost. I got around this by
rewriting _getline() to use an internal buffer. Konrad confirms that
it still works correctly on his server, so that's a grand total of two
servers which are known to work...
There are two ways to set up the server connection:
# the original way
p = POP(server)
p.identify(user,pass)
# the new way
p = POP(server,user,pass)
p.connect()
With the new method, you can connect(), do your business, close(), and
then later connect() again. See the little mail POPping daemon at the
end of the file.
A major new feature is that messages can referenced using an indexing
interface. Note that slicing is not supported, and the message list
behaves more like a dictionary (i.e., if you delete a message in the
middle, higher numbered messages are not moved down a number). Note
that messages are indexed from zero (Python-style) and not one
(POP-server style).
Messages can now be retrieved in a couple of ways:
# retrieve message x from server p as string s
s = p[x]
# retrieve as a list of newline-terminated strings
l = p.retrieve(x)
# retrieve into named file
p.retrieve(x,filename)
# retrieve into file object
p.retrieve(x,fileobject)
Note that when retrieving to a file object that it attempts to ensure
that mailbox format is maintained. Mailbox format consists of adding
the initial "From user date" header and guaranteeing that the last
line is empty. This should guarantee that mail clients can parse out
individual messages. The munging is pretty trivial. I suspect every
mail reader on Earth will at least tolerate the presence of "From".
Considering that the standard cross-platform rfc822.py looks for it, I
feel pretty safe putting it in. If this munging doesn't work for your
platform (probably you need *more* munging instead of less), your best
bet is to retrieve as a list of strings (analogous to readlines()) and
do your own munging.
The top method has been removed, but it's functionality has been
included in retrieve via an optional lines parameter:
# retrieve only the top 10 lines as a list of strings
# (but you always get at least the entire header from the server)
p.retrieve(x,lines=10)
Deleting messages has also been given the indexing treatment:
# delete message x
del p[x]
p.delete(x) # same thing
There are also two ways to get information on the number of messages:
# query number of messages n and bytes of data b
n,b = p.status()
n = len(p) # indexed-style, number of messages only
Terminating the server connection is now different:
# you used to do this with quit(), but close() more closely
# parallels the socket interface
p.close()
Exception handling: socket.error now caught, produces a
POPError. This seems to be an easier way to handle exceptions in the
application.
Note that messages are indexed from zero (Python-style) and not one
(POP-server style).