Contributions by Eric Raymond: documentation for modules
cmd, multifile and smtplib.
This commit is contained in:
parent
911ec188c8
commit
8668e8e49c
|
@ -109,6 +109,7 @@ add new extensions to Python and how to embed it in other applications.
|
||||||
\input{libarray}
|
\input{libarray}
|
||||||
\input{libfileinput}
|
\input{libfileinput}
|
||||||
\input{libcalendar}
|
\input{libcalendar}
|
||||||
|
\input{libcmd}
|
||||||
|
|
||||||
\input{liballos} % Generic Operating System Services
|
\input{liballos} % Generic Operating System Services
|
||||||
\input{libos}
|
\input{libos}
|
||||||
|
@ -161,6 +162,7 @@ add new extensions to Python and how to embed it in other applications.
|
||||||
\input{libpoplib}
|
\input{libpoplib}
|
||||||
\input{libimaplib}
|
\input{libimaplib}
|
||||||
\input{libnntplib}
|
\input{libnntplib}
|
||||||
|
\input{libsmtplib}
|
||||||
\input{liburlparse}
|
\input{liburlparse}
|
||||||
\input{libsgmllib}
|
\input{libsgmllib}
|
||||||
\input{libhtmllib}
|
\input{libhtmllib}
|
||||||
|
@ -168,6 +170,7 @@ add new extensions to Python and how to embed it in other applications.
|
||||||
\input{libformatter}
|
\input{libformatter}
|
||||||
\input{librfc822}
|
\input{librfc822}
|
||||||
\input{libmimetools}
|
\input{libmimetools}
|
||||||
|
\input{libmultifile}
|
||||||
\input{libbinhex}
|
\input{libbinhex}
|
||||||
\input{libuu}
|
\input{libuu}
|
||||||
\input{libbinascii}
|
\input{libbinascii}
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
% Documentation by ESR
|
||||||
|
\section{Standard Module \module{cmd}}
|
||||||
|
\stmodindex{cmd}
|
||||||
|
\label{module-cmd}
|
||||||
|
|
||||||
|
The \code{Cmd} class provides a simple framework for writing
|
||||||
|
line-oriented command interpreters. These are often useful for
|
||||||
|
test harnesses, administrative tools, and prototypes that will
|
||||||
|
later be wrapped in a more sophisticated interface.
|
||||||
|
|
||||||
|
\begin{classdesc}{Cmd}{}
|
||||||
|
A \class{Cmd} instance or subclass instance is a line-oriented
|
||||||
|
interpreter framework. There is no good reason to instantiate Cmd
|
||||||
|
itself; rather, it's useful as a superclass of an interpreter class
|
||||||
|
you define yourself in order to inherit Cmd's methods and encapsulate
|
||||||
|
action functions.
|
||||||
|
\end{classdesc}
|
||||||
|
|
||||||
|
\subsection{Cmd Objects}
|
||||||
|
\label{Cmd-objects}
|
||||||
|
|
||||||
|
A \class{Cmd} instance has the following methods:
|
||||||
|
|
||||||
|
\begin{methoddesc}{cmdloop}{intro}
|
||||||
|
Repeatedly issue a prompt, accept input, parse an initial prefix off
|
||||||
|
the received input, and dispatch to action methods, passing them the
|
||||||
|
remainder of the line as argument.
|
||||||
|
|
||||||
|
The optional argument is a banner or intro string to be issued before the
|
||||||
|
first prompt (this overrides the \member{intro} class member).
|
||||||
|
|
||||||
|
If the \module{readline} module is loaded, input will automatically
|
||||||
|
inherit Emacs-like history-list editing (e.g. Ctrl-P scrolls back to
|
||||||
|
the last command, Ctrl-N forward to the next one, Ctrl-F moves the
|
||||||
|
cursor to the right non-destructively, Ctrl-B moves the cursor to the
|
||||||
|
left non-destructively, etc.).
|
||||||
|
|
||||||
|
An end-of-file on input is passed back as the string "EOF".
|
||||||
|
|
||||||
|
An interpreter instance will recognize a command name \code{foo} if
|
||||||
|
and only if it has a method named \method{do_foo}. As a special case,
|
||||||
|
a line containing only the character `?' is dispatched to the method
|
||||||
|
\method{do_help}. As another special case, a line containing only the
|
||||||
|
character `!' is dispatched to the method \method{do_shell} (if such a method
|
||||||
|
is defined).
|
||||||
|
|
||||||
|
All subclasses of \class{Cmd} inherit a predefined \method{do_help}.
|
||||||
|
This method, called with an argument \code{bar}, invokes the
|
||||||
|
corresponding method \method{help_bar}. With no argument,
|
||||||
|
\method{do_help} lists all available help topics (that is, all
|
||||||
|
commands with corresponding \code{help_} methods), and also lists any
|
||||||
|
undocumented commands.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{onecmd}{str}
|
||||||
|
Interpret the argument as though it had been typed in in
|
||||||
|
response to the prompt.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{emptyline}{}
|
||||||
|
Method called when an empty line is entered in response to the prompt.
|
||||||
|
If this method is not overridden, it repeats the last nonempty command
|
||||||
|
entered.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{default}{line}
|
||||||
|
Method called on an input line when the command prefix is not
|
||||||
|
recognized. If this method is not overridden, it prints an
|
||||||
|
error message and returns.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{precmd}
|
||||||
|
Hook method executed just before the input prompt is issued. This method is
|
||||||
|
a stub in \class{Cmd}; it exists to be overridden by subclasses.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{postcmd}
|
||||||
|
Hook method executed just after a command dispatch is finished. This
|
||||||
|
method is a stub in \class{Cmd}; it exists to be overridden by
|
||||||
|
subclasses.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{preloop}
|
||||||
|
Hook method executed once when \method{cmdloop()} is called. This method is
|
||||||
|
a stub in \class{Cmd}; it exists to be overridden by subclasses.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{postloop}
|
||||||
|
Hook method executed once when \method{cmdloop()} is about to return. This
|
||||||
|
method is a stub in \class{Cmd}; it exists to be overridden by
|
||||||
|
subclasses.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
Instances of \class{Cmd} subclasses have some public instance variables:
|
||||||
|
|
||||||
|
\begin{memberdesc}{prompt}
|
||||||
|
The prompt issued to solicit input.
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{identchars}
|
||||||
|
The string of characters accepted for the command prefix.
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{lastcmd}
|
||||||
|
The last nonempty command prefix seen.
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{intro}
|
||||||
|
A string to issue as an intro or banner. May be overridden by giving
|
||||||
|
the \method{cmdloop()} method an argument.
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{doc_header}
|
||||||
|
The header to issue if the help output has a section for documented commands.
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{misc_header}
|
||||||
|
The header to issue if the help output has a section for miscellaneous
|
||||||
|
help topics (that is, there are \code{help_} methods withoud corresponding
|
||||||
|
\code{do_} functions).
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{undoc_header}
|
||||||
|
The header to issue if the help output has a section for undocumented
|
||||||
|
commands (that is, there are \code{do_} methods withoud corresponding
|
||||||
|
\code{help_} functions).
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{ruler}
|
||||||
|
The character used to draw separator lines under the help-message
|
||||||
|
headers. If empty, no ruler line is drawn. It defaults to "=".
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
% Documentation by ESR
|
||||||
|
\section{Standard Module \module{multifile}}
|
||||||
|
\stmodindex{multiFile}
|
||||||
|
\label{module-multifile}
|
||||||
|
|
||||||
|
The \code{MultiFile} object enables you to treat sections of a text
|
||||||
|
file as file-like input objects, with EOF being returned by
|
||||||
|
\code{readline} when a given delimiter pattern is encountered. The
|
||||||
|
defaults of this class are designed to make it useful for parsing
|
||||||
|
MIME multipart messages, but by subclassing it and overriding methods
|
||||||
|
it can be easily adapted for more general use.
|
||||||
|
|
||||||
|
\begin{classdesc}{MultiFile}{fp[, seekable=1]}
|
||||||
|
Create a multi-file. You must instantiate this class with an input
|
||||||
|
object argument for MultiFile to get lines from, such as as a file
|
||||||
|
object returned by \code{open}.
|
||||||
|
|
||||||
|
MultiFile only ever looks at the input object's \code{readline},
|
||||||
|
\code{seek} and \code{tell} methods, and the latter two are only
|
||||||
|
needed if you want to random-access the multifile sections. To use
|
||||||
|
MultiFile on a non-seekable stream object, set the optional seekable
|
||||||
|
argument to 0; this will avoid using the input object's \code{seek}
|
||||||
|
and \code{tell} at all.
|
||||||
|
\end{classdesc}
|
||||||
|
|
||||||
|
It will be useful to know that in MultiFile's view of the world, text
|
||||||
|
is composed of three kinds of lines: data, section-dividers, and
|
||||||
|
end-markers. MultiFile is designed to support parsing of
|
||||||
|
messages that may have multiple nested message parts, each with its
|
||||||
|
own pattern for section-divider and end-marker lines.
|
||||||
|
|
||||||
|
\subsection{MultiFile Objects}
|
||||||
|
\label{MultiFile-objects}
|
||||||
|
|
||||||
|
A \class{MultiFile} instance has the following methods:
|
||||||
|
|
||||||
|
\begin{methoddesc}{push}{str}
|
||||||
|
Push a boundary string. When an appropriately decorated version of
|
||||||
|
this boundary is found as an input line, it will be interpreted as a
|
||||||
|
section-divider or end-marker and passed back as EOF. All subsequent
|
||||||
|
reads will also be passed back as EOF, until a \method{pop} removes
|
||||||
|
the boundary a or \method{next} call reenables it.
|
||||||
|
|
||||||
|
It is possible to push more than one boundary. Encountering the
|
||||||
|
most-recently-pushed boundary will return EOF; encountering any other
|
||||||
|
boundary will raise an error.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{readline}{str}
|
||||||
|
Read a line. If the line is data (not a section-divider or end-marker
|
||||||
|
or real EOF) return it. If the line matches the most-recently-stacked
|
||||||
|
boundary, return EOF and set \code{self.last} to 1 or 0 according as
|
||||||
|
the match is or is not an end-marker. If the line matches any other
|
||||||
|
stacked boundary, raise an error. If the line is a real EOF, raise an
|
||||||
|
error unless all boundaries have been popped.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{readlines}{str}
|
||||||
|
Read all lines, up to the next section. Return them as a list of strings
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{read}{str}
|
||||||
|
Read all lines, up to the next section. Return them as a single
|
||||||
|
(multiline) string. Note that this doesn't take a size argument!
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{next}{str}
|
||||||
|
Skip lines to the next section (that is, read lines until a
|
||||||
|
section-divider or end-marker has been consumed). Return 1 if there
|
||||||
|
is such a section, 0 if an end-marker is seen. Re-enable the
|
||||||
|
most-recently-pushed boundary.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{pop}{str}
|
||||||
|
Pop a section boundary. This boundary will no longer be interpreted as EOF.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{seek}{str, pos, whence=0}
|
||||||
|
Seek. Seek indices are relative to the start of the current section.
|
||||||
|
The pos and whence arguments are interpreted as for a file seek.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{next}{str}
|
||||||
|
Tell. Tell indices are relative to the start of the current section.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{is_data}{str}
|
||||||
|
Return true if a 1 is certainly data and 0 if it might be a section
|
||||||
|
boundary. As written, it tests for a prefix other than '--' at start of
|
||||||
|
line (which all MIME boundaries have) but it is declared so it can be
|
||||||
|
overridden in derived classes.
|
||||||
|
|
||||||
|
Note that this test is used intended as a fast guard for the real
|
||||||
|
boundary tests; if it always returns 0 it will merely slow processing,
|
||||||
|
not cause it to fail.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{section_divider}{str}
|
||||||
|
Turn a boundary into a section-divider line. By default, this
|
||||||
|
method prepends '--' (which MIME section boundaries have) but it is
|
||||||
|
declared so it can be overridden in derived classes. This method
|
||||||
|
need not append LF or CR-LF, as comparison with the result ignores
|
||||||
|
trailing whitespace.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{end_marker}{str}
|
||||||
|
Turn a boundary string into an end-marker line. By default, this
|
||||||
|
method prepends '--' and appends '--' (like a MIME-multipart
|
||||||
|
end-of-message marker) but it is declared so it can be be overridden
|
||||||
|
in derived classes. This method need not append LF or CR-LF, as
|
||||||
|
comparison with the result ignores trailing whitespace.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
Finally, \class{MultiFile} instances have two public instance variables:
|
||||||
|
|
||||||
|
\begin{memberdesc}{level}
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
\begin{memberdesc}{last}
|
||||||
|
1 if the last EOF passed back was for an end-of-message marker, 0 otherwise.
|
||||||
|
\end{memberdesc}
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
fp = MultiFile(sys.stdin, 0)
|
||||||
|
fp.push(outer_boundary)
|
||||||
|
message1 = fp.readlines()
|
||||||
|
# We should now be either at real EOF or stopped on a message
|
||||||
|
# boundary. Re-enable the outer boundary.
|
||||||
|
fp.next()
|
||||||
|
# Read another message with the same delimiter
|
||||||
|
message2 = fp.readlines()
|
||||||
|
# Re-enable that delimiter again
|
||||||
|
fp.next()
|
||||||
|
# Now look for a message subpart with a different boundary
|
||||||
|
fp.push(inner_boundary)
|
||||||
|
sub_header = fp.readlines()
|
||||||
|
# If no exception has been thrown, we're looking at the start of
|
||||||
|
# the message subpart. Reset and grab the subpart
|
||||||
|
fp.next()
|
||||||
|
sub_body = fp.readlines()
|
||||||
|
# Got it. Now pop the inner boundary to re-enable the outer one.
|
||||||
|
fp.pop()
|
||||||
|
# Read to next outer boundary
|
||||||
|
message3 = fp.readlines()
|
||||||
|
\end{verbatim}
|
|
@ -0,0 +1,144 @@
|
||||||
|
% Documentation by ESR
|
||||||
|
\section{Standard Module \module{smtp}}
|
||||||
|
\stmodindex{smtp}
|
||||||
|
\label{module-smtp}
|
||||||
|
|
||||||
|
The \code{smtp} module defines an SMTP session object that can be used
|
||||||
|
to send mail to any Internet machine with an SMTP or ESMTP listener daemon.
|
||||||
|
For details of SMTP and ESMTP operation, consult RFC 821 (Simple Mail
|
||||||
|
Transfer Protocol) and RFC1869 (SMTP Service Extensions).
|
||||||
|
|
||||||
|
\begin{classdesc}{SMTP}{\optional{host, port}}
|
||||||
|
A \class{SMTP} instance encapsulates an SMTP connection. It has
|
||||||
|
methods that support a full repertoire of SMTP and ESMTP
|
||||||
|
operations. If the optional host and port parameters are given, the
|
||||||
|
SMTP connect method is called with those parameters during
|
||||||
|
initialization.
|
||||||
|
|
||||||
|
For normal use, you should only require the initialization/connect,
|
||||||
|
\var{sendmail}, and \var{quit} methods An example is included below.
|
||||||
|
\end{classdesc}
|
||||||
|
|
||||||
|
\subsection{SMTP Objects}
|
||||||
|
\label{SMTP-objects}
|
||||||
|
|
||||||
|
A \class{SMTP} instance has the following methods:
|
||||||
|
|
||||||
|
\begin{methoddesc}{set_debuglevel}{level}
|
||||||
|
Set the debug output level. A non-false value results in debug
|
||||||
|
messages for connection and for all messages sent to and received from
|
||||||
|
the server.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{connect}{\optional{host='localhost',port=0}}
|
||||||
|
Connect to a host on a given port.
|
||||||
|
|
||||||
|
If the hostname ends with a colon (`:') followed by a number,
|
||||||
|
that suffix will be stripped off and the number interpreted as
|
||||||
|
the port number to use.
|
||||||
|
|
||||||
|
Note: This method is automatically invoked by __init__,
|
||||||
|
if a host is specified during instantiation.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{docmd}{cmd, \optional{, argstring}}
|
||||||
|
Send a command to the server. The optional argument
|
||||||
|
string is simply concatenated to the command.
|
||||||
|
|
||||||
|
Get back a 2-tuple composed of a numeric response code and the actual
|
||||||
|
response line (multiline responses are joined into one long line.)
|
||||||
|
|
||||||
|
In normal operation it should not be necessary to call this method
|
||||||
|
explicitly. It is used to implement other methods and may be useful
|
||||||
|
for testing private extensions.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{helo}{\optional{hostname}}
|
||||||
|
Identify yourself to the SMTP server using HELO. The hostname
|
||||||
|
argument defaults to the FQDN of the local host.
|
||||||
|
|
||||||
|
In normal operation it should not be necessary to call this method
|
||||||
|
explicitly. It will be implicitly called by the \var{sendmail} method
|
||||||
|
when necessary.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{ehlo}{\optional{hostname}}
|
||||||
|
Identify yourself to an ESMTP server using HELO. The hostname
|
||||||
|
argument defaults to the FQDN of the local host. Examine the
|
||||||
|
response for ESMTP option and store them for use by the
|
||||||
|
\var{has_option} method.
|
||||||
|
|
||||||
|
Unless you wish to use the \var{has_option} method before sending
|
||||||
|
mail, it should not be necessary to call this method explicitly. It
|
||||||
|
will be implicitly called by the \var{sendmail} method when necessary.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{has_option}{name}
|
||||||
|
Return 1 if name is in the set of ESMTP options returned by the
|
||||||
|
server, 0 otherwise. Case is ignored.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{verify}{address}
|
||||||
|
Check the validity of an address on this server using SMTP VRFY.
|
||||||
|
Returns a tuple consisting of code 250 and a full RFC822 address
|
||||||
|
(including human name) if the user address is valid. Otherwise returns
|
||||||
|
an SMTP error code of 400 or greater and an error string.
|
||||||
|
|
||||||
|
Note: many sites disable SMTP VRFY in order to foil spammers.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{sendmail}{from_addr, to_addrs, msg\optional{, options=[]}}
|
||||||
|
Send mail. The required arguments are an RFC822 from-address string,
|
||||||
|
a list of RFC822 to-address strings, and a message string. The caller
|
||||||
|
may pass a list of ESMTP options to be used in MAIL FROM commands.
|
||||||
|
|
||||||
|
If there has been no previous EHLO or HELO command this session, this
|
||||||
|
method tries ESMTP EHLO first. If the server does ESMTP, message size
|
||||||
|
and each of the specified options will be passed to it (if the option
|
||||||
|
is in the feature set the server advertises). If EHLO fails, HELO
|
||||||
|
will be tried and ESMTP options suppressed.
|
||||||
|
|
||||||
|
This method will return normally if the mail is accepted for at least
|
||||||
|
one recipient. Otherwise it will throw an exception (either
|
||||||
|
SMTPSenderRefused, SMTPRecipientsRefused, or SMTPDataError)
|
||||||
|
That is, if this method does not throw an exception, then someone
|
||||||
|
should get your mail. If this method does not throw an exception,
|
||||||
|
it returns a dictionary, with one entry for each recipient that was
|
||||||
|
refused.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{quit}{}
|
||||||
|
Terminate the SMTP session and close the connection.
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
Low-level methods corresponding to the standard SMTP/ESMTP commands
|
||||||
|
HELP, RSET, NOOP, MAIL, RCPT, and DATA are also supported. Normally
|
||||||
|
these do not need to be called directly, so they are not documented
|
||||||
|
here. For details, consult the module code.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
import sys, rfc822
|
||||||
|
|
||||||
|
def prompt(prompt):
|
||||||
|
sys.stdout.write(prompt + ": ")
|
||||||
|
return string.strip(sys.stdin.readline())
|
||||||
|
|
||||||
|
fromaddr = prompt("From")
|
||||||
|
toaddrs = string.splitfields(prompt("To"), ',')
|
||||||
|
print "Enter message, end with ^D:"
|
||||||
|
msg = ''
|
||||||
|
while 1:
|
||||||
|
line = sys.stdin.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
msg = msg + line
|
||||||
|
print "Message length is " + `len(msg)`
|
||||||
|
|
||||||
|
server = SMTP('localhost')
|
||||||
|
server.set_debuglevel(1)
|
||||||
|
server.sendmail(fromaddr, toaddrs, msg)
|
||||||
|
server.quit()
|
||||||
|
\end{verbatim}
|
||||||
|
|
Loading…
Reference in New Issue