[Zope3-checkins] CVS: Zope3/src/zope/server/interfaces - __init__.py:1.2 ftp.py:1.2 logger.py:1.2 vfs.py:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:15:57 -0500
Update of /cvs-repository/Zope3/src/zope/server/interfaces
In directory cvs.zope.org:/tmp/cvs-serv20790/src/zope/server/interfaces
Added Files:
__init__.py ftp.py logger.py vfs.py
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/server/interfaces/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:56 2002
+++ Zope3/src/zope/server/interfaces/__init__.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,364 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Server interfaces.
+
+$Id$
+"""
+
+from zope.interface import Interface
+from zope.interface import Attribute
+
+
+class ISocket(Interface):
+ """Represents a socket.
+
+ Note: Most of this documentation is taken from the Python Library
+ Reference.
+ """
+
+ def listen(num):
+ """Listen for connections made to the socket. The backlog argument
+ specifies the maximum number of queued connections and should
+ be at least 1; the maximum value is system-dependent (usually
+ 5).
+ """
+
+ def bind(addr):
+ """Bind the socket to address. The socket must not already be bound.
+ """
+
+ def connect(address):
+ """Connect to a remote socket at address.
+ """
+
+ def accept():
+ """Accept a connection. The socket must be bound to an address and
+ listening for connections. The return value is a pair (conn,
+ address) where conn is a new socket object usable to send and
+ receive data on the connection, and address is the address
+ bound to the socket on the other end of the connection.
+ """
+
+ def recv(buffer_size):
+ """Receive data from the socket. The return value is a string
+ representing the data received. The maximum amount of data
+ to be received at once is specified by bufsize. See the
+ Unix manual page recv(2) for the meaning of the optional
+ argument flags; it defaults to zero.
+ """
+
+ def send(data):
+ """Send data to the socket. The socket must be connected to a
+ remote socket. The optional flags argument has the same
+ meaning as for recv() above. Returns the number of bytes
+ sent. Applications are responsible for checking that all
+ data has been sent; if only some of the data was
+ transmitted, the application needs to attempt delivery of
+ the remaining data.
+ """
+
+ def close():
+ """Close the socket. All future operations on the socket
+ object will fail. The remote end will receive no more data
+ (after queued data is flushed). Sockets are automatically
+ closed when they are garbage-collected.
+ """
+
+
+class ITaskDispatcher(Interface):
+ """An object that accepts tasks and dispatches them to threads.
+ """
+
+ def setThreadCount(count):
+ """Sets the number of handler threads.
+ """
+
+ def addTask(task):
+ """Receives a task and dispatches it to a thread.
+
+ Note that, depending on load, a task may have to wait a
+ while for its turn.
+ """
+
+ def shutdown(cancel_pending=1, timeout=5):
+ """Shuts down all handler threads and may cancel pending tasks.
+ """
+
+ def getPendingTasksEstimate():
+ """Returns an estimate of the number of tasks waiting to be serviced.
+
+ This method may be useful for monitoring purposes. If the
+ number of pending tasks is continually climbing, your server
+ is becoming overloaded and the operator should be notified.
+ """
+
+
+class ITask(Interface):
+ """
+ The interface expected of an object placed in the queue of
+ a ThreadedTaskDispatcher. Provides facilities for executing
+ or canceling the task.
+ """
+
+ def service():
+ """
+ Services the task. Either service() or cancel() is called
+ for every task queued.
+ """
+
+ def cancel():
+ """
+ Called instead of service() during shutdown or if an
+ exception occurs that prevents the task from being
+ serviced. Must return quickly and should not throw exceptions.
+ """
+
+ def defer():
+ """
+ Called just before the task is queued to be executed in
+ a different thread.
+ """
+
+
+class IRequestFactory:
+
+ def __call__(input_stream, output_steam, environment):
+ """Create a request object *with* a publication
+
+ Factories that support multiple request/response/publication
+ types may look at the environment (headers) or the stream to
+ determine which request/response/publication to create.
+ """
+
+
+class IHeaderOutput(Interface):
+ """Interface for setting HTTP response headers.
+
+ This allows the HTTP server and the application to both set response
+ headers.
+
+ zope.publisher.http.HTTPResponse is optionally passed an
+ object which implements this interface in order to intermingle
+ its headers with the HTTP server's response headers,
+ and for the purpose of better logging.
+ """
+
+ def setResponseStatus(status, reason):
+ """Sets the status code and the accompanying message.
+ """
+
+ def setResponseHeaders(mapping):
+ """Sets headers. The headers must be Correctly-Cased.
+ """
+
+ def appendResponseHeaders(lst):
+ """Sets headers that can potentially repeat.
+
+ Takes a list of strings.
+ """
+
+ def wroteResponseHeader():
+ """Returns a flag indicating whether the response
+
+ header has already been sent.
+ """
+
+ def setAuthUserName(name):
+ """Sets the name of the authenticated user so the name can be logged.
+ """
+
+
+class IDispatcherEventHandler(Interface):
+ """The Dispatcher can receive several different types of events. This
+ interface describes the necessary methods that handle these common
+ event types.
+ """
+
+ def handle_read_event():
+ """Given a read event, a server has to handle the event and
+ read the input from the client.
+ """
+
+ def handle_write_event():
+ """Given a write event, a server has to handle the event and
+ write the output to the client.
+ """
+
+ def handle_expt_event():
+ """An exception event was handed to the server.
+ """
+
+ def handle_error():
+ """An error occured, but we are still trying to fix it.
+ """
+
+ def handle_expt():
+ """Handle unhandled exceptions. This is usually a time to log.
+ """
+
+ def handle_read():
+ """Read output from client.
+ """
+
+ def handle_write():
+ """Write output via the socket to the client.
+ """
+
+ def handle_connect():
+ """A client requests a connection, now we need to do soemthing.
+ """
+
+ def handle_accept():
+ """A connection is accepted.
+ """
+
+ def handle_close():
+ """A connection is being closed.
+ """
+
+
+class IStreamConsumer(Interface):
+ """Consumes a data stream until reaching a completion point.
+
+ The actual amount to be consumed might not be known ahead of time.
+ """
+
+ def received(data):
+ """Accepts data, returning the number of bytes consumed."""
+
+ completed = Attribute(
+ 'completed', 'Set to a true value when finished consuming data.')
+
+
+class IServer(Interface):
+ """This interface describes the basic base server.
+
+ The most unusual part about the Zope servers (since they all
+ implement this interface or inherit its base class) is that it
+ uses a mix of asynchronous and thread-based mechanism to
+ serve. While the low-level socket listener uses async, the
+ actual request is executed in a thread. This has the huge
+ advantage that if a request takes really long to process, the
+ server does not hang at that point to wait for the request to
+ finish.
+ """
+
+ channel_class = Attribute("""
+ The channel class defines the type of channel
+ to be used by the server. See IServerChannel
+ for more information.
+ """)
+
+ SERVER_IDENT = Attribute("""
+ This string identifies the server. By default
+ this is 'zope.server.' and should be
+ overridden.
+ """)
+
+
+class IDispatcherLogging(Interface):
+ """This interface provides methods through which the Dispatcher will
+ write its logs. A distinction is made between hit and message logging,
+ since they often go to different output types and can have very
+ different structure.
+ """
+
+ def log (message):
+ """Logs general requests made to the server.
+ """
+
+ def log_info(message, type='info'):
+ """Logs informational messages, warnings and errors.
+ """
+
+
+class IServerChannel(Interface):
+
+ parser_class = Attribute("Subclasses must provide a parser class")
+ task_class = Attribute("Subclasses must provide a task class.")
+
+ active_channels = Attribute("Class-specific channel tracker")
+ next_channel_cleanup = Attribute("Class-specific cleanup time")
+
+ proto_request = Attribute("A request parser instance")
+ ready_requests = Attribute("A list of requests to be processed.")
+ last_activity = Attribute("Time of last activity")
+ running_tasks = Attribute("boolean")
+
+
+ def queue_request(self, req):
+ """Queues a request to be processed in sequence by a task.
+ """
+
+ def end_task(self, close):
+ """Called at the end of a task, may launch another task.
+ """
+
+ def create_task(self, req):
+ """Creates a new task and queues it for execution.
+
+ The task may get executed in another thread.
+ """
+
+
+class IDispatcher(ISocket, IDispatcherEventHandler, IDispatcherLogging):
+ """The dispatcher is the most low-level component of a server.
+
+ 1. It manages the socket connections and distributes the
+ request to the appropriate channel.
+
+ 2. It handles the events passed to it, such as reading input,
+ writing output and handling errors. More about this
+ functionality can be found in IDispatcherEventHandler.
+
+ 3. It handles logging of the requests passed to the server as
+ well as other informational messages and erros. Please see
+ IDispatcherLogging for more details.
+
+ Note: Most of this documentation is taken from the Python
+ Library Reference.
+ """
+
+ def add_channel(map=None):
+ """After the low-level socket connection negotiation is
+ completed, a channel is created that handles all requests
+ and responses until the end of the connection.
+ """
+
+ def del_channel(map=None):
+ """Delete a channel. This should include also closing the
+ socket to the client.
+ """
+
+ def create_socket(family, type):
+ """This is identical to the creation of a normal socket, and
+ will use the same options for creation. Refer to the socket
+ documentation for information on creating sockets.
+ """
+
+ def readable():
+ """Each time through the select() loop, the set of sockets is
+ scanned, and this method is called to see if there is any
+ interest in reading. The default method simply returns 1,
+ indicating that by default, all channels will be
+ interested.
+ """
+
+ def writable():
+ """Each time through the select() loop, the set of sockets is
+ scanned, and this method is called to see if there is any
+ interest in writing. The default method simply returns 1,
+ indicating that by default, all channels will be
+ interested.
+ """
=== Zope3/src/zope/server/interfaces/ftp.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:56 2002
+++ Zope3/src/zope/server/interfaces/ftp.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,174 @@
+
+
+from zope.interface import Interface
+
+class IFTPCommandHandler(Interface):
+ """This interface defines all the FTP commands that are supported by the
+ server.
+
+ Every command takes the command line as first arguments, since it is
+ responsible
+ """
+
+ def cmd_abor(args):
+ """Abort operation. No read access required.
+ """
+
+ def cmd_appe(args):
+ """Append to a file. Write access required.
+ """
+
+ def cmd_cdup(args):
+ """Change to parent of current working directory.
+ """
+
+ def cmd_cwd(args):
+ """Change working directory.
+ """
+
+ def cmd_dele(args):
+ """Delete a file. Write access required.
+ """
+
+ def cmd_help(args):
+ """Give help information. No read access required.
+ """
+
+ def cmd_list(args):
+ """Give list files in a directory or displays the info of one file.
+ """
+
+ def cmd_mdtm(args):
+ """Show last modification time of file.
+
+ Example output: 213 19960301204320
+
+ Geez, there seems to be a second syntax for this fiel, where one
+ can also set the modification time using:
+ MDTM datestring pathname
+
+ """
+
+ def cmd_mkd(args):
+ """Make a directory. Write access required.
+ """
+
+ def cmd_mode(args):
+ """Set file transfer mode. No read access required. Obselete.
+ """
+
+ def cmd_nlst(args):
+ """Give name list of files in directory.
+ """
+
+ def cmd_noop(args):
+ """Do nothing. No read access required.
+ """
+
+ def cmd_pass(args):
+ """Specify password.
+ """
+
+ def cmd_pasv(args):
+ """Prepare for server-to-server transfer. No read access required.
+ """
+
+ def cmd_port(args):
+ """Specify data connection port. No read access required.
+ """
+
+ def cmd_pwd(args):
+ """Print the current working directory.
+ """
+
+ def cmd_quit(args):
+ """Terminate session. No read access required.
+ """
+
+ def cmd_rest(args):
+ """Restart incomplete transfer.
+ """
+
+ def cmd_retr(args):
+ """Retrieve a file.
+ """
+
+ def cmd_rmd(args):
+ """Remove a directory. Write access required.
+ """
+
+ def cmd_rnfr(args):
+ """Specify rename-from file name. Write access required.
+ """
+
+ def cmd_rnto(args):
+ """Specify rename-to file name. Write access required.
+ """
+
+ def cmd_size(args):
+ """Return size of file.
+ """
+
+ def cmd_stat(args):
+ """Return status of server. No read access required.
+ """
+
+ def cmd_stor(args):
+ """Store a file. Write access required.
+ """
+
+ def cmd_stru(args):
+ """Set file transfer structure. Obselete."""
+
+ def cmd_syst(args):
+ """Show operating system type of server system.
+
+ No read access required.
+
+ Replying to this command is of questionable utility,
+ because this server does not behave in a predictable way
+ w.r.t. the output of the LIST command. We emulate Unix ls
+ output, but on win32 the pathname can contain drive
+ information at the front Currently, the combination of
+ ensuring that os.sep == '/' and removing the leading slash
+ when necessary seems to work. [cd'ing to another drive
+ also works]
+
+ This is how wuftpd responds, and is probably the most
+ expected. The main purpose of this reply is so that the
+ client knows to expect Unix ls-style LIST output.
+
+ one disadvantage to this is that some client programs
+ assume they can pass args to /bin/ls. a few typical
+ responses:
+
+ 215 UNIX Type: L8 (wuftpd)
+ 215 Windows_NT version 3.51
+ 215 VMS MultiNet V3.3
+ 500 'SYST': command not understood. (SVR4)
+ """
+
+ def cmd_type(args):
+ """Specify data transfer type. No read access required.
+ """
+
+ def cmd_user(args):
+ """Specify user name. No read access required.
+ """
+
+
+
+# this is the command list from the wuftpd man page
+# '!' requires write access
+#
+not_implemented_commands = {
+ 'acct': 'specify account (ignored)',
+ 'allo': 'allocate storage (vacuously)',
+ 'site': 'non-standard commands (see next section)',
+ 'stou': 'store a file with a unique name', #!
+ 'xcup': 'change to parent of current working directory (deprecated)',
+ 'xcwd': 'change working directory (deprecated)',
+ 'xmkd': 'make a directory (deprecated)', #!
+ 'xpwd': 'print the current working directory (deprecated)',
+ 'xrmd': 'remove a directory (deprecated)', #!
+}
=== Zope3/src/zope/server/interfaces/logger.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:56 2002
+++ Zope3/src/zope/server/interfaces/logger.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+
+from zope.interface import Interface
+
+
+class IRequestLogger(Interface):
+ """This interface describes a requets logger, which logs
+ ip addresses and messages.
+ """
+
+ def logRequest(ip, message):
+ """Logs the ip address and message at the appropriate place."""
+
+
+"""
+
+$Id$
+"""
+
+from zope.interface import Interface
+
+
+class IMessageLogger(Interface):
+ """This interface describes a message logger, which logs
+ with the resolution of one message.
+ """
+
+ def logMessage(message):
+ """Logs the message at the appropriate place."""
=== Zope3/src/zope/server/interfaces/vfs.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:15:56 2002
+++ Zope3/src/zope/server/interfaces/vfs.py Wed Dec 25 09:15:26 2002
@@ -0,0 +1,170 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+
+from zope.interface import Interface
+
+
+# XXX These interfaces should be located in a more central location.
+# (so I don't mind putting them together in one module for now ;-) )
+
+class ICredentials(Interface):
+ """Base interface for presentation of authentication credentials.
+
+ Different kinds of credentials include username/password, client
+ certificate, IP address and port, etc., including combinations.
+ """
+
+
+class IUsernamePassword(ICredentials):
+ """A type of authentication credentials consisting of user name and
+ password. The most recognized form of credentials.
+ """
+
+ def getUserName():
+ """Returns the user name presented for authentication.
+ """
+
+ def getPassword():
+ """Returns the password presented for authentication.
+ """
+
+
+# XXX This interface should be in a more central location.
+
+class IFilesystemAccess(Interface):
+ """Provides authenticated access to a filesystem.
+ """
+
+ def authenticate(credentials):
+ """Verifies filesystem access based on the presented credentials.
+
+ Should raise Unauthorized if the user can not be authenticated.
+
+ This method only checks general access and is not used for each
+ call to open(). Rather, open() should do its own verification.
+ """
+
+ def open(credentials):
+ """Returns an IReadFilesystem or IWriteFilesystem.
+
+ Should raise Unauthorized if the user can not be authenticated.
+ """
+
+
+class IReadFileSystem(Interface):
+ """We want to provide a complete wrapper around any and all read
+ filesystem operations.
+
+ Opening files for reading, and listing directories, should
+ return a producer.
+
+ All paths are POSIX paths, even when run on Windows,
+ which mainly means that FS implementations always expect forward
+ slashes, and filenames are case-sensitive.
+
+ Note: A file system should *not* store any state!
+ """
+
+ def exists(path):
+ """Test whether a path exists.
+ """
+
+ def isdir(path):
+ """Test whether a path is a directory.
+ """
+
+ def isfile(path):
+ """Test whether a path is a file.
+ """
+
+ def listdir(path, with_stats=0, pattern='*'):
+ """Return a listing of the directory at 'path' The empty
+ string indicates the current directory. If 'with_stats' is set,
+ instead return a list of (name, stat_info) tuples. All file
+ names are filtered by the globbing pattern. (See the 'glob'
+ module in the Python standard library.)
+ """
+ return list(tuple(str, str))
+
+ def readfile(path, mode, outstream, start=0, end=-1):
+ """Outputs the file at path to a stream.
+ """
+
+ def stat(path):
+ """Return the equivalent of os.stat() on the given path:
+
+ (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)
+ """
+
+
+class IWriteFileSystem(Interface):
+ """We want to provide a complete wrapper around any and all write
+ filesystem operations.
+
+ Notes:
+ - A file system should *not* store any state!
+ - Most of the commands copy the functionality given in os.
+ """
+
+ def mkdir(path, mode=777):
+ """Create a directory.
+ """
+
+ def remove(path):
+ """Remove a file. Same as unlink.
+ """
+
+ def rmdir(path):
+ """Remove a directory.
+ """
+
+ def rename(old, new):
+ """Rename a file or directory.
+ """
+
+ def writefile(path, mode, instream, start=0):
+ """Write data to a file.
+ """
+
+ def check_writable(path):
+ """Ensures a path is writable. Throws an IOError if not."""
+
+
+class IPosixFileSystem(IWriteFileSystem, IReadFileSystem):
+ """
+ """
+
+ def chmod(path, mode):
+ """Change the access permissions of a file.
+ """
+
+ def chown(path, uid, gid):
+ """Change the owner and group id of path to numeric uid and gid.
+ """
+
+ def link(src, dst):
+ """Create a heard link to a file.
+ """
+
+ def mkfifo(path, mode=777):
+ """Create a FIFO (a POSIX named pipe).
+ """
+
+ def symlink(src, dst):
+ """Create a symbolic link at dst pointing to src.
+ """