# An NNTP client class.  Based on RFC 977: Network News Transfer
# Protocol, by Brian Kantor and Phil Lapsley.


# Example:
#
# >>> from nntplib import NNTP
# >>> s = NNTP('news')
# >>> resp, count, first, last, name = s.group('comp.lang.python')
# >>> print 'Group', name, 'has', count, 'articles, range', first, 'to', last
# Group comp.lang.python has 51 articles, range 5770 to 5821
# >>> resp, subs = s.xhdr('subject', first + '-' + last)
# >>> resp = s.quit()
# >>>
#
# Here 'resp' is the server response line.
# Error responses are turned into exceptions.
#
# To post an article from a file:
# >>> f = open(filename, 'r') # file containing article, including header
# >>> resp = s.post(f)
# >>>
#
# For descriptions of all methods, read the comments in the code below.
# Note that all arguments and return values representing article numbers
# are strings, not numbers, since they are rarely used for calculations.

# (xover, xgtitle, xpath, date methods by Kevan Heydon)


# Imports
import regex
import socket
import string


# Exception raised when an error or invalid response is received

error_reply = 'nntplib.error_reply'	# unexpected [123]xx reply
error_temp = 'nntplib.error_temp'	# 4xx errors
error_perm = 'nntplib.error_perm'	# 5xx errors
error_proto = 'nntplib.error_proto'	# response does not begin with [1-5]
error_data = 'nntplib.error_data'	# error in response data


# Standard port used by NNTP servers
NNTP_PORT = 119


# Response numbers that are followed by additional text (e.g. article)
LONGRESP = ['100', '215', '220', '221', '222', '224', '230', '231', '282']


# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
CRLF = '\r\n'


# The class itself

class NNTP:

	# Initialize an instance.  Arguments:
	# - host: hostname to connect to
	# - port: port to connect to (default the standard NNTP port)

	def __init__(self, host, port = NNTP_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()

	# Get the welcome message from the server
	# (this is read and squirreled away by __init__()).
	# If the response code is 200, posting is allowed;
	# if it 201, posting is not allowed

	def getwelcome(self):
		if self.debugging: print '*welcome*', `self.welcome`
		return self.welcome

	# Set the debugging level.  Argument level means:
	# 0: no debugging output (default)
	# 1: print commands and responses but not body text etc.
	# 2: also print raw lines read and sent before stripping CR/LF

	def set_debuglevel(self, level):
		self.debugging = level
	debug = set_debuglevel

	# Internal: send one line to the server, appending CRLF
	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: print '*resp*', `resp`
		c = resp[:1]
		if c == '4':
			raise error_temp, resp
		if c == '5':
			raise error_perm, resp
		if c not in '123':
			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()
		if resp[:3] not in LONGRESP:
			raise error_reply, resp
		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()

	# Process a NEWGROUPS command.  Arguments:
	# - date: string 'yymmdd' indicating the date
	# - time: string 'hhmmss' indicating the time
	# Return:
	# - resp: server response if succesful
	# - list: list of newsgroup names

	def newgroups(self, date, time):
		return self.longcmd('NEWGROUPS ' + date + ' ' + time)

	# Process a NEWNEWS command.  Arguments:
	# - group: group name or '*'
	# - date: string 'yymmdd' indicating the date
	# - time: string 'hhmmss' indicating the time
	# Return:
	# - resp: server response if succesful
	# - list: list of article ids

	def newnews(self, group, date, time):
		cmd = 'NEWNEWS ' + group + ' ' + date + ' ' + time
		return self.longcmd(cmd)

	# Process a LIST command.  Return:
	# - resp: server response if succesful
	# - list: list of (group, last, first, flag) (strings)

	def list(self):
		resp, list = self.longcmd('LIST')
		for i in range(len(list)):
			# Parse lines into "group last first flag"
			list[i] = tuple(string.split(list[i]))
		return resp, list

	# Process a GROUP command.  Argument:
	# - group: the group name
	# Returns:
	# - resp: server response if succesful
	# - count: number of articles (string)
	# - first: first article number (string)
	# - last: last article number (string)
	# - name: the group name

	def group(self, name):
		resp = self.shortcmd('GROUP ' + name)
		if resp[:3] <> '211':
			raise error_reply, resp
		words = string.split(resp)
		count = first = last = 0
		n = len(words)
		if n > 1:
			count = words[1]
			if n > 2:
				first = words[2]
				if n > 3:
					last = words[3]
					if n > 4:
						name = string.lower(words[4])
		return resp, count, first, last, name

	# Process a HELP command.  Returns:
	# - resp: server response if succesful
	# - list: list of strings

	def help(self):
		return self.longcmd('HELP')

	# Internal: parse the response of a STAT, NEXT or LAST command
	def statparse(self, resp):
		if resp[:2] <> '22':
			raise error_reply, resp
		words = string.split(resp)
		nr = 0
		id = ''
		n = len(words)
		if n > 1:
			nr = words[1]
			if n > 2:
				id = string.lower(words[2])
		return resp, nr, id

	# Internal: process a STAT, NEXT or LAST command
	def statcmd(self, line):
		resp = self.shortcmd(line)
		return self.statparse(resp)

	# Process a STAT command.  Argument:
	# - id: article number or message id
	# Returns:
	# - resp: server response if succesful
	# - nr:   the article number
	# - id:   the article id

	def stat(self, id):
		return self.statcmd('STAT ' + id)

	# Process a NEXT command.  No arguments.  Return as for STAT

	def next(self):
		return self.statcmd('NEXT')

	# Process a LAST command.  No arguments.  Return as for STAT

	def last(self):
		return self.statcmd('LAST')

	# Internal: process a HEAD, BODY or ARTICLE command
	def artcmd(self, line):
		resp, list = self.longcmd(line)
		resp, nr, id = self.statparse(resp)
		return resp, nr, id, list

	# Process a HEAD command.  Argument:
	# - id: article number or message id
	# Returns:
	# - resp: server response if succesful
	# - list: the lines of the article's header

	def head(self, id):
		return self.artcmd('HEAD ' + id)

	# Process a BODY command.  Argument:
	# - id: article number or message id
	# Returns:
	# - resp: server response if succesful
	# - list: the lines of the article's body

	def body(self, id):
		return self.artcmd('BODY ' + id)

	# Process an ARTICLE command.  Argument:
	# - id: article number or message id
	# Returns:
	# - resp: server response if succesful
	# - list: the lines of the article

	def article(self, id):
		return self.artcmd('ARTICLE ' + id)

	# Process a SLAVE command.  Returns:
	# - resp: server response if succesful

	def slave(self):
		return self.shortcmd('SLAVE')

	# Process an XHDR command (optional server extension).  Arguments:
	# - hdr: the header type (e.g. 'subject')
	# - str: an article nr, a message id, or a range nr1-nr2
	# Returns:
	# - resp: server response if succesful
	# - list: list of (nr, value) strings

	def xhdr(self, hdr, str):
		resp, lines = self.longcmd('XHDR ' + hdr + ' ' + str)
		for i in range(len(lines)):
			line = lines[i]
			n = regex.match('^[0-9]+', line)
			nr = line[:n]
			if n < len(line) and line[n] == ' ': n = n+1
			lines[i] = (nr, line[n:])
		return resp, lines

	# Process an XOVER command (optional server extension) Arguments:
	# - start: start of range
	# - end: end of range
	# Returns:
	# - resp: server response if succesful
	# - list: list of (art-nr, subject, poster, date, id, refrences, size, lines)

	def xover(self,start,end):
		resp, lines = self.longcmd('XOVER ' + start + '-' + end)
		xover_lines = []
		for line in lines:
			elem = string.splitfields(line,"\t")
			try:
				xover_lines.append((elem[0],
						    elem[1],
						    elem[2],
						    elem[3],
						    elem[4],
						    string.split(elem[5]),
						    elem[6],
						    elem[7]))
			except IndexError:
				raise error_data,line
		return resp,xover_lines

	# Process an XGTITLE command (optional server extension) Arguments:
	# - group: group name wildcard (i.e. news.*)
	# Returns:
	# - resp: server response if succesful
	# - list: list of (name,title) strings

	def xgtitle(self, group):
		line_pat = regex.compile("^\([^ \t]+\)[ \t]+\(.*\)$")
		resp, raw_lines = self.longcmd('XGTITLE ' + group)
		lines = []
		for raw_line in raw_lines:
			if line_pat.search(string.strip(raw_line)) == 0:
				lines.append(line_pat.group(1),
					     line_pat.group(2))

		return resp, lines

	# Process an XPATH command (optional server extension) Arguments:
	# - id: Message id of article
	# Returns:
	# resp: server response if succesful
	# path: directory path to article

	def xpath(self,id):
		resp = self.shortcmd("XPATH " + id)
		if resp[:3] <> '223':
			raise error_reply, resp
		try:
			[resp_num, path] = string.split(resp)
		except ValueError:
			raise error_reply, resp
		else:
			return resp, path

	# Process the DATE command. Arguments:
	# None
	# Returns:
	# resp: server response if succesful
	# date: Date suitable for newnews/newgroups commands etc.
	# time: Time suitable for newnews/newgroups commands etc.

	def date (self):
		resp = self.shortcmd("DATE")
		if resp[:3] <> '111':
			raise error_reply, resp
		elem = string.split(resp)
		if len(elem) != 2:
			raise error_data, resp
		date = elem[1][2:8]
		time = elem[1][-6:]
		if len(date) != 6 or len(time) != 6:
			raise error_data, resp
		return resp, date, time


	# Process a POST command.  Arguments:
	# - f: file containing the article
	# Returns:
	# - resp: server response if succesful

	def post(self, f):
		resp = self.shortcmd('POST')
		# Raises error_??? if posting is not allowed
		if resp[0] <> '3':
			raise error_reply, resp
		while 1:
			line = f.readline()
			if not line:
				break
			if line[-1] == '\n':
				line = line[:-1]
			if line == '.':
				line = '..'
			self.putline(line)
		self.putline('.')
		return self.getresp()

	# Process an IHAVE command.  Arguments:
	# - id: message-id of the article
	# - f:  file containing the article
	# Returns:
	# - resp: server response if succesful
	# Note that if the server refuses the article an exception is raised

	def ihave(self, id, f):
		resp = self.shortcmd('IHAVE ' + id)
		# Raises error_??? if the server already has it
		if resp[0] <> '3':
			raise error_reply, resp
		while 1:
			line = f.readline()
			if not line:
				break
			if line[-1] == '\n':
				line = line[:-1]
			if line == '.':
				line = '..'
			self.putline(line)
		self.putline('.')
		return self.getresp()

	 # Process a QUIT command and close the socket.  Returns:
	 # - resp: server response if succesful

	def quit(self):
		resp = self.shortcmd('QUIT')
		self.file.close()
		self.sock.close()
		del self.file, self.sock
		return resp
