[Patches] Re: [Mailman-Developers] Bug#57223: mailman: gate_news problems (fwd)
bwarsaw@cnri.reston.va.us
bwarsaw@cnri.reston.va.us
Tue, 8 Feb 2000 18:18:14 -0500 (EST)
Okay, here's my proposed patch to the current CVS version of
nntplib.py. It merges Jim's and Thomas's patches, and re-implements
the module's exceptions as class-based (with backwards compatibility).
I'm not sure what to do about the email disclaimers, but I'd say to be
safe that both Jim and Thomas should re-submit their patches with the
disclaimer attached (you can just to this to patches@python.org).
Everyone else on patches@python.org: please let me know if you have
any objections to this change. Otherwise, I'll commit it (and make
the necessary documentation updates).
-Barry
-------------------- snip snip --------------------
Index: nntplib.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/nntplib.py,v
retrieving revision 1.17
diff -c -r1.17 nntplib.py
*** nntplib.py 2000/02/04 15:10:33 1.17
--- nntplib.py 2000/02/08 23:11:44
***************
*** 34,47 ****
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
--- 34,79 ----
import string
!
! # Exceptions raised when an error or invalid response is received
! class NNTPError(Exception):
! """Base class for all nntplib exceptions"""
! def __init__(self, *args):
! apply(Exception.__init__, (self,)+args)
! try:
! self.response = args[0]
! except IndexError:
! self.response = 'No response given'
!
! class NNTPReplyError(NNTPError):
! """Unexpected [123]xx reply"""
! pass
!
! class NNTPTemporaryError(NNTPError):
! """4xx errors"""
! pass
!
! class NNTPPermanentError(NNTPError):
! """5xx errors"""
! pass
!
! class NNTPProtocolError(NNTPError):
! """Response does not begin with [1-5]"""
! pass
!
! class NNTPDataError(NNTPError):
! """Error in response data"""
! pass
!
! # for backwards compatibility
! error_reply = NNTPReplyError
! error_temp = NNTPTemporaryError
! error_perm = NNTPPermanentError
! error_proto = NNTPProtocolError
! error_data = NNTPDataError
+
# Standard port used by NNTP servers
NNTP_PORT = 119
***************
*** 54,68 ****
CRLF = '\r\n'
# The class itself
-
class NNTP:
!
! def __init__(self, host, port = NNTP_PORT, user=None, password=None):
"""Initialize an instance. Arguments:
- host: hostname to connect to
! - port: port to connect to (default the standard NNTP port)"""
!
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
--- 86,108 ----
CRLF = '\r\n'
+
# The class itself
class NNTP:
! def __init__(self, host, port = NNTP_PORT, user=None, password=None,
! readermode=None):
"""Initialize an instance. Arguments:
- host: hostname to connect to
! - port: port to connect to (default the standard NNTP port)
! - user: username to authenticate with
! - password: password to use with username
! - readermode: if true, send 'mode reader' command after
! connecting.
!
! readermode is sometimes necessary if you are connecting to an
! NNTP server on your local machine and intend to call the
! group() method.
! """
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
***************
*** 70,85 ****
self.file = self.sock.makefile('rb')
self.debugging = 0
self.welcome = self.getresp()
if user:
resp = self.shortcmd('authinfo user '+user)
if resp[:3] == '381':
if not password:
! raise error_reply, resp
else:
resp = self.shortcmd(
'authinfo pass '+password)
if resp[:3] != '281':
! raise error_perm, resp
def getwelcome(self):
"""Get the welcome message from the server
--- 110,136 ----
self.file = self.sock.makefile('rb')
self.debugging = 0
self.welcome = self.getresp()
+ if readermode:
+ try:
+ self.welcome = self.shortcmd('mode reader')
+ except NNTPPermanentError:
+ # error 500, probably 'not implemented'
+ pass
if user:
resp = self.shortcmd('authinfo user '+user)
if resp[:3] == '381':
if not password:
! raise NNTPReplyError(resp)
else:
resp = self.shortcmd(
'authinfo pass '+password)
if resp[:3] != '281':
! raise NNTPPermanentError(resp)
!
! # 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):
"""Get the welcome message from the server
***************
*** 128,138 ****
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
def getlongresp(self):
--- 179,189 ----
if self.debugging: print '*resp*', `resp`
c = resp[:1]
if c == '4':
! raise NNTPTemporaryError(resp)
if c == '5':
! raise NNTPPermanentError(resp)
if c not in '123':
! raise NNTPProtocolError(resp)
return resp
def getlongresp(self):
***************
*** 140,146 ****
Raise various errors if the response indicates an error."""
resp = self.getresp()
if resp[:3] not in LONGRESP:
! raise error_reply, resp
list = []
while 1:
line = self.getline()
--- 191,197 ----
Raise various errors if the response indicates an error."""
resp = self.getresp()
if resp[:3] not in LONGRESP:
! raise NNTPReplyError(resp)
list = []
while 1:
line = self.getline()
***************
*** 206,212 ****
resp = self.shortcmd('GROUP ' + name)
if resp[:3] <> '211':
! raise error_reply, resp
words = string.split(resp)
count = first = last = 0
n = len(words)
--- 257,263 ----
resp = self.shortcmd('GROUP ' + name)
if resp[:3] <> '211':
! raise NNTPReplyError(resp)
words = string.split(resp)
count = first = last = 0
n = len(words)
***************
*** 230,236 ****
def statparse(self, resp):
"""Internal: parse the response of a STAT, NEXT or LAST command."""
if resp[:2] <> '22':
! raise error_reply, resp
words = string.split(resp)
nr = 0
id = ''
--- 281,287 ----
def statparse(self, resp):
"""Internal: parse the response of a STAT, NEXT or LAST command."""
if resp[:2] <> '22':
! raise NNTPReplyError(resp)
words = string.split(resp)
nr = 0
id = ''
***************
*** 349,355 ****
elem[6],
elem[7]))
except IndexError:
! raise error_data,line
return resp,xover_lines
def xgtitle(self, group):
--- 400,406 ----
elem[6],
elem[7]))
except IndexError:
! raise NNTPDataError(line)
return resp,xover_lines
def xgtitle(self, group):
***************
*** 377,387 ****
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
--- 428,438 ----
resp = self.shortcmd("XPATH " + id)
if resp[:3] <> '223':
! raise NNTPReplyError(resp)
try:
[resp_num, path] = string.split(resp)
except ValueError:
! raise NNTPReplyError(resp)
else:
return resp, path
***************
*** 395,408 ****
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
--- 446,459 ----
resp = self.shortcmd("DATE")
if resp[:3] <> '111':
! raise NNTPReplyError(resp)
elem = string.split(resp)
if len(elem) != 2:
! raise NNTPDataError(resp)
date = elem[1][2:8]
time = elem[1][-6:]
if len(date) != 6 or len(time) != 6:
! raise NNTPDataError(resp)
return resp, date, time
***************
*** 415,421 ****
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:
--- 466,472 ----
resp = self.shortcmd('POST')
# Raises error_??? if posting is not allowed
if resp[0] <> '3':
! raise NNTPReplyError(resp)
while 1:
line = f.readline()
if not line:
***************
*** 439,445 ****
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:
--- 490,496 ----
resp = self.shortcmd('IHAVE ' + id)
# Raises error_??? if the server already has it
if resp[0] <> '3':
! raise NNTPReplyError(resp)
while 1:
line = f.readline()
if not line:
***************
*** 465,471 ****
def _test():
"""Minimal test function."""
! s = NNTP('news')
resp, count, first, last, name = s.group('comp.lang.python')
print resp
print 'Group', name, 'has', count, 'articles, range', first, 'to', last
--- 516,522 ----
def _test():
"""Minimal test function."""
! s = NNTP('news', readermode='reader')
resp, count, first, last, name = s.group('comp.lang.python')
print resp
print 'Group', name, 'has', count, 'articles, range', first, 'to', last