Ignore:
Timestamp:
Feb 12, 2010, 9:13:33 AM (11 years ago)
Author:
Stefan Schwarzer <sschwarzer@…>
Branch:
default
Message:
Split `_TransferredFile` into two classes (local and remote).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • ftputil.py

    r854 r855  
    9393
    9494
    95 #TODO turn into three classes (one base class and two derived classes)
    96 class _TransferredFile(object):
     95class _LocalFile(object):
    9796    """
    98     Represent a file on the local or remote side which is to
    99     be transferred or is already transferred.
     97    Represent a file on the local side which is to be transferred or
     98    is already transferred.
    10099    """
    101100
    102     def __init__(self, host, name, mode):
    103         self._host = host
    104         self._is_local = (host is None)
    105         if self._is_local:
    106             self._path = os.path
    107         else:
    108             self._path = host.path
     101    def __init__(self, name, mode):
     102        self.name = os.path.abspath(name)
     103        self.mode = mode
     104
     105    def exists(self):
     106        """
     107        Return `True` if the path representing this file exists.
     108        Otherwise return `False`.
     109        """
     110        return os.path.exists(self.name)
     111
     112    def mtime(self):
     113        """Return the timestamp for the last modification in seconds."""
     114        return os.path.getmtime(self.name)
     115
     116    def mtime_precision(self):
     117        """Return the precision of the last modification time in seconds."""
     118        # assume modification timestamps for local filesystems are
     119        #  at least precise up to a second
     120        return 1.0
     121
     122    def fobj(self):
     123        """Return a file object for the name/path in the constructor."""
     124        return open(self.name, self.mode)
     125
     126
     127class _RemoteFile(object):
     128    """
     129    Represent a file on the remote side which is to be transferred or
     130    is already transferred.
     131    """
     132
     133    def __init__(self, ftp_host, name, mode):
     134        self._host = ftp_host
     135        self._path = ftp_host.path
    109136        self.name = self._path.abspath(name)
    110137        self.mode = mode
     
    119146    def mtime(self):
    120147        """Return the timestamp for the last modification in seconds."""
    121         mtime_ = self._path.getmtime(self.name)
    122         if not self._is_local:
    123             # convert to client time zone; see definition of time
    124             #  shift in docstring of `FTPHost.set_time_shift`
    125             mtime_ -= self._host.time_shift()
    126         return mtime_
     148        # convert to client time zone; see definition of time
     149        #  shift in docstring of `FTPHost.set_time_shift`
     150        return self._path.getmtime(self.name) - self._host.time_shift()
    127151
    128152    def mtime_precision(self):
    129153        """Return the precision of the last modification time in seconds."""
    130         if self._is_local:
    131             # assume modification timestamps for local filesystems are
    132             #  at least precise up to a second
    133             return 1.0
    134         else:
    135             # I think using `stat` instead of `lstat` makes more sense here
    136             return self.stat(self.name)._st_mtime_precision
     154        # I think using `stat` instead of `lstat` makes more sense here
     155        return self._host.stat(self.name)._st_mtime_precision
    137156
    138157    def fobj(self):
    139158        """Return a file object for the name/path in the constructor."""
    140         if self._is_local:
    141             return open(self.name, self.mode)
    142         else:
    143             return self._host.file(self.name, self.mode)
     159        return self._host.file(self.name, self.mode)
    144160
    145161
     
    461477    def __get_modes(self, mode):
    462478        """Return modes for source and target file."""
     479        #XXX Should we allow mode "a" at all? We don't support appending!
    463480        #XXX use dictionary?
    464481        # invalid mode values are handled when a file object is made
     
    472489        Copy a file from `source_file` to `target_file`.
    473490       
    474         Both of these are `_TransferredFile` objects. Which of them is
    475         a local or a remote file, respectively, is determined by the
    476         arguments. If `conditional` is true, the file is only copied
    477         if the target doesn't exist or is older than the source. If
    478         `conditional` is false, the file is copied unconditionally.
     491        These are `_LocalFile` or `_RemoteFile` objects. Which of them
     492        is a local or a remote file, respectively, is determined by
     493        the arguments. If `conditional` is true, the file is only
     494        copied if the target doesn't exist or is older than the
     495        source. If `conditional` is false, the file is copied
     496        unconditionally.
    479497        """
    480498        if conditional:
     
    509527        """
    510528        source_mode, target_mode = self.__get_modes(mode)
    511         source_file = _TransferredFile(None, source, source_mode)
    512         target_file = _TransferredFile(self, target, target_mode)
     529        source_file = _LocalFile(source, source_mode)
     530        # passing `self` (the `FTPHost` instance) here is correct
     531        target_file = _RemoteFile(self, target, target_mode)
    513532        # the path in the stat cache is implicitly invalidated when
    514533        #  the file is opened on the remote host
     
    516535
    517536    def upload(self, source, target, mode=''):
    518         #FIXME should we support mode "a" at all? We don't support
    519         #  appending on remote files!
    520537        """
    521538        Upload a file from the local source (name) to the remote
     
    544561        """
    545562        source_mode, target_mode = self.__get_modes(mode)
    546         source_file = _TransferredFile(self, source, source_mode)
    547         target_file = _TransferredFile(None, target, target_mode)
     563        # passing `self` (the `FTPHost` instance) here is correct
     564        source_file = _RemoteFile(self, source, source_mode)
     565        target_file = _LocalFile(target, target_mode)
    548566        return self.__copy_file(source_file, target_file, conditional)
    549567
    550568    def download(self, source, target, mode=''):
    551         #FIXME should we support mode "a" at all? We don't support
    552         #  appending!
    553569        """
    554570        Download a file from the remote source (name) to the local
Note: See TracChangeset for help on using the changeset viewer.