[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - FTPServer.py:1.1.2.10 FTPServerChannel.py:1.1.2.17 PublisherFTPServer.py:1.1.2.3

Stephan Richter srichter@cbu.edu
Tue, 9 Apr 2002 12:12:32 -0400


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

Modified Files:
      Tag: Zope3-Server-Branch
	FTPServer.py FTPServerChannel.py PublisherFTPServer.py 
Log Message:
Check in my big mess of stuff, which is working towards making FTP work 
together with the Publisher. I will keep working on startup now, so that 
we can test easier. 

This is basically a check-in, so that Shane can see what I have done last 
night. Please do not expect anything towork, since this is more than just
work in progress... it is a prototype to get FTP running via Publisher!


=== Zope3/lib/python/Zope/Server/FTP/FTPServer.py 1.1.2.9 => 1.1.2.10 ===
 """
 import asyncore
+import pwd
 from FTPServerChannel import FTPServerChannel
 from Zope.Server.ServerBase import ServerBase
 
-from Zope.Server.VFS.UnixFileSystem import UnixFileSystem
+from Zope.Server.VFS.UnixFileSystem import \
+     SchizophrenicUnixFileSystem
 from Zope.Server.Authentication.DictionaryAuthentication import \
      DictionaryAuthentication
 
 
+class FileSystemOpener:
+
+    filesystem_class = SchizophrenicUnixFileSystem
+
+    def __init__(self, root_dir):
+        self.root_dir = root_dir
+
+    def __call__(self, username):
+        persona = pwd.getpwnam(username)[2:4]
+        return self.filesystem_class(self.root_dir, persona)
+
+
 class FTPServer(ServerBase):
     """Generic FTP Server"""
 
@@ -35,28 +49,19 @@
                  task_dispatcher=None, adj=None, start=1, hit_log=None,
                  verbose=0, socket_map=None):
 
-        self.filesystem = UnixFileSystem(dir)
+        self.openFilesystem = FileSystemOpener(dir)
         self.auth_source = auth_source
 
         super(FTPServer, self).__init__(ip, port, task_dispatcher,
                                         adj, start, hit_log,
                                         verbose, socket_map)
 
-        # statistics
-##        self.total_sessions = 0
-##        self.closed_sessions = 0
-##        self.total_files_out = 0
-##        self.total_files_in = 0
-##        self.total_bytes_out = 0
-##        self.total_bytes_in = 0
-##        self.total_exceptions = 0
-
 
 if __name__ == '__main__':
     from Zope.Server.TaskThreads import ThreadedTaskDispatcher
     td = ThreadedTaskDispatcher()
     td.setThreadCount(4)
-    auth_source = DictionaryAuthentication({'foo': 'bar'})
+    auth_source = DictionaryAuthentication({'root': 'bar'})
     FTPServer('', 8021, '/', auth_source, task_dispatcher=td)
     try:
         while 1:


=== Zope3/lib/python/Zope/Server/FTP/FTPServerChannel.py 1.1.2.16 => 1.1.2.17 ===
 from Zope.Server.LineReceiver.LineServerChannel import LineServerChannel
 from FTPStatusMessages import status_msgs
+from OSEmulators import unix_longify as longify
 
 from IFTPCommandHandler import IFTPCommandHandler
 from PassiveAcceptor import PassiveAcceptor
@@ -109,7 +110,7 @@
     def cmd_cdup(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
         path = self._generatePath('../')
-        if self.server.filesystem.exists(path):
+        if self.server.openFilesystem(self.username).exists(path):
             self.cwd = path
             self.reply('SUCCESS_250', 'CDUP')
         else:
@@ -119,7 +120,7 @@
     def cmd_cwd(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
         path = self._generatePath(args)
-        if self.server.filesystem.exists(path):
+        if self.server.openFilesystem(self.username).exists(path):
             self.cwd = path
             self.reply('SUCCESS_250', 'CWD')
         else:
@@ -134,7 +135,7 @@
         path = self._generatePath(args)
 
         try:
-            self.server.filesystem.remove(path)
+            self.server.openFilesystem(self.username).remove(path)
         except OSError, err:
             self.reply('ERR_DELETE_FILE', str(err))
         else:
@@ -169,11 +170,12 @@
     def cmd_mdtm(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
         path = self._generatePath(args)
-        if not self.server.filesystem.isfile(path):
+        if not self.server.openFilesystem(self.username).isfile(path):
             self.reply('ERR_IS_NOT_FILE', path)
         else:
             mtime = time.gmtime(
-                self.server.filesystem.stat(path)[stat.ST_MTIME]
+                self.server.openFilesystem(
+                self.username).stat(path)[stat.ST_MTIME]
                 )
             self.reply('FILE_DATE', (mtime[0], mtime[1], mtime[2],
                                      mtime[3], mtime[4], mtime[5]) )
@@ -186,7 +188,7 @@
             return
         path = self._generatePath(args)
         try:
-            self.server.filesystem.mkdir(path)
+            self.server.openFilesystem(self.username).mkdir(path)
         except OSError, err:
             self.reply('ERR_CREATE_DIR', str(err))
         else:
@@ -266,7 +268,7 @@
             self.reply('CMD_UNKNOWN', 'RETR')
         path = self._generatePath(args)
 
-        if not self.server.filesystem.isfile(path):
+        if not self.server.openFilesystem(self.username).isfile(path):
             self.reply('ERR_IS_NOT_FILE', path)
             return
 
@@ -283,7 +285,7 @@
         outstream = ApplicationXmitStream(cdc)
 
         try:
-            self.server.filesystem.readfile(
+            self.server.openFilesystem(self.username).readfile(
                 path, mode, outstream, start)
             cdc.close_when_done()
         except OSError, err:
@@ -310,7 +312,7 @@
             return
         path = self._generatePath(args)
         try:
-            self.server.filesystem.rmdir(path)
+            self.server.openFilesystem(self.username).rmdir(path)
         except OSError, err:
             self.reply('ERR_DELETE_DIR', str(err))
         else:
@@ -320,7 +322,7 @@
     def cmd_rnfr(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
         path = self._generatePath(args)
-        if self.server.filesystem.exists(path):
+        if self.server.openFilesystem(self.username).exists(path):
             self._rnfr = path
             self.reply('READY_FOR_DEST')
         else:
@@ -333,7 +335,7 @@
         if self._rnfr is None:
             self.reply('ERR_RENAME')
         try:
-            self.server.filesystem.rename(self._rnfr, path)
+            self.server.openFilesystem(self.username).rename(self._rnfr, path)
         except OSError, err:
             self.reply('ERR_RENAME', (self._rnfr, rnto, str(err)))
         else:
@@ -344,11 +346,11 @@
     def cmd_size(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
         path = self._generatePath(args)
-        if not self.server.filesystem.isfile(path):
+        if not self.server.openFilesystem(self.username).isfile(path):
             self.reply('ERR_NO_FILE', path)
         else:
-            self.reply('FILE_SIZE',
-                       self.server.filesystem.stat(path)[stat.ST_SIZE])
+            self.reply('FILE_SIZE', self.server.openFilesystem(
+                self.username).stat(path)[stat.ST_SIZE])
 
 
     def cmd_stor(self, args, write_mode='w'):
@@ -368,7 +370,7 @@
             # Verify the file can be opened, but don't open it yet.
             # The actually write should be transactional without
             # holding up the application.
-            fs = self.server.filesystem
+            fs = self.server.openFilesystem(self.username)
             fs.check_writable(path, mode)
         except OSError, err:
             self.reply('ERR_OPEN_WRITE', str(err))
@@ -388,7 +390,8 @@
         try:
             infile = buffer.getfile()
             infile.seek(0)
-            self.server.filesystem.writefile(path, mode, infile, start)
+            self.server.openFilesystem(self.username).writefile(path, mode,
+                                                                infile, start)
         except OSError, err:
             self.reply('ERR_OPEN_WRITE', str(err))
         except IOError, err:
@@ -462,11 +465,12 @@
 
     def listdir (self, path, long=0):
         """returns a string"""
-        res = self.server.filesystem.listdir(path, long)
-        if hasattr(res, 'read'):
-            # Dump the stream.
-            res = res.read()
-        return res
+        path = self._generatePath(path)
+        file_list = self.server.openFilesystem(self.username).listdir(path,
+                                                                      long)
+        if long:
+            file_list = map(longify, file_list)
+        return '\r\n'.join(file_list) + '\r\n'
 
 
     def getDirectoryList(self, args, long=0):


=== Zope3/lib/python/Zope/Server/FTP/PublisherFTPServer.py 1.1.2.2 => 1.1.2.3 ===
 $Id$
 """
+import asyncore
+import pwd
+from FTPServerChannel import FTPServerChannel
+from Zope.Server.ServerBase import ServerBase
 
-from FTPServer import FTPServer
+from Zope.StartUp.RequestFactory import RequestFactory
 from Zope.Server.VFS.PublisherFileSystem import PublisherFileSystem
+from Zope.Server.Authentication.DictionaryAuthentication import \
+     DictionaryAuthentication
 
+from ZODB import DB
+from ZODB.FileStorage import FileStorage
+from Zope.Publisher.VFS.VFSRequest import VFSRequest
+from Zope.App.ZopePublication.VFS.Publication import VFSPublication
 
-class PublisherFTPServer(FTPServer):
-    """Zope Publisher-specific HTTP Server"""
+class FileSystemOpener:
 
-    __implements__ = FTPServer.__implements__
 
-    filesystem = PublisherFileSystem('/')
+    def __init__(self, root_dir, request_factory):
+        self.root_dir = root_dir
+        self.filesystem_class = PublisherFileSystem
+        self.filesystem_class.request_factory = request_factory
 
+    def __call__(self, username):
+        persona = pwd.getpwnam(username)[2:4]
+        return self.filesystem_class(self.root_dir, persona)
 
-    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
+class PublisherFTPServer(ServerBase):
+    """Generic FTP Server"""
+
+    channel_class = FTPServerChannel
+    SERVER_IDENT = 'Zope.Server.FTPServer'
+
+
+    def __init__(self, request_factory, ip, port, task_dispatcher=None,
+                 adj=None, start=1, hit_log=None, verbose=0, socket_map=None,
+                 fs_opener=None, auth_source=None):
+
+        self.request_factory = request_factory
+        self.openFilesystem = fs_opener
+        self.auth_source = auth_source
 
-        FTPServer.__init__(self, *args, **kw)
+        super(PublisherFTPServer, self).__init__(ip, port, task_dispatcher,
+                                                 adj, start, hit_log,
+                                                 verbose, socket_map)
+
+
+if __name__ == '__main__':
+    from Zope.Server.TaskThreads import ThreadedTaskDispatcher
+    td = ThreadedTaskDispatcher()
+    td.setThreadCount(4)
+
+    auth_source = DictionaryAuthentication({'root': 'bar'})
+    req = RequestFactory(VFSPublication, VFSRequest)
+    db = DB(FileStorage('/opt/Zope3-Branches/Zope-3x-Server/Data.fs'))
+    req = req.realize(db)
+    fs_opener = FileSystemOpener(dir, req)
+
+
+    from Zope.App.OFS.Container.Views.VFS.VFSContainerView import \
+         VFSContainerView
+    from Zope.App.OFS.Container.ContainerTraverser import ContainerTraverser
+    from Zope.Publisher.VFS.IVFSPublisher import IVFSPublisher
+    from Zope.App.OFS.Container.IContainer import IContainer
+    from Zope.App.OFS.Folder.RootFolder import IRootFolder
+    from Zope.ComponentArchitecture import provideView, setDefaultViewName
+    setDefaultViewName(IContainer, IVFSPublisher, 'vfs')
+    provideView(IContainer, 'vfs', IVFSPublisher, VFSContainerView, '')
+    provideView(IContainer, '_traverse', IVFSPublisher, ContainerTraverser, '')
+
+    from Zope.App.Security.PrincipalRoleManager import \
+         principalRoleManager as principal_role_mgr
+    from Zope.App.Security.PrincipalRegistry import principalRegistry
+
+    principalRegistry.defineDefaultPrincipal('anybody', 'anybody', 'All') 
+    principal_role_mgr.assignRoleToPrincipal('Manager', 'anybody')
+
+    PublisherFTPServer(req, '', 8021, task_dispatcher=td, fs_opener=fs_opener,
+              auth_source=auth_source)
+    try:
+        while 1:
+            asyncore.poll(5)
+            print 'active channels:', FTPServerChannel.active_channels
+    except KeyboardInterrupt:
+        print 'shutting down...'
+        td.shutdown()