diff options
Diffstat (limited to 'lib/python2.7/poplib.py')
-rw-r--r-- | lib/python2.7/poplib.py | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/lib/python2.7/poplib.py b/lib/python2.7/poplib.py deleted file mode 100644 index e2b33ef..0000000 --- a/lib/python2.7/poplib.py +++ /dev/null @@ -1,417 +0,0 @@ -"""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] -# Updated: Piers Lauder <piers@cs.su.oz.au> [Jul '97] -# String method conversion and test jig improvements by ESR, February 2001. -# Added the POP3_SSL class. Methods loosely based on IMAP_SSL. Hector Urtubia <urtubia@mrbook.org> Aug 2003 - -# Example (see the test function at the end of this file) - -# Imports - -import re, socket - -__all__ = ["POP3","error_proto"] - -# Exception raised when an error or invalid response is received: - -class error_proto(Exception): pass - -# Standard Port -POP3_PORT = 110 - -# POP SSL PORT -POP3_SSL_PORT = 995 - -# Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF) -CR = '\r' -LF = '\n' -CRLF = CR+LF - - -class POP3: - - """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 - authorization until QUIT, so be sure to get in, suck - 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. - """ - - - def __init__(self, host, port=POP3_PORT, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - self.host = host - self.port = port - self.sock = socket.create_connection((host, port), timeout) - self.file = self.sock.makefile('rb') - self._debugging = 0 - self.welcome = self._getresp() - - - def _putline(self, line): - if self._debugging > 1: print '*put*', repr(line) - self.sock.sendall('%s%s' % (line, CRLF)) - - - # Internal: send one command to the server (through _putline()) - - def _putcmd(self, line): - if self._debugging: print '*cmd*', repr(line) - self._putline(line) - - - # Internal: return one line from the server, stripping CRLF. - # This is where all the CPU time of this module is consumed. - # Raise error_proto('-ERR EOF') if the connection is closed. - - def _getline(self): - line = self.file.readline() - if self._debugging > 1: print '*get*', repr(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 - - - # Internal: get a response from the server. - # Raise 'error_proto' if the response doesn't start with '+'. - - def _getresp(self): - resp, o = self._getline() - if self._debugging > 1: print '*resp*', repr(resp) - c = resp[:1] - if c != '+': - raise error_proto(resp) - return resp - - - # Internal: get a response plus following text from the server. - - def _getlongresp(self): - resp = self._getresp() - list = []; octets = 0 - line, o = self._getline() - while line != '.': - if line[:2] == '..': - o = o-1 - line = line[1:] - octets = octets + o - list.append(line) - line, o = self._getline() - return resp, list, octets - - - # 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): - """Send user name, return response - - (should indicate password required). - """ - return self._shortcmd('USER %s' % user) - - - def pass_(self, pswd): - """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) - - - def stat(self): - """Get mailbox status. - - Result is tuple of 2 ints (message count, mailbox size) - """ - retval = self._shortcmd('STAT') - rets = retval.split() - if self._debugging: print '*stat*', repr(rets) - numMessages = int(rets[1]) - sizeMessages = int(rets[2]) - return (numMessages, sizeMessages) - - - def list(self, which=None): - """Request listing, return result. - - Result without a message number argument is in form - ['response', ['mesg_num octets', ...], octets]. - - Result when a message number argument is given is a - single response: the "scan listing" for that message. - """ - if which is not None: - return self._shortcmd('LIST %s' % which) - return self._longcmd('LIST') - - - def retr(self, which): - """Retrieve whole message number 'which'. - - Result is in form ['response', ['line', ...], octets]. - """ - return self._longcmd('RETR %s' % which) - - - def dele(self, which): - """Delete message number 'which'. - - Result is 'response'. - """ - return self._shortcmd('DELE %s' % which) - - - def noop(self): - """Does nothing. - - One supposes the response indicates the server is alive. - """ - return self._shortcmd('NOOP') - - - def rset(self): - """Unmark all messages marked for deletion.""" - return self._shortcmd('RSET') - - - def quit(self): - """Signoff: commit changes on server, unlock mailbox, close connection.""" - try: - resp = self._shortcmd('QUIT') - except error_proto, val: - resp = val - self.file.close() - self.sock.close() - del self.file, self.sock - return resp - - #__del__ = quit - - - # optional commands: - - def rpop(self, user): - """Not sure what this does.""" - return self._shortcmd('RPOP %s' % user) - - - timestamp = re.compile(r'\+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()' - """ - m = self.timestamp.match(self.welcome) - if not m: - raise error_proto('-ERR APOP not supported by server') - import hashlib - digest = hashlib.md5(m.group(1)+secret).digest() - digest = ''.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. - - If 'which', result contains unique id for that message - in the form 'response mesgnum uid', otherwise result is - the list ['response', ['mesgnum uid', ...], octets] - """ - if which is not None: - return self._shortcmd('UIDL %s' % which) - return self._longcmd('UIDL') - -try: - import ssl -except ImportError: - pass -else: - - class POP3_SSL(POP3): - """POP3 client class over SSL connection - - Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None) - - hostname - the hostname of the pop3 over ssl server - port - port number - keyfile - PEM formatted file that countains your private key - certfile - PEM formatted certificate chain file - - See the methods of the parent class POP3 for more documentation. - """ - - def __init__(self, host, port = POP3_SSL_PORT, keyfile = None, certfile = None): - self.host = host - self.port = port - self.keyfile = keyfile - self.certfile = certfile - self.buffer = "" - msg = "getaddrinfo returns an empty list" - self.sock = None - for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): - af, socktype, proto, canonname, sa = res - try: - self.sock = socket.socket(af, socktype, proto) - self.sock.connect(sa) - except socket.error, msg: - if self.sock: - self.sock.close() - self.sock = None - continue - break - if not self.sock: - raise socket.error, msg - self.file = self.sock.makefile('rb') - self.sslobj = ssl.wrap_socket(self.sock, self.keyfile, self.certfile) - self._debugging = 0 - self.welcome = self._getresp() - - def _fillBuffer(self): - localbuf = self.sslobj.read() - if len(localbuf) == 0: - raise error_proto('-ERR EOF') - self.buffer += localbuf - - def _getline(self): - line = "" - renewline = re.compile(r'.*?\n') - match = renewline.match(self.buffer) - while not match: - self._fillBuffer() - match = renewline.match(self.buffer) - line = match.group(0) - self.buffer = renewline.sub('' ,self.buffer, 1) - if self._debugging > 1: print '*get*', repr(line) - - octets = len(line) - if line[-2:] == CRLF: - return line[:-2], octets - if line[0] == CR: - return line[1:-1], octets - return line[:-1], octets - - def _putline(self, line): - if self._debugging > 1: print '*put*', repr(line) - line += CRLF - bytes = len(line) - while bytes > 0: - sent = self.sslobj.write(line) - if sent == bytes: - break # avoid copy - line = line[sent:] - bytes = bytes - sent - - def quit(self): - """Signoff: commit changes on server, unlock mailbox, close connection.""" - try: - resp = self._shortcmd('QUIT') - except error_proto, val: - resp = val - self.sock.close() - del self.sslobj, self.sock - return resp - - __all__.append("POP3_SSL") - -if __name__ == "__main__": - import sys - a = POP3(sys.argv[1]) - print a.getwelcome() - a.user(sys.argv[2]) - a.pass_(sys.argv[3]) - a.list() - (numMsgs, totalSize) = a.stat() - for i in range(1, numMsgs + 1): - (header, msg, octets) = a.retr(i) - print "Message %d:" % i - for line in msg: - print ' ' + line - print '-----------------------' - a.quit() |