[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - PublisherFTPServer.py:1.1.2.1 CommonFTPActivityLogger.py:1.1.2.2 FTPServer.py:1.1.2.4 FTPServerChannel.py:1.1.2.8 FTPTask.py:1.1.2.2

Stephan Richter srichter@cbu.edu
Thu, 4 Apr 2002 06:45:24 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/Server/FTP
In directory cvs.zope.org:/tmp/cvs-serv21650/lib/python/Zope/Server/FTP

Modified Files:
      Tag: Zope3-Server-Branch
	CommonFTPActivityLogger.py FTPServer.py FTPServerChannel.py 
	FTPTask.py 
Added Files:
      Tag: Zope3-Server-Branch
	PublisherFTPServer.py 
Log Message:
Worked some more on FTP, especially in regards with the Publisher.

- Finally we can get rid of the medusa base. I think I have extracted all
  of the interesting code.

- Started on a PublisherFileSystem. A few methods might work, but most of 
  the FS methods are not hooked up yet.

- Started writing VFS Publisher hooks.

- Added the FTPServer to the startup registry. It comes up, but do not 
  expect it to work, since no views have been written for VFS yet.


=== Added File Zope3/lib/python/Zope/Server/FTP/PublisherFTPServer.py ===
##############################################################################
#
# 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: PublisherFTPServer.py,v 1.1.2.1 2002/04/04 11:44:52 srichter Exp $
"""

from FTPServer import FTPServer
from Zope.Server.VFS.PublisherFileSystem import PublisherFileSystem


class PublisherFTPServer(FTPServer):
    """Zope Publisher-specific HTTP Server"""

    __implements__ = FTPServer.__implements__

    filesystem = PublisherFileSystem('/')


    def __init__(self, request_factory, sub_protocol=None, *args, **kw):
        self.request_factory = request_factory
        self.filesystem.request_factory = self.request_factory

        if sub_protocol:
            self.SERVER_IDENT += ' (%s)' %sub_protocol

        FTPServer.__init__(self, *args, **kw)


=== Zope3/lib/python/Zope/Server/FTP/CommonFTPActivityLogger.py 1.1.2.1 => 1.1.2.2 ===
 """
 
-class CommonActivityLogger:
-    """This logger's output is 
 
+import time
+import sys
+
+from Zope.Server.Logger.FileLogger import FileLogger
+from Zope.Server.Logger.ResolvingLogger import ResolvingLogger
+from Zope.Server.Logger.UnresolvingLogger import UnresolvingLogger
+
+
+class CommonFTPActivityLogger:
+    """Outputs hits in common HTTP log format.
     """
-    pass
+
+    def __init__(self, logger_object=None, resolver=None):
+        if logger_object is None:
+            logger_object = FileLogger(sys.stdout)
+
+        if resolver is not None:
+            self.output = ResolvingLogger(resolver, logger_object)
+        else:
+            self.output = UnresolvingLogger(logger_object)
+            
+
+    def log(self, task):
+        """
+        Receives a completed task and logs it in the
+        common log format.
+        """
+
+        now = time.localtime(time.time())
+
+        print now
+        self.output.log('127.0.0.1', time.strftime('%Y/%m/%d %H:%M', now))


=== Zope3/lib/python/Zope/Server/FTP/FTPServer.py 1.1.2.3 => 1.1.2.4 ===
     def __init__(self, ip, port, task_dispatcher=None, adj=None, start=1,
                  hit_log=None, verbose=0, socket_map=None):
-        super(FTPServer, self).__init__(ip, port, task_dispatcher=None,
-                                        adj=None, start=1, hit_log=None,
-                                        verbose=0, socket_map=None)
+        super(FTPServer, self).__init__(ip, port, task_dispatcher,
+                                        adj, start, hit_log,
+                                        verbose, socket_map)
 
         # statistics
         self.total_sessions = Counter()


=== Zope3/lib/python/Zope/Server/FTP/FTPServerChannel.py 1.1.2.7 => 1.1.2.8 ===
 
 
+# These are the commands that are accessing the filesystem.
+# Since this could be also potentially a longer process, these commands
+# are slao the ones that are executed in a different thread.
+fs_access_cmds = ('cmd_appe', 'cmd_cdup', 'cmd_cwd', 'cmd_dele', 'cmd_list',
+                  'cmd_nlst', 'cmd_mdtm', 'cmd_mkd', 'cmd_pass', 'cmd_retr',
+                  'cmd_rmd', 'cmd_rnfr', 'cmd_rnto', 'cmd_size', 'cmd_stor',
+                  'cmd_stru')
+
+
 class FTPServerChannel(ServerChannelBase):
     """The FTP Server Channel represents a connection to a particular
        client. We can therefore store information here."""
@@ -97,33 +106,26 @@
 
         Some commands use an alternate thread.
         """
-        
         assert isinstance(command, FTPCommandParser)
         cmd = command.cmd
-        m = 'cmd_' + cmd.lower()
+        method = 'cmd_' + cmd.lower()
         if ( not self.authenticated and
-             m not in ('cmd_user', 'cmd_pass', 'cmd_quit')):
+             method not in ('cmd_user', 'cmd_pass', 'cmd_quit')):
             # The user is not logged in, therefore don't allow anything 
             self.reply(530, 1)
 
-        elif m == 'cmd_':            
-            # The empty case is very important, since the server crashes
-            # otherwise
-            self.reply(500, 0, (''))            
-
-        elif hasattr(self, m):
-            # Quick processing
-            getattr(self, m)(command.args)
+        elif method in fs_access_cmds:
+            # Process in another thread.
+            task = self.task_class(self, command, method)
+            self.set_sync()
+            self.server.addTask(task)
+            return
+
+        elif hasattr(self, method):
+            getattr(self, method)(command.args)
 
         else:
-            # Process in another thread.
-            task = self.task_class(self, command, m)
-            if hasattr(task, m):
-                self.set_sync()
-                self.server.addTask(task)
-                return
-            else:
-                self.reply(500, 0, (cmd.upper()))
+            self.reply(500, 0, (cmd.upper()))
 
         self.end_task(0)
 


=== Zope3/lib/python/Zope/Server/FTP/FTPTask.py 1.1.2.1 => 1.1.2.2 ===
 
 import socket
+import time
 from Zope.Server.ITask import ITask
 
 
@@ -32,6 +33,8 @@
         self.m_name = m_name
         self.args = command.args
 
+        self.close_on_finish = 0
+
 
     ############################################################
     # Implementation methods for interface
@@ -43,7 +46,7 @@
         try:
             try:
                 self.start()
-                getattr(self, self.m_name)(self.args)
+                getattr(self.channel, self.m_name)(self.args)
                 self.finish()
             except socket.error:
                 self.close_on_finish = 1