| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | """A POP3 client class.
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | Based on the J. Myers POP3 draft, Jan. 96 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-28 15:12:25 +00:00
										 |  |  | # Author: David Ascher <david_ascher@brown.edu> | 
					
						
							|  |  |  | #         [heavily stealing from nntplib.py] | 
					
						
							|  |  |  | # Updated: Piers Lauder <piers@cs.su.oz.au> [Jul '97] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | # Example (see the test function at the end of this file) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TESTSERVER = "localhost" | 
					
						
							|  |  |  | TESTACCOUNT = "test" | 
					
						
							|  |  |  | TESTPASSWORD = "_passwd_" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Imports | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | import regex, socket, string | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Exception raised when an error or invalid response is received: | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class error_proto(Exception): pass | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Standard Port | 
					
						
							|  |  |  | POP3_PORT = 110 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | # Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF) | 
					
						
							|  |  |  | CR = '\r' | 
					
						
							|  |  |  | LF = '\n' | 
					
						
							|  |  |  | CRLF = CR+LF | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class POP3: | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"""This class 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): | 
					
						
							|  |  |  | 		RPOP name		rpop(name) | 
					
						
							|  |  |  | 		APOP name digest	apop(name, digest) | 
					
						
							|  |  |  | 		TOP msg n		top(msg, n) | 
					
						
							|  |  |  | 		UIDL [msg]		uidl(msg = None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Raises one exception: 'error_proto'. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Instantiate with: | 
					
						
							|  |  |  | 		POP3(hostname, port=110) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NB:	the POP protocol locks the mailbox from user | 
					
						
							| 
									
										
										
										
											2000-07-16 12:04:32 +00:00
										 |  |  | 		authorization until QUIT, so be sure to get in, suck | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		the messages, and quit, each time you access the | 
					
						
							|  |  |  | 		mailbox. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		POP is a line-based protocol, which means large mail | 
					
						
							|  |  |  | 		messages consume lots of python cycles reading them | 
					
						
							|  |  |  | 		line-by-line. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		If it's available on your mail server, use IMAP4 | 
					
						
							|  |  |  | 		instead, it doesn't suffer from the two problems | 
					
						
							|  |  |  | 		above. | 
					
						
							|  |  |  | 	"""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def __init__(self, host, port = POP3_PORT): | 
					
						
							|  |  |  | 		self.host = host | 
					
						
							|  |  |  | 		self.port = port | 
					
						
							|  |  |  | 		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 
					
						
							| 
									
										
										
										
											2000-03-28 21:45:46 +00:00
										 |  |  | 		self.sock.connect((self.host, self.port)) | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		self.file = self.sock.makefile('rb') | 
					
						
							|  |  |  | 		self._debugging = 0 | 
					
						
							|  |  |  | 		self.welcome = self._getresp() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def _putline(self, line): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		#if self._debugging > 1: print '*put*', `line` | 
					
						
							|  |  |  | 		self.sock.send('%s%s' % (line, CRLF)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# Internal: send one command to the server (through _putline()) | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def _putcmd(self, line): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		#if self._debugging: print '*cmd*', `line` | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		self._putline(line) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	# Internal: return one line from the server, stripping CRLF. | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 	# This is where all the CPU time of this module is consumed. | 
					
						
							|  |  |  | 	# Raise error_proto('-ERR EOF') if the connection is closed. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def _getline(self): | 
					
						
							|  |  |  | 		line = self.file.readline() | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		#if self._debugging > 1: print '*get*', `line` | 
					
						
							|  |  |  | 		if not line: raise error_proto('-ERR EOF') | 
					
						
							|  |  |  | 		octets = len(line) | 
					
						
							|  |  |  | 		# server can send any combination of CR & LF | 
					
						
							|  |  |  | 		# however, 'readline()' returns lines ending in LF | 
					
						
							|  |  |  | 		# so only possibilities are ...LF, ...CRLF, CR...LF | 
					
						
							|  |  |  | 		if line[-2:] == CRLF: | 
					
						
							|  |  |  | 			return line[:-2], octets | 
					
						
							|  |  |  | 		if line[0] == CR: | 
					
						
							|  |  |  | 			return line[1:-1], octets | 
					
						
							|  |  |  | 		return line[:-1], octets | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# Internal: get a response from the server. | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 	# Raise 'error_proto' if the response doesn't start with '+'. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def _getresp(self): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		resp, o = self._getline() | 
					
						
							|  |  |  | 		#if self._debugging > 1: print '*resp*', `resp` | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		c = resp[:1] | 
					
						
							|  |  |  | 		if c != '+': | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 			raise error_proto(resp) | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		return resp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	# Internal: get a response plus following text from the server. | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def _getlongresp(self): | 
					
						
							|  |  |  | 		resp = self._getresp() | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		list = []; octets = 0 | 
					
						
							|  |  |  | 		line, o = self._getline() | 
					
						
							|  |  |  | 		while line != '.': | 
					
						
							| 
									
										
										
										
											2000-05-09 10:56:00 +00:00
										 |  |  | 			if line[:2] == '..': | 
					
						
							|  |  |  | 				o = o-1 | 
					
						
							|  |  |  | 				line = line[1:] | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 			octets = octets + o | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 			list.append(line) | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 			line, o = self._getline() | 
					
						
							|  |  |  | 		return resp, list, octets | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# Internal: send a command and get the response | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def _shortcmd(self, line): | 
					
						
							|  |  |  | 		self._putcmd(line) | 
					
						
							|  |  |  | 		return self._getresp() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	# Internal: send a command and get the response plus following text | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def _longcmd(self, line): | 
					
						
							|  |  |  | 		self._putcmd(line) | 
					
						
							|  |  |  | 		return self._getlongresp() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	# These can be useful: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 	def getwelcome(self):  | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		return self.welcome | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def set_debuglevel(self, level): | 
					
						
							|  |  |  | 		self._debugging = level | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	# Here are all the POP commands: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def user(self, user): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Send user name, return response
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		(should indicate password required). | 
					
						
							|  |  |  | 		"""
 | 
					
						
							|  |  |  | 		return self._shortcmd('USER %s' % user) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def pass_(self, pswd): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Send password, return response
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		(response includes message count, mailbox size). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		NB: mailbox is locked by server from here to 'quit()' | 
					
						
							|  |  |  | 		"""
 | 
					
						
							|  |  |  | 		return self._shortcmd('PASS %s' % pswd) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def stat(self): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Get mailbox status.
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		Result is tuple of 2 ints (message count, mailbox size) | 
					
						
							|  |  |  | 		"""
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		retval = self._shortcmd('STAT') | 
					
						
							|  |  |  | 		rets = string.split(retval) | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		#if self._debugging: print '*stat*', `rets` | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		numMessages = string.atoi(rets[1]) | 
					
						
							|  |  |  | 		sizeMessages = string.atoi(rets[2]) | 
					
						
							|  |  |  | 		return (numMessages, sizeMessages) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-09-14 17:36:51 +00:00
										 |  |  | 	def list(self, which=None): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Request listing, return result.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-09-14 17:36:51 +00:00
										 |  |  | 		Result without a message number argument is in form | 
					
						
							| 
									
										
										
										
											1998-09-02 14:42:02 +00:00
										 |  |  | 		['response', ['mesg_num octets', ...]]. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-09-14 17:36:51 +00:00
										 |  |  | 		Result when a message number argument is given is a | 
					
						
							|  |  |  | 		single response: the "scan listing" for that message. | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""
 | 
					
						
							|  |  |  | 		if which: | 
					
						
							| 
									
										
										
										
											1998-09-02 14:42:02 +00:00
										 |  |  | 			return self._shortcmd('LIST %s' % which) | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		return self._longcmd('LIST') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def retr(self, which): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Retrieve whole message number 'which'.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Result is in form ['response', ['line', ...], octets]. | 
					
						
							|  |  |  | 		"""
 | 
					
						
							|  |  |  | 		return self._longcmd('RETR %s' % which) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def dele(self, which): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Delete message number 'which'.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Result is 'response'. | 
					
						
							|  |  |  | 		"""
 | 
					
						
							|  |  |  | 		return self._shortcmd('DELE %s' % which) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def noop(self): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Does nothing.
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		One supposes the response indicates the server is alive. | 
					
						
							|  |  |  | 		"""
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		return self._shortcmd('NOOP') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 	def rset(self): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Not sure what this does.""" | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		return self._shortcmd('RSET') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def quit(self): | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""Signoff: commit changes on server, unlock mailbox, close connection.""" | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			resp = self._shortcmd('QUIT') | 
					
						
							| 
									
										
										
										
											1998-08-06 02:59:07 +00:00
										 |  |  | 		except error_proto, val: | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 			resp = val | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 		self.file.close() | 
					
						
							|  |  |  | 		self.sock.close() | 
					
						
							|  |  |  | 		del self.file, self.sock | 
					
						
							|  |  |  | 		return resp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 	#__del__ = quit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# optional commands: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def rpop(self, user): | 
					
						
							|  |  |  | 		"""Not sure what this does.""" | 
					
						
							|  |  |  | 		return self._shortcmd('RPOP %s' % user) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	timestamp = regex.compile('\+OK.*\(<[^>]+>\)') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def apop(self, user, secret): | 
					
						
							|  |  |  | 		"""Authorisation
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		- only possible if server has supplied a timestamp in initial greeting. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Args: | 
					
						
							|  |  |  | 			user	- mailbox user; | 
					
						
							|  |  |  | 			secret	- secret shared between client and server. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		NB: mailbox is locked by server from here to 'quit()' | 
					
						
							|  |  |  | 		"""
 | 
					
						
							|  |  |  | 		if self.timestamp.match(self.welcome) <= 0: | 
					
						
							|  |  |  | 			raise error_proto('-ERR APOP not supported by server') | 
					
						
							|  |  |  | 		import md5 | 
					
						
							|  |  |  | 		digest = md5.new(self.timestamp.group(1)+secret).digest() | 
					
						
							|  |  |  | 		digest = string.join(map(lambda x:'%02x'%ord(x), digest), '') | 
					
						
							|  |  |  | 		return self._shortcmd('APOP %s %s' % (user, digest)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def top(self, which, howmuch): | 
					
						
							|  |  |  | 		"""Retrieve message header of message number 'which'
 | 
					
						
							|  |  |  | 		and first 'howmuch' lines of message body. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Result is in form ['response', ['line', ...], octets]. | 
					
						
							|  |  |  | 		"""
 | 
					
						
							|  |  |  | 		return self._longcmd('TOP %s %s' % (which, howmuch)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def uidl(self, which=None): | 
					
						
							|  |  |  | 		"""Return message digest (unique id) list.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-05-13 18:47:25 +00:00
										 |  |  | 		If 'which', result contains unique id for that message | 
					
						
							|  |  |  | 		in the form 'response mesgnum uid', otherwise result is | 
					
						
							|  |  |  | 		the list ['response', ['mesgnum uid', ...], octets] | 
					
						
							| 
									
										
										
										
											1998-04-09 13:50:55 +00:00
										 |  |  | 		"""
 | 
					
						
							|  |  |  | 		if which: | 
					
						
							|  |  |  | 			return self._shortcmd('UIDL %s' % which) | 
					
						
							|  |  |  | 		return self._longcmd('UIDL') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											1998-04-06 18:27:27 +00:00
										 |  |  | 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() |