Commit a2685409 authored by Guido van Rossum's avatar Guido van Rossum

- Several methods of nntplib.NNTP have grown an optional file argument

  which specifies a file where to divert the command's output
  (already supported by the body() method).  (SF patch #720468)
  Thanks to Terry Carroll.
parent 8d98d2cb
...@@ -132,23 +132,35 @@ logging each line sent and received on the connection (including ...@@ -132,23 +132,35 @@ logging each line sent and received on the connection (including
message text). message text).
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{newgroups}{date, time} \begin{methoddesc}{newgroups}{date, time, \optional{file}}
Send a \samp{NEWGROUPS} command. The \var{date} argument should be a Send a \samp{NEWGROUPS} command. The \var{date} argument should be a
string of the form \code{'\var{yy}\var{mm}\var{dd}'} indicating the string of the form \code{'\var{yy}\var{mm}\var{dd}'} indicating the
date, and \var{time} should be a string of the form date, and \var{time} should be a string of the form
\code{'\var{hh}\var{mm}\var{ss}'} indicating the time. Return a pair \code{'\var{hh}\var{mm}\var{ss}'} indicating the time. Return a pair
\code{(\var{response}, \var{groups})} where \var{groups} is a list of \code{(\var{response}, \var{groups})} where \var{groups} is a list of
group names that are new since the given date and time. group names that are new since the given date and time.
If the \var{file} parameter is supplied, then the output of the
\samp{NEWGROUPS} command is stored in a file. If \var{file} is a string,
then the method will open a file object with that name, write to it
then close it. If \var{file} is a file object, then it will start
calling \method{write()} on it to store the lines of the command output.
If \var{file} is supplied, then the returned \var{list} is an empty list.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{newnews}{group, date, time} \begin{methoddesc}{newnews}{group, date, time, \optional{file}}
Send a \samp{NEWNEWS} command. Here, \var{group} is a group name or Send a \samp{NEWNEWS} command. Here, \var{group} is a group name or
\code{'*'}, and \var{date} and \var{time} have the same meaning as for \code{'*'}, and \var{date} and \var{time} have the same meaning as for
\method{newgroups()}. Return a pair \code{(\var{response}, \method{newgroups()}. Return a pair \code{(\var{response},
\var{articles})} where \var{articles} is a list of article ids. \var{articles})} where \var{articles} is a list of article ids.
If the \var{file} parameter is supplied, then the output of the
\samp{NEWNEWS} command is stored in a file. If \var{file} is a string,
then the method will open a file object with that name, write to it
then close it. If \var{file} is a file object, then it will start
calling \method{write()} on it to store the lines of the command output.
If \var{file} is supplied, then the returned \var{list} is an empty list.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{list}{} \begin{methoddesc}{list}{\optional{file}}
Send a \samp{LIST} command. Return a pair \code{(\var{response}, Send a \samp{LIST} command. Return a pair \code{(\var{response},
\var{list})} where \var{list} is a list of tuples. Each tuple has the \var{list})} where \var{list} is a list of tuples. Each tuple has the
form \code{(\var{group}, \var{last}, \var{first}, \var{flag})}, where form \code{(\var{group}, \var{last}, \var{first}, \var{flag})}, where
...@@ -157,6 +169,12 @@ and first article numbers (as strings), and \var{flag} is ...@@ -157,6 +169,12 @@ and first article numbers (as strings), and \var{flag} is
\code{'y'} if posting is allowed, \code{'n'} if not, and \code{'m'} if \code{'y'} if posting is allowed, \code{'n'} if not, and \code{'m'} if
the newsgroup is moderated. (Note the ordering: \var{last}, the newsgroup is moderated. (Note the ordering: \var{last},
\var{first}.) \var{first}.)
If the \var{file} parameter is supplied, then the output of the
\samp{LIST} command is stored in a file. If \var{file} is a string,
then the method will open a file object with that name, write to it
then close it. If \var{file} is a file object, then it will start
calling \method{write()} on it to store the lines of the command output.
If \var{file} is supplied, then the returned \var{list} is an empty list.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{group}{name} \begin{methoddesc}{group}{name}
...@@ -168,9 +186,15 @@ the group, \var{last} is the last article number in the group, and ...@@ -168,9 +186,15 @@ the group, \var{last} is the last article number in the group, and
\var{name} is the group name. The numbers are returned as strings. \var{name} is the group name. The numbers are returned as strings.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{help}{} \begin{methoddesc}{help}{\optional{file}}
Send a \samp{HELP} command. Return a pair \code{(\var{response}, Send a \samp{HELP} command. Return a pair \code{(\var{response},
\var{list})} where \var{list} is a list of help strings. \var{list})} where \var{list} is a list of help strings.
If the \var{file} parameter is supplied, then the output of the
\samp{HELP} command is stored in a file. If \var{file} is a string,
then the method will open a file object with that name, write to it
then close it. If \var{file} is a file object, then it will start
calling \method{write()} on it to store the lines of the command output.
If \var{file} is supplied, then the returned \var{list} is an empty list.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{stat}{id} \begin{methoddesc}{stat}{id}
...@@ -205,7 +229,7 @@ the body is stored in a file. If \var{file} is a string, then ...@@ -205,7 +229,7 @@ the body is stored in a file. If \var{file} is a string, then
the method will open a file object with that name, write to it then close it. the method will open a file object with that name, write to it then close it.
If \var{file} is a file object, then it will start calling If \var{file} is a file object, then it will start calling
\method{write()} on it to store the lines of the body. \method{write()} on it to store the lines of the body.
Return as for \method{head()}. If \var{file} is supplied. Then Return as for \method{head()}. If \var{file} is supplied, then
the returned \var{list} is an empty list. the returned \var{list} is an empty list.
\end{methoddesc} \end{methoddesc}
...@@ -218,7 +242,7 @@ for \method{stat()}. Return as for \method{head()}. ...@@ -218,7 +242,7 @@ for \method{stat()}. Return as for \method{head()}.
Send a \samp{SLAVE} command. Return the server's \var{response}. Send a \samp{SLAVE} command. Return the server's \var{response}.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{xhdr}{header, string} \begin{methoddesc}{xhdr}{header, string, \optional{file}}
Send an \samp{XHDR} command. This command is not defined in the RFC Send an \samp{XHDR} command. This command is not defined in the RFC
but is a common extension. The \var{header} argument is a header but is a common extension. The \var{header} argument is a header
keyword, e.g. \code{'subject'}. The \var{string} argument should have keyword, e.g. \code{'subject'}. The \var{string} argument should have
...@@ -228,6 +252,12 @@ pair \code{(\var{response}, \var{list})}, where \var{list} is a list of ...@@ -228,6 +252,12 @@ pair \code{(\var{response}, \var{list})}, where \var{list} is a list of
pairs \code{(\var{id}, \var{text})}, where \var{id} is an article id pairs \code{(\var{id}, \var{text})}, where \var{id} is an article id
(as a string) and \var{text} is the text of the requested header for (as a string) and \var{text} is the text of the requested header for
that article. that article.
If the \var{file} parameter is supplied, then the output of the
\samp{XHDR} command is stored in a file. If \var{file} is a string,
then the method will open a file object with that name, write to it
then close it. If \var{file} is a file object, then it will start
calling \method{write()} on it to store the lines of the command output.
If \var{file} is supplied, then the returned \var{list} is an empty list.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{post}{file} \begin{methoddesc}{post}{file}
...@@ -251,21 +281,33 @@ This is an optional NNTP extension, and may not be supported by all ...@@ -251,21 +281,33 @@ This is an optional NNTP extension, and may not be supported by all
servers. servers.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{xgtitle}{name} \begin{methoddesc}{xgtitle}{name, \optional{file}}
Process an \samp{XGTITLE} command, returning a pair \code{(\var{response}, Process an \samp{XGTITLE} command, returning a pair \code{(\var{response},
\var{list})}, where \var{list} is a list of tuples containing \var{list})}, where \var{list} is a list of tuples containing
\code{(\var{name}, \var{title})}. \code{(\var{name}, \var{title})}.
% XXX huh? Should that be name, description? % XXX huh? Should that be name, description?
If the \var{file} parameter is supplied, then the output of the
\samp{XGTITLE} command is stored in a file. If \var{file} is a string,
then the method will open a file object with that name, write to it
then close it. If \var{file} is a file object, then it will start
calling \method{write()} on it to store the lines of the command output.
If \var{file} is supplied, then the returned \var{list} is an empty list.
This is an optional NNTP extension, and may not be supported by all This is an optional NNTP extension, and may not be supported by all
servers. servers.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{xover}{start, end} \begin{methoddesc}{xover}{start, end, \optional{file}}
Return a pair \code{(\var{resp}, \var{list})}. \var{list} is a list Return a pair \code{(\var{resp}, \var{list})}. \var{list} is a list
of tuples, one for each article in the range delimited by the \var{start} of tuples, one for each article in the range delimited by the \var{start}
and \var{end} article numbers. Each tuple is of the form and \var{end} article numbers. Each tuple is of the form
\code{(\var{article number}, \var{subject}, \var{poster}, \var{date}, \code{(\var{article number}, \var{subject}, \var{poster}, \var{date},
\var{id}, \var{references}, \var{size}, \var{lines})}. \var{id}, \var{references}, \var{size}, \var{lines})}.
If the \var{file} parameter is supplied, then the output of the
\samp{XOVER} command is stored in a file. If \var{file} is a string,
then the method will open a file object with that name, write to it
then close it. If \var{file} is a file object, then it will start
calling \method{write()} on it to store the lines of the command output.
If \var{file} is supplied, then the returned \var{list} is an empty list.
This is an optional NNTP extension, and may not be supported by all This is an optional NNTP extension, and may not be supported by all
servers. servers.
\end{methoddesc} \end{methoddesc}
......
...@@ -264,7 +264,7 @@ class NNTP: ...@@ -264,7 +264,7 @@ class NNTP:
self.putcmd(line) self.putcmd(line)
return self.getlongresp(file) return self.getlongresp(file)
def newgroups(self, date, time): def newgroups(self, date, time, file=None):
"""Process a NEWGROUPS command. Arguments: """Process a NEWGROUPS command. Arguments:
- date: string 'yymmdd' indicating the date - date: string 'yymmdd' indicating the date
- time: string 'hhmmss' indicating the time - time: string 'hhmmss' indicating the time
...@@ -272,9 +272,9 @@ class NNTP: ...@@ -272,9 +272,9 @@ class NNTP:
- resp: server response if successful - resp: server response if successful
- list: list of newsgroup names""" - list: list of newsgroup names"""
return self.longcmd('NEWGROUPS ' + date + ' ' + time) return self.longcmd('NEWGROUPS ' + date + ' ' + time, file)
def newnews(self, group, date, time): def newnews(self, group, date, time, file=None):
"""Process a NEWNEWS command. Arguments: """Process a NEWNEWS command. Arguments:
- group: group name or '*' - group: group name or '*'
- date: string 'yymmdd' indicating the date - date: string 'yymmdd' indicating the date
...@@ -284,14 +284,14 @@ class NNTP: ...@@ -284,14 +284,14 @@ class NNTP:
- list: list of article ids""" - list: list of article ids"""
cmd = 'NEWNEWS ' + group + ' ' + date + ' ' + time cmd = 'NEWNEWS ' + group + ' ' + date + ' ' + time
return self.longcmd(cmd) return self.longcmd(cmd, file)
def list(self): def list(self, file=None):
"""Process a LIST command. Return: """Process a LIST command. Return:
- resp: server response if successful - resp: server response if successful
- list: list of (group, last, first, flag) (strings)""" - list: list of (group, last, first, flag) (strings)"""
resp, list = self.longcmd('LIST') resp, list = self.longcmd('LIST', file)
for i in range(len(list)): for i in range(len(list)):
# Parse lines into "group last first flag" # Parse lines into "group last first flag"
list[i] = tuple(list[i].split()) list[i] = tuple(list[i].split())
...@@ -323,12 +323,12 @@ class NNTP: ...@@ -323,12 +323,12 @@ class NNTP:
name = words[4].lower() name = words[4].lower()
return resp, count, first, last, name return resp, count, first, last, name
def help(self): def help(self, file=None):
"""Process a HELP command. Returns: """Process a HELP command. Returns:
- resp: server response if successful - resp: server response if successful
- list: list of strings""" - list: list of strings"""
return self.longcmd('HELP') return self.longcmd('HELP',file)
def statparse(self, resp): def statparse(self, resp):
"""Internal: parse the response of a STAT, NEXT or LAST command.""" """Internal: parse the response of a STAT, NEXT or LAST command."""
...@@ -414,7 +414,7 @@ class NNTP: ...@@ -414,7 +414,7 @@ class NNTP:
return self.shortcmd('SLAVE') return self.shortcmd('SLAVE')
def xhdr(self, hdr, str): def xhdr(self, hdr, str, file=None):
"""Process an XHDR command (optional server extension). Arguments: """Process an XHDR command (optional server extension). Arguments:
- hdr: the header type (e.g. 'subject') - hdr: the header type (e.g. 'subject')
- str: an article nr, a message id, or a range nr1-nr2 - str: an article nr, a message id, or a range nr1-nr2
...@@ -423,7 +423,7 @@ class NNTP: ...@@ -423,7 +423,7 @@ class NNTP:
- list: list of (nr, value) strings""" - list: list of (nr, value) strings"""
pat = re.compile('^([0-9]+) ?(.*)\n?') pat = re.compile('^([0-9]+) ?(.*)\n?')
resp, lines = self.longcmd('XHDR ' + hdr + ' ' + str) resp, lines = self.longcmd('XHDR ' + hdr + ' ' + str, file)
for i in range(len(lines)): for i in range(len(lines)):
line = lines[i] line = lines[i]
m = pat.match(line) m = pat.match(line)
...@@ -431,7 +431,7 @@ class NNTP: ...@@ -431,7 +431,7 @@ class NNTP:
lines[i] = m.group(1, 2) lines[i] = m.group(1, 2)
return resp, lines return resp, lines
def xover(self,start,end): def xover(self, start, end, file=None):
"""Process an XOVER command (optional server extension) Arguments: """Process an XOVER command (optional server extension) Arguments:
- start: start of range - start: start of range
- end: end of range - end: end of range
...@@ -440,7 +440,7 @@ class NNTP: ...@@ -440,7 +440,7 @@ class NNTP:
- list: list of (art-nr, subject, poster, date, - list: list of (art-nr, subject, poster, date,
id, references, size, lines)""" id, references, size, lines)"""
resp, lines = self.longcmd('XOVER ' + start + '-' + end) resp, lines = self.longcmd('XOVER ' + start + '-' + end, file)
xover_lines = [] xover_lines = []
for line in lines: for line in lines:
elem = line.split("\t") elem = line.split("\t")
...@@ -457,7 +457,7 @@ class NNTP: ...@@ -457,7 +457,7 @@ class NNTP:
raise NNTPDataError(line) raise NNTPDataError(line)
return resp,xover_lines return resp,xover_lines
def xgtitle(self, group): def xgtitle(self, group, file=None):
"""Process an XGTITLE command (optional server extension) Arguments: """Process an XGTITLE command (optional server extension) Arguments:
- group: group name wildcard (i.e. news.*) - group: group name wildcard (i.e. news.*)
Returns: Returns:
...@@ -465,7 +465,7 @@ class NNTP: ...@@ -465,7 +465,7 @@ class NNTP:
- list: list of (name,title) strings""" - list: list of (name,title) strings"""
line_pat = re.compile("^([^ \t]+)[ \t]+(.*)$") line_pat = re.compile("^([^ \t]+)[ \t]+(.*)$")
resp, raw_lines = self.longcmd('XGTITLE ' + group) resp, raw_lines = self.longcmd('XGTITLE ' + group, file)
lines = [] lines = []
for raw_line in raw_lines: for raw_line in raw_lines:
match = line_pat.search(raw_line.strip()) match = line_pat.search(raw_line.strip())
......
...@@ -86,6 +86,7 @@ Ralph Butler ...@@ -86,6 +86,7 @@ Ralph Butler
Daniel Calvelo Daniel Calvelo
Brett Cannon Brett Cannon
Mike Carlton Mike Carlton
Terry Carroll
Luke Kenneth Casson Leighton Luke Kenneth Casson Leighton
Donn Cave Donn Cave
Per Cederqvist Per Cederqvist
......
...@@ -118,6 +118,10 @@ Extension modules ...@@ -118,6 +118,10 @@ Extension modules
Library Library
------- -------
- Several methods of nntplib.NNTP have grown an optional file argument
which specifies a file where to divert the command's output
(already supported by the body() method). (SF patch #720468)
- The self-documenting XML server library DocXMLRPCServer was added. - The self-documenting XML server library DocXMLRPCServer was added.
- Support for internationalized domain names has been added through - Support for internationalized domain names has been added through
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment