Changeset 451:1bac6c89ddf7


Ignore:
Timestamp:
Feb 3, 2006, 12:55:57 AM (15 years ago)
Author:
Stefan Schwarzer <sschwarzer@…>
Branch:
default
Convert:
svn:778c30c8-61e0-0310-89d4-fe2f97a467b2/trunk@468
Message:
FTPHost.set_directory_format: Renamed parameter `server_platform`
to `directory_format` because some servers can use different formats
and so the format and the server platform aren't equivalent.

Implemented - experimental! - autodetection of FTP server directory
format.
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • _test_real_ftp.py

    r439 r451  
    4242import ftputil
    4343from ftputil import ftp_error
    44 
     44from ftputil import ftp_stat
    4545
    4646# difference between local times of server and client; if 0.0, server
     
    182182        host.rmdir(dir_name)
    183183
     184    def test_autodetect_directory_format(self):
     185        host = self.host
     186        host.auto_set_directory_format()
     187        self.failUnless(isinstance(host._stat, ftp_stat._UnixStat))
     188
    184189    def make_local_file(self):
    185190        fobj = file("_localfile_", "wb")
  • ftp_error.py

    r396 r451  
    1 # Copyright (C) 2003-2004, Stefan Schwarzer <sschwarzer@sschwarzer.net>
     1# Copyright (C) 2003-2006, Stefan Schwarzer <sschwarzer@sschwarzer.net>
    22# All rights reserved.
    33#
     
    3434"""
    3535
    36 # $Id: ftp_error.py,v 1.4 2004/07/09 21:48:34 schwa Exp $
     36# $Id$
    3737
    3838import ftplib
     
    5757class RootDirError(InternalError): pass
    5858class InaccessibleLoginDirError(InternalError): pass
     59class FormatDetectionError(InternalError): pass
    5960
    6061class TimeShiftError(FTPError): pass
  • ftp_stat.py

    r447 r451  
    1 # Copyright (C) 2002-2004, Stefan Schwarzer
     1# Copyright (C) 2002-2006, Stefan Schwarzer
    22# All rights reserved.
    33#
     
    376376
    377377
     378_stat_classes = {
     379  "unix": _UnixStat,
     380  "ms"  : _MSStat,
     381  }
     382
     383
    378384# Unix format
    379385# total 14
  • ftputil.py

    r448 r451  
    187187        return False
    188188
    189     def set_directory_format(self, server_platform):
     189    def auto_set_directory_format(self):
     190        """
     191        Try to find out the directory format used by the FTP server
     192        automatically.
     193
     194        This is _not_ the default applied by ftputil because the
     195        method requires write access to the current directory which
     196        can't be taken for granted.
     197
     198        If the auto-detection fails for any reason, a
     199        `FormatDetectionError` is raised. The error conditions include
     200        the impossibility to find an appropriate parser for the
     201        directory format but in fact there are many possible reasons,
     202        e. g. no write access to the current directory. If such an
     203        exception occurs, the stat functionality of the `FTPHost`
     204        instance won't work but other functionality might.
     205        """
     206        helper_file_name = "_ftputil_format_"
     207        # open a dummy file for writing in the current directory
     208        #  on the FTP host, then close it
     209        try:
     210            file_ = self.file(helper_file_name, 'w')
     211            file_.close()
     212        except ftp_error.FTPIOError:
     213            # couldn't write the file; since errors should never pass
     214            #  silently, raise an exception; using `getcwd` here should
     215            #  be safe because it doesn't need `stat` itself
     216            raise ftp_error.FormatDetectionError(
     217                  "couldn't detect directory format using directory '%s'" %
     218                  self.getcwd())
     219        # try to parse the directory with the available parsers until
     220        #  one works
     221        try:
     222            for format in ftp_stat._stat_classes.keys():
     223                self.set_directory_format(format)
     224                try:
     225                    stat_result = self.stat(helper_file_name)
     226                except FTPOSError:
     227                    # parser doen't work; try the next
     228                    continue
     229                else:
     230                    if (stat_result._st_name, stat_result.st_size)  == \
     231                       (helper_file_name, 0):
     232                        break
     233            else:
     234                raise ftp_error.FormatDetectionError(
     235                      "no usable directory parser found")
     236        finally:
     237            # remove the helper file
     238            try:
     239                self.unlink(helper_file_name)
     240            except ftp_error.FTPOSError:
     241                raise ftp_error.FormatDetectionError(
     242                      "couldn't remove helper file")
     243
     244    def set_directory_format(self, directory_format):
    190245        """
    191246        Tell this `FTPHost` object the directory format of the remote
     
    194249        work as it should.
    195250
    196         `server_platform` is one of the following strings:
     251        `directory_format` is one of the following strings:
    197252
    198253        "unix": Use this if the directory listing from the server
     
    211266        is raised.
    212267        """
    213         parsers = {"unix"   : ftp_stat._UnixStat,
    214                    "ms"     : ftp_stat._MSStat}
    215         if parsers.has_key(server_platform):
    216             self._stat = parsers[server_platform](self)
     268        try:
     269            stat_class = ftp_stat._stat_classes[directory_format]
     270        except KeyError:
     271            raise ValueError("invalid directory format '%s'" % directory_format)
    217272        else:
    218             raise ValueError("invalid server platform '%s'" % server_platform)
     273            self._stat = stat_class(self)
    219274
    220275    #
Note: See TracChangeset for help on using the changeset viewer.