"""IMAP4 client.

Based on RFC 2060.

Author: Piers Lauder <piers@cs.su.oz.au> December 1997.

Public class:		IMAP4
Public variable:	Debug
Public functions:	Internaldate2tuple
			Int2AP
			ParseFlags
			Time2Internaldate
"""

import re, socket, string, time, whrandom

#	Globals

CRLF = '\r\n'
Debug = 0
IMAP4_PORT = 143
AllowedVersions = ('IMAP4REV1', 'IMAP4')	# Most recent first

#	Commands

Commands = {
	# name		  valid states
	'APPEND':	('AUTH', 'SELECTED'),
	'AUTHENTICATE':	('NONAUTH',),
	'CAPABILITY':	('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'),
	'CHECK':	('SELECTED',),
	'CLOSE':	('SELECTED',),
	'COPY':		('SELECTED',),
	'CREATE':	('AUTH', 'SELECTED'),
	'DELETE':	('AUTH', 'SELECTED'),
	'EXAMINE':	('AUTH', 'SELECTED'),
	'EXPUNGE':	('SELECTED',),
	'FETCH':	('SELECTED',),
	'LIST':		('AUTH', 'SELECTED'),
	'LOGIN':	('NONAUTH',),
	'LOGOUT':	('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'),
	'LSUB':		('AUTH', 'SELECTED'),
	'NOOP':		('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'),
	'RENAME':	('AUTH', 'SELECTED'),
	'SEARCH':	('SELECTED',),
	'SELECT':	('AUTH', 'SELECTED'),
	'STATUS':	('AUTH', 'SELECTED'),
	'STORE':	('SELECTED',),
	'SUBSCRIBE':	('AUTH', 'SELECTED'),
	'UID':		('SELECTED',),
	'UNSUBSCRIBE':	('AUTH', 'SELECTED'),
	}

#	Patterns to match server responses

Continuation = re.compile(r'\+ (?P<data>.*)')
Flags = re.compile(r'.*FLAGS \((?P<flags>[^\)]*)\)')
InternalDate = re.compile(r'.*INTERNALDATE "'
	r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-(?P<year>[0-9][0-9][0-9][0-9])'
	r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
	r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
	r'"')
Literal = re.compile(r'(?P<data>.*) {(?P<size>\d+)}$')
Response_code = re.compile(r'\[(?P<type>[A-Z-]+)( (?P<data>[^\]]*))?\]')
Untagged_response = re.compile(r'\* (?P<type>[A-Z-]+) (?P<data>.*)')
Untagged_status = re.compile(r'\* (?P<data>\d+) (?P<type>[A-Z-]+)( (?P<data2>.*))?')



class IMAP4:

	"""IMAP4 client class.

	Instantiate with: IMAP4([host[, port]])

		host - host's name (default: localhost);
		port - port number (default: standard IMAP4 port).

	All IMAP4rev1 commands are supported by methods of the same
	name (in lower-case). Each command returns a tuple: (type, [data, ...])
	where 'type' is usually 'OK' or 'NO', and 'data' is either the
	text from the tagged response, or untagged results from command.

	Errors raise the exception class <instance>.error("<reason>").
	IMAP4 server errors raise <instance>.abort("<reason>"),
	which is a sub-class of 'error'.
	"""

	class error(Exception): pass	# Logical errors - debug required
	class abort(error): pass	# Service errors - close and retry


	def __init__(self, host = '', port = IMAP4_PORT):
		self.host = host
		self.port = port
		self.debug = Debug
		self.state = 'LOGOUT'
		self.tagged_commands = {}	# Tagged commands awaiting response
		self.untagged_responses = {}	# {typ: [data, ...], ...}
		self.continuation_response = ''	# Last continuation response
		self.tagnum = 0

		# Open socket to server.

		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.connect(self.host, self.port)
		self.file = self.sock.makefile('r')

		# Create unique tag for this session,
		# and compile tagged response matcher.

		self.tagpre = Int2AP(whrandom.random()*32000)
		self.tagre = re.compile(r'(?P<tag>'
				+ self.tagpre
				+ r'\d+) (?P<type>[A-Z]+) (?P<data>.*)')

		# Get server welcome message,
		# request and store CAPABILITY response.

		if __debug__ and self.debug >= 1:
			print '\tnew IMAP4 connection, tag=%s' % self.tagpre

		self.welcome = self._get_response()
		if self.untagged_responses.has_key('PREAUTH'):
			self.state = 'AUTH'
		elif self.untagged_responses.has_key('OK'):
			self.state = 'NONAUTH'
#		elif self.untagged_responses.has_key('BYE'):
		else:
			raise self.error(self.welcome)

		cap = 'CAPABILITY'
		self._simple_command(cap)
		if not self.untagged_responses.has_key(cap):
			raise self.error('no CAPABILITY response from server')
		self.capabilities = tuple(string.split(self.untagged_responses[cap][-1]))

		if __debug__ and self.debug >= 3:
			print '\tCAPABILITIES: %s' % `self.capabilities`

		self.PROTOCOL_VERSION = None
		for version in AllowedVersions:
			if not version in self.capabilities:
				continue
			self.PROTOCOL_VERSION = version
			break
		if not self.PROTOCOL_VERSION:
			raise self.error('server not IMAP4 compliant')


	def __getattr__(self, attr):
		"""Allow UPPERCASE variants of all following IMAP4 commands."""
		if Commands.has_key(attr):
			return eval("self.%s" % string.lower(attr))
		raise AttributeError("Unknown IMAP4 command: '%s'" % attr)


	#	Public methods


	def append(self, mailbox, flags, date_time, message):
		"""Append message to named mailbox.

		(typ, [data]) = <instance>.append(mailbox, flags, date_time, message)
		"""
		name = 'APPEND'
		if flags:
			flags = '(%s)' % flags
		else:
			flags = None
		if date_time:
			date_time = Time2Internaldate(date_time)
		else:
			date_time = None
		tag = self._command(name, mailbox, flags, date_time, message)
		return self._command_complete(name, tag)


	def authenticate(self, func):
		"""Authenticate command - requires response processing.

		UNIMPLEMENTED
		"""
		raise self.error('UNIMPLEMENTED')


	def check(self):
		"""Checkpoint mailbox on server.

		(typ, [data]) = <instance>.check()
		"""
		return self._simple_command('CHECK')


	def close(self):
		"""Close currently selected mailbox.

		Deleted messages are removed from writable mailbox.
		This is the recommended command before 'LOGOUT'.

		(typ, [data]) = <instance>.close()
		"""
		try:
			try: typ, dat = self._simple_command('CLOSE')
			except EOFError: typ, dat = None, [None]
		finally:
			self.state = 'AUTH'
		return typ, dat


	def copy(self, message_set, new_mailbox):
		"""Copy 'message_set' messages onto end of 'new_mailbox'.

		(typ, [data]) = <instance>.copy(message_set, new_mailbox)
		"""
		return self._simple_command('COPY', message_set, new_mailbox)


	def create(self, mailbox):
		"""Create new mailbox.

		(typ, [data]) = <instance>.create(mailbox)
		"""
		return self._simple_command('CREATE', mailbox)


	def delete(self, mailbox):
		"""Delete old mailbox.

		(typ, [data]) = <instance>.delete(mailbox)
		"""
		return self._simple_command('DELETE', mailbox)


	def expunge(self):
		"""Permanently remove deleted items from selected mailbox.

		Generates 'EXPUNGE' response for each deleted message.

		(typ, [data]) = <instance>.expunge()

		'data' is list of 'EXPUNGE'd message numbers in order received.
		"""
		name = 'EXPUNGE'
		typ, dat = self._simple_command(name)
		return self._untagged_response(typ, name)


	def fetch(self, message_set, message_parts):
		"""Fetch (parts of) messages.

		(typ, [data, ...]) = <instance>.fetch(message_set, message_parts)

		'data' are tuples of message part envelope and data.
		"""
		name = 'FETCH'
		typ, dat = self._simple_command(name, message_set, message_parts)
		return self._untagged_response(typ, name)


	def list(self, directory='""', pattern='*'):
		"""List mailbox names in directory matching pattern.

		(typ, [data]) = <instance>.list(directory='""', pattern='*')

		'data' is list of LIST responses.
		"""
		name = 'LIST'
		typ, dat = self._simple_command(name, directory, pattern)
		return self._untagged_response(typ, name)


	def login(self, user, password):
		"""Identify client using plaintext password.

		(typ, [data]) = <instance>.list(user, password)
		"""
		typ, dat = self._simple_command('LOGIN', user, password)
		if typ != 'OK':
			raise self.error(dat)
		self.state = 'AUTH'
		return typ, dat


	def logout(self):
		"""Shutdown connection to server.

		(typ, [data]) = <instance>.logout()

		Returns server 'BYE' response.
		"""
		self.state = 'LOGOUT'
		try: typ, dat = self._simple_command('LOGOUT')
		except EOFError: typ, dat = None, [None]
		self.file.close()
		self.sock.close()
		if self.untagged_responses.has_key('BYE'):
			return 'BYE', self.untagged_responses['BYE']
		return typ, dat


	def lsub(self, directory='""', pattern='*'):
		"""List 'subscribed' mailbox names in directory matching pattern.

		(typ, [data, ...]) = <instance>.lsub(directory='""', pattern='*')

		'data' are tuples of message part envelope and data.
		"""
		name = 'LSUB'
		typ, dat = self._simple_command(name, directory, pattern)
		return self._untagged_response(typ, name)


	def recent(self):
		"""Prompt server for an update.

		(typ, [data]) = <instance>.recent()

		'data' is None if no new messages,
		else value of RECENT response.
		"""
		name = 'RECENT'
		typ, dat = self._untagged_response('OK', name)
		if dat[-1]:
			return typ, dat
		typ, dat = self._simple_command('NOOP')
		return self._untagged_response(typ, name)


	def rename(self, oldmailbox, newmailbox):
		"""Rename old mailbox name to new.

		(typ, data) = <instance>.rename(oldmailbox, newmailbox)
		"""
		return self._simple_command('RENAME', oldmailbox, newmailbox)


	def response(self, code):
		"""Return data for response 'code' if received, or None.

		(code, [data]) = <instance>.response(code)
		"""
		return code, self.untagged_responses.get(code, [None])


	def search(self, charset, criteria):
		"""Search mailbox for matching messages.

		(typ, [data]) = <instance>.search(charset, criteria)

		'data' is space separated list of matching message numbers.
		"""
		name = 'SEARCH'
		if charset:
			charset = 'CHARSET ' + charset
		typ, dat = self._simple_command(name, charset, criteria)
		return self._untagged_response(typ, name)


	def select(self, mailbox='INBOX', readonly=None):
		"""Select a mailbox.

		(typ, [data]) = <instance>.select(mailbox='INBOX', readonly=None)

		'data' is count of messages in mailbox ('EXISTS' response).
		"""
		# Mandated responses are ('FLAGS', 'EXISTS', 'RECENT', 'UIDVALIDITY')
		# Remove immediately interesting responses
		for r in ('EXISTS', 'READ-WRITE'):
			if self.untagged_responses.has_key(r):
				del self.untagged_responses[r]
		if readonly:
			name = 'EXAMINE'
		else:
			name = 'SELECT'
		typ, dat = self._simple_command(name, mailbox)
		if typ == 'OK':
			self.state = 'SELECTED'
		elif typ == 'NO':
			self.state = 'AUTH'
		if not readonly and not self.untagged_responses.has_key('READ-WRITE'):
			raise self.error('%s is not writable' % mailbox)
		return typ, self.untagged_responses.get('EXISTS', [None])


	def status(self, mailbox, names):
		"""Request named status conditions for mailbox.

		(typ, [data]) = <instance>.status(mailbox, names)
		"""
		name = 'STATUS'
		if self.PROTOCOL_VERSION == 'IMAP4':
			raise self.error('%s unimplemented in IMAP4 (obtain IMAP4rev1 server, or re-code)' % name)
		typ, dat = self._simple_command(name, mailbox, names)
		return self._untagged_response(typ, name)


	def store(self, message_set, command, flag_list):
		"""Alters flag dispositions for messages in mailbox.

		(typ, [data]) = <instance>.store(message_set, command, flag_list)
		"""
		command = '%s %s' % (command, flag_list)
		typ, dat = self._simple_command('STORE', message_set, command)
		return self._untagged_response(typ, 'FETCH')


	def subscribe(self, mailbox):
		"""Subscribe to new mailbox.

		(typ, [data]) = <instance>.subscribe(mailbox)
		"""
		return self._simple_command('SUBSCRIBE', mailbox)


	def uid(self, command, args):
		"""Execute "command args" with messages identified by UID,
			rather than message number.

		(typ, [data]) = <instance>.uid(command, args)

		Returns response appropriate to 'command'.
		"""
		name = 'UID'
		typ, dat = self._simple_command('UID', command, args)
		if command == 'SEARCH':
			name = 'SEARCH'
		else:
			name = 'FETCH'
		typ, dat2 = self._untagged_response(typ, name)
		if dat2[-1]: dat = dat2
		return typ, dat


	def unsubscribe(self, mailbox):
		"""Unsubscribe from old mailbox.

		(typ, [data]) = <instance>.unsubscribe(mailbox)
		"""
		return self._simple_command('UNSUBSCRIBE', mailbox)


	def xatom(self, name, arg1=None, arg2=None):
		"""Allow simple extension commands
			notified by server in CAPABILITY response.

		(typ, [data]) = <instance>.xatom(name, arg1=None, arg2=None)
		"""
		if name[0] != 'X' or not name in self.capabilities:
			raise self.error('unknown extension command: %s' % name)
		return self._simple_command(name, arg1, arg2)



	#	Private methods


	def _append_untagged(self, typ, dat):

		if self.untagged_responses.has_key(typ):
			self.untagged_responses[typ].append(dat)
		else:
			self.untagged_responses[typ] = [dat]

		if __debug__ and self.debug >= 5:
			print '\tuntagged_responses[%s] += %.20s..' % (typ, `dat`)


	def _command(self, name, dat1=None, dat2=None, dat3=None, literal=None):

		if self.state not in Commands[name]:
			raise self.error(
			'command %s illegal in state %s' % (name, self.state))

		tag = self._new_tag()
		data = '%s %s' % (tag, name)
		for d in (dat1, dat2, dat3):
			if d is not None: data = '%s %s' % (data, d)
		if literal is not None:
			data = '%s {%s}' % (data, len(literal))

		try:
			self.sock.send('%s%s' % (data, CRLF))
		except socket.error, val:
			raise self.abort('socket error: %s' % val)

		if __debug__ and self.debug >= 4:
			print '\t> %s' % data

		if literal is None:
			return tag

		# Wait for continuation response

		while self._get_response():
			if self.tagged_commands[tag]:	# BAD/NO?
				return tag

		# Send literal

		if __debug__ and self.debug >= 4:
			print '\twrite literal size %s' % len(literal)

		try:
			self.sock.send(literal)
			self.sock.send(CRLF)
		except socket.error, val:
			raise self.abort('socket error: %s' % val)

		return tag


	def _command_complete(self, name, tag):
		try:
			typ, data = self._get_tagged_response(tag)
		except self.abort, val:
			raise self.abort('command: %s => %s' % (name, val))
		except self.error, val:
			raise self.error('command: %s => %s' % (name, val))
		if self.untagged_responses.has_key('BYE') and name != 'LOGOUT':
			raise self.abort(self.untagged_responses['BYE'][-1])
		if typ == 'BAD':
			raise self.error('%s command error: %s %s' % (name, typ, data))
		return typ, data


	def _get_response(self):

		# Read response and store.
		#
		# Returns None for continuation responses,
		# otherwise first response line received

		# Protocol mandates all lines terminated by CRLF.

		resp = self._get_line()[:-2]

		# Command completion response?

		if self._match(self.tagre, resp):
			tag = self.mo.group('tag')
			if not self.tagged_commands.has_key(tag):
				raise self.abort('unexpected tagged response: %s' % resp)

			typ = self.mo.group('type')
			dat = self.mo.group('data')
			self.tagged_commands[tag] = (typ, [dat])
		else:
			dat2 = None

			# '*' (untagged) responses?

			if not self._match(Untagged_response, resp):
				if self._match(Untagged_status, resp):
					dat2 = self.mo.group('data2')

			if self.mo is None:
				# Only other possibility is '+' (continuation) rsponse...

				if self._match(Continuation, resp):
					self.continuation_response = self.mo.group('data')
					return None	# NB: indicates continuation

				raise self.abort('unexpected response: %s' % resp)

			typ = self.mo.group('type')
			dat = self.mo.group('data')
			if dat2: dat = dat + ' ' + dat2

			# Is there a literal to come?

			while self._match(Literal, dat):

				# Read literal direct from connection.

				size = string.atoi(self.mo.group('size'))
				if __debug__ and self.debug >= 4:
					print '\tread literal size %s' % size
				data = self.file.read(size)

				# Store response with literal as tuple

				self._append_untagged(typ, (dat, data))

				# Read trailer - possibly containing another literal

				dat = self._get_line()[:-2]

			self._append_untagged(typ, dat)

		# Bracketed response information?

		if typ in ('OK', 'NO', 'BAD') and self._match(Response_code, dat):
			self._append_untagged(self.mo.group('type'), self.mo.group('data'))

		return resp


	def _get_tagged_response(self, tag):

		while 1:
			result = self.tagged_commands[tag]
			if result is not None:
				del self.tagged_commands[tag]
				return result
			self._get_response()


	def _get_line(self):

		line = self.file.readline()
		if not line:
			raise EOFError

		# Protocol mandates all lines terminated by CRLF

		if __debug__ and self.debug >= 4:
			print '\t< %s' % line[:-2]
		return line


	def _match(self, cre, s):

		# Run compiled regular expression match method on 's'.
		# Save result, return success.

		self.mo = cre.match(s)
		if __debug__ and self.mo is not None and self.debug >= 5:
			print "\tmatched r'%s' => %s" % (cre.pattern, `self.mo.groups()`)
		return self.mo is not None


	def _new_tag(self):

		tag = '%s%s' % (self.tagpre, self.tagnum)
		self.tagnum = self.tagnum + 1
		self.tagged_commands[tag] = None
		return tag


	def _simple_command(self, name, dat1=None, dat2=None):

		return self._command_complete(name, self._command(name, dat1, dat2))


	def _untagged_response(self, typ, name):

		if not self.untagged_responses.has_key(name):
			return typ, [None]
		data = self.untagged_responses[name]
		del self.untagged_responses[name]
		return typ, data



Mon2num = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
	'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}

def Internaldate2tuple(resp):

	"""Convert IMAP4 INTERNALDATE to UT.

	Returns Python time module tuple.
	"""

	mo = InternalDate.match(resp)
	if not mo:
		return None

	mon = Mon2num[mo.group('mon')]
	zonen = mo.group('zonen')

	for name in ('day', 'year', 'hour', 'min', 'sec', 'zoneh', 'zonem'):
		exec "%s = string.atoi(mo.group('%s'))" % (name, name)

	# INTERNALDATE timezone must be subtracted to get UT

	zone = (zoneh*60 + zonem)*60
	if zonen == '-':
		zone = -zone

	tt = (year, mon, day, hour, min, sec, -1, -1, -1)

	utc = time.mktime(tt)

	# Following is necessary because the time module has no 'mkgmtime'.
	# 'mktime' assumes arg in local timezone, so adds timezone/altzone.

	lt = time.localtime(utc)
	if time.daylight and lt[-1]:
		zone = zone + time.altzone
	else:
		zone = zone + time.timezone

	return time.localtime(utc - zone)



def Int2AP(num):

	"""Convert integer to A-P string representation."""

	val = ''; AP = 'ABCDEFGHIJKLMNOP'
	num = int(abs(num))
	while num:
		num, mod = divmod(num, 16)
		val = AP[mod] + val
	return val



def ParseFlags(resp):

	"""Convert IMAP4 flags response to python tuple."""

	mo = Flags.match(resp)
	if not mo:
		return ()

	return tuple(string.split(mo.group('flags')))


def Time2Internaldate(date_time):

	"""Convert 'date_time' to IMAP4 INTERNALDATE representation.

	Return string in form: '"DD-Mmm-YYYY HH:MM:SS +HHMM"'
	"""

	dttype = type(date_time)
	if dttype is type(1):
		tt = time.localtime(date_time)
	elif dttype is type(()):
		tt = date_time
	elif dttype is type(""):
		return date_time	# Assume in correct format
	else: raise ValueError

	dt = time.strftime("%d-%b-%Y %H:%M:%S", tt)
	if dt[0] == '0':
		dt = ' ' + dt[1:]
	if time.daylight and tt[-1]:
		zone = -time.altzone
	else:
		zone = -time.timezone
	return '"' + dt + " %+02d%02d" % divmod(zone/60, 60) + '"'



if __debug__ and __name__ == '__main__':

	import getpass
	USER = getpass.getuser()
	PASSWD = getpass.getpass()

	test_seq1 = (
	('login', (USER, PASSWD)),
	('create', ('/tmp/xxx',)),
	('rename', ('/tmp/xxx', '/tmp/yyy')),
	('CREATE', ('/tmp/yyz',)),
	('append', ('/tmp/yyz', None, None, 'From: anon@x.y.z\n\ndata...')),
	('select', ('/tmp/yyz',)),
	('recent', ()),
	('uid', ('SEARCH', 'ALL')),
	('fetch', ('1', '(INTERNALDATE RFC822)')),
	('store', ('1', 'FLAGS', '(\Deleted)')),
	('expunge', ()),
	('close', ()),
	)

	test_seq2 = (
	('select', ()),
	('response',('UIDVALIDITY',)),
	('uid', ('SEARCH', 'ALL')),
	('recent', ()),
	('response', ('EXISTS',)),
	('logout', ()),
	)

	def run(cmd, args):
		typ, dat = apply(eval('M.%s' % cmd), args)
		print ' %s %s\n  => %s %s' % (cmd, args, typ, dat)
		return dat

	Debug = 4
	M = IMAP4()
	print 'PROTOCOL_VERSION = %s' % M.PROTOCOL_VERSION

	for cmd,args in test_seq1:
		run(cmd, args)

	for ml in run('list', ('/tmp/', 'yy%')):
		path = string.split(ml)[-1]
		run('delete', (path,))

	for cmd,args in test_seq2:
		dat = run(cmd, args)

		if (cmd,args) != ('uid', ('SEARCH', 'ALL')):
			continue

		uid = string.split(dat[0])[-1]
		run('uid', ('FETCH',
			'%s (FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822)' % uid))
