From 8668e8e49cff1164de373dbcfb52f53a0f7eda89 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 28 Jun 1998 17:55:53 +0000 Subject: [PATCH] Contributions by Eric Raymond: documentation for modules cmd, multifile and smtplib. --- Doc/lib/lib.tex | 3 + Doc/lib/libcmd.tex | 134 +++++++++++++++++++++++++++++++++++ Doc/lib/libmultifile.tex | 147 +++++++++++++++++++++++++++++++++++++++ Doc/lib/libsmtplib.tex | 144 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 428 insertions(+) create mode 100644 Doc/lib/libcmd.tex create mode 100644 Doc/lib/libmultifile.tex create mode 100644 Doc/lib/libsmtplib.tex diff --git a/Doc/lib/lib.tex b/Doc/lib/lib.tex index 4f46bf7f7bb..7c749034e0a 100644 --- a/Doc/lib/lib.tex +++ b/Doc/lib/lib.tex @@ -109,6 +109,7 @@ add new extensions to Python and how to embed it in other applications. \input{libarray} \input{libfileinput} \input{libcalendar} +\input{libcmd} \input{liballos} % Generic Operating System Services \input{libos} @@ -161,6 +162,7 @@ add new extensions to Python and how to embed it in other applications. \input{libpoplib} \input{libimaplib} \input{libnntplib} +\input{libsmtplib} \input{liburlparse} \input{libsgmllib} \input{libhtmllib} @@ -168,6 +170,7 @@ add new extensions to Python and how to embed it in other applications. \input{libformatter} \input{librfc822} \input{libmimetools} +\input{libmultifile} \input{libbinhex} \input{libuu} \input{libbinascii} diff --git a/Doc/lib/libcmd.tex b/Doc/lib/libcmd.tex new file mode 100644 index 00000000000..7c4dd4a3dc6 --- /dev/null +++ b/Doc/lib/libcmd.tex @@ -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} + + diff --git a/Doc/lib/libmultifile.tex b/Doc/lib/libmultifile.tex new file mode 100644 index 00000000000..0741aa1304f --- /dev/null +++ b/Doc/lib/libmultifile.tex @@ -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} diff --git a/Doc/lib/libsmtplib.tex b/Doc/lib/libsmtplib.tex new file mode 100644 index 00000000000..90bbc1e198a --- /dev/null +++ b/Doc/lib/libsmtplib.tex @@ -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} +