[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.
+        """