diff options
Diffstat (limited to 'Lib/poplib.py')
| -rw-r--r-- | Lib/poplib.py | 201 | 
1 files changed, 201 insertions, 0 deletions
diff --git a/Lib/poplib.py b/Lib/poplib.py new file mode 100644 index 0000000..7b406d9 --- /dev/null +++ b/Lib/poplib.py @@ -0,0 +1,201 @@ +"""A POP3 client class.  Based on the J. Myers POP3 draft, Jan. 96 + +Author: David Ascher <david_ascher@brown.edu> [heavily stealing from +nntplib.py] + +""" + +__version__ = "0.01a - Feb 1, 1996 (with formatting changes by GvR)" + +# Example (see the test function at the end of this file) + +TESTSERVER = "localhost" +TESTACCOUNT = "test" +TESTPASSWORD = "_passwd_" + +# Imports + +from types import StringType +import regex +import socket +import string + +# Exception raised when an error or invalid response is received: +error_proto = 'pop3.error_proto'	 # response does not begin with + + +# Standard Port +POP3_PORT = 110 + +# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF) +CRLF = '\r\n' + +# This library supports both the minimal and optional command sets: +# Arguments can be strings or integers (where appropriate) +# (e.g.: retr(1) and retr('1') both work equally well. +# +# Minimal Command Set: +#	 USER name				user(name) +#	 PASS string				pass_(string) +#	 STAT					stat() +#	 LIST [msg]				list(msg = None) +#	 RETR msg				retr(msg) +#	 DELE msg				dele(msg) +#	 NOOP					noop() +#	 RSET					rset() +#	 QUIT					quit() +# +# Optional Commands (some servers support these) +#	 APOP name digest			apop(name, digest) +#	 TOP msg n				top(msg, n) +#	 UIDL [msg]				uidl(msg = None) +# + + +class POP3: +	def __init__(self, host, port = POP3_PORT): +		self.host = host +		self.port = port +		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +		self.sock.connect(self.host, self.port) +		self.file = self.sock.makefile('rb') +		self._debugging = 0 +		self.welcome = self._getresp() + +	def _putline(self, line): +		line = line + CRLF +		if self._debugging > 1: print '*put*', `line` +		self.sock.send(line) + +	# Internal: send one command to the server (through _putline()) +	def _putcmd(self, line): +		if self._debugging: print '*cmd*', `line` +		self._putline(line) + +	# Internal: return one line from the server, stripping CRLF. +	# Raise EOFError if the connection is closed +	def _getline(self): +		line = self.file.readline() +		if self._debugging > 1: +			print '*get*', `line` +		if not line: raise EOFError +		if line[-2:] == CRLF: line = line[:-2] +		elif line[-1:] in CRLF: line = line[:-1] +		return line + +	# Internal: get a response from the server. +	# Raise various errors if the response indicates an error +	def _getresp(self): +		resp = self._getline() +		if self._debugging > 1: print '*resp*', `resp` +		c = resp[:1] +		if c != '+': +			raise error_proto, resp +		return resp + +	# Internal: get a response plus following text from the server. +	# Raise various errors if the response indicates an error +	def _getlongresp(self): +		resp = self._getresp() +		list = [] +		while 1: +			line = self._getline() +			if line == '.': +				break +			list.append(line) +		return resp, list + +	# Internal: send a command and get the response +	def _shortcmd(self, line): +		self._putcmd(line) +		return self._getresp() + +	# Internal: send a command and get the response plus following text +	def _longcmd(self, line): +		self._putcmd(line) +		return self._getlongresp() + +	# These can be useful: + +	def getwelcome(self): +		return self.welcome + +	def set_debuglevel(self, level): +		self._debugging = level + +	# Here are all the POP commands: + +	def user(self, user): +		user = str(user) +		return self._shortcmd('USER ' + user) + +	def pass_(self, pswd): +		pswd = str(pswd) +		return self._shortcmd('PASS ' + pswd) + +	def stat(self): +		retval = self._shortcmd('STAT') +		rets = string.split(retval) +		numMessages = string.atoi(rets[1]) +		sizeMessages = string.atoi(rets[2]) +		return (numMessages, sizeMessages) + +	def list(self, msg=None): +		if msg: +			msg = str(msg) +			return self._longcmd('LIST ' + msg) +		else: +			return self._longcmd('LIST') + +	def retr(self, which): +		which = str(which) +		return self._longcmd('RETR ' + which) + +	def dele(self, which): +		which = str(which) +		return self._shortcmd('DELE ' + which) + +	def noop(self): +		return self._shortcmd('NOOP') + +	def rset(self): +		return self._shortcmd('RSET') + +	# optional commands: + +	def apop(self, digest): +		digest = str(digest) +		return self._shortcmd('APOP ' + digest) + +	def top(self, which, howmuch): +		which = str(which) +		howmuch = str(howmuch) +		return self._longcmd('TOP ' + which + ' ' + howmuch) + +	def uidl(self, which = None): +		if which: +			which = str(which) +			return self._longcmd('UIDL ' + which) +		else: +			return self._longcmd('UIDL') + +	def quit(self): +		resp = self._shortcmd('QUIT') +		self.file.close() +		self.sock.close() +		del self.file, self.sock +		return resp + +if __name__ == "__main__": +	a = POP3(TESTSERVER) +	print a.getwelcome() +	a.user(TESTACCOUNT) +	a.pass_(TESTPASSWORD) +	a.list() +	(numMsgs, totalSize) = a.stat() +	for i in range(1, numMsgs + 1): +		(header, msg, octets) = a.retr(i) +		print "Message ", `i`, ':' +		for line in msg: +			print '   ' + line +		print '-----------------------' +	a.quit()  | 
