Rev 2507: Finish ftp refactoring. Test suite passing. in file:///v/home/vila/src/experimental/reuse.transports/

Vincent Ladeuil v.ladeuil+lp at free.fr
Fri Jun 1 08:25:52 BST 2007


At file:///v/home/vila/src/experimental/reuse.transports/

------------------------------------------------------------
revno: 2507
revision-id: v.ladeuil+lp at free.fr-20070601072550-oku4t5llxk4invum
parent: v.ladeuil+lp at free.fr-20070531181534-7dh1f70t6x8tq2mc
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: reuse.transports
timestamp: Fri 2007-06-01 09:25:50 +0200
message:
  Finish ftp refactoring. Test suite passing.
  
  * bzrlib/transport/ftp.py:
  (FtpTransport.__init__): Simplified.
  (FtpTransport._unparse_url): Deleted.
  (FtpTransport._abspath): Deleted and reimplemented as a
  specialisation of _remote_path. The heart is: we don't support
  Unicode paths :-/
  (FtpTransport.abspath): Deleted.
modified:
  bzrlib/transport/ftp.py        ftp.py-20051116161804-58dc9506548c2a53
-------------- next part --------------
=== modified file 'bzrlib/transport/ftp.py'
--- a/bzrlib/transport/ftp.py	2007-05-30 07:15:16 +0000
+++ b/bzrlib/transport/ftp.py	2007-06-01 07:25:50 +0000
@@ -47,7 +47,6 @@
 from bzrlib.trace import mutter, warning
 from bzrlib.transport import (
     Server,
-    split_url,
     ConnectedTransport,
     )
 from bzrlib.transport.local import LocalURLServer
@@ -82,54 +81,30 @@
 
     def __init__(self, base, _provided_instance=None):
         """Set the base path where files will be stored."""
-        assert base.startswith('ftp://') or base.startswith('aftp://')
-
-        self.is_active = base.startswith('aftp://')
-        if self.is_active:
-            # urlparse won't handle aftp://, delete the leading 'a'
-            # FIXME: This breaks even hopes of connection sharing
-            # (by reusing the url instead of true cloning) by
-            # modifying the the url coming from the user.
-            base = base[1:]
-        if not base.endswith('/'):
-            base += '/'
-        (self._proto, self._username,
-            self._password, self._host,
-            self._port, self._path) = split_url(base)
-        base = self._unparse_url()
-
         super(FtpTransport, self).__init__(base)
+        if self._scheme == 'aftp':
+            self._unqualified_scheme = 'ftp'
+            self.is_active = True
+        else:
+            self._unqualified_scheme = self._scheme
+            self.is_active = False
         self._FTP_instance = _provided_instance
 
-    def _unparse_url(self, path=None):
-        if path is None:
-            path = self._path
-        path = urllib.quote(path)
-        netloc = urllib.quote(self._host)
-        if self._username is not None:
-            netloc = '%s@%s' % (urllib.quote(self._username), netloc)
-        if self._port is not None:
-            netloc = '%s:%d' % (netloc, self._port)
-        proto = 'ftp'
-        if self.is_active:
-            proto = 'aftp'
-        return urlparse.urlunparse((proto, netloc, path, '', '', ''))
-
     def _get_FTP(self):
         """Return the ftplib.FTP instance for this object."""
         if self._FTP_instance is None:
             mutter("Constructing FTP instance against %r" %
-                   ((self._host, self._port, self._username, '********',
+                   ((self._host, self._port, self._user, '********',
                     self.is_active),))
             try:
                 connection = ftplib.FTP()
                 connection.connect(host=self._host, port=self._port)
-                if self._username and self._username != 'anonymous' and \
+                if self._user and self._user != 'anonymous' and \
                         not self._password:
                     self._password = bzrlib.ui.ui_factory.get_password(
                         prompt='FTP %(user)s@%(host)s password',
-                        user=self._username, host=self._host)
-                connection.login(user=self._username, passwd=self._password)
+                        user=self._user, host=self._host)
+                connection.login(user=self._user, passwd=self._password)
                 connection.set_pasv(not self.is_active)
             except ftplib.error_perm, e:
                 raise errors.TransportError(msg="Error setting up connection:"
@@ -187,43 +162,16 @@
         else:
             return FtpTransport(self.abspath(offset), self._FTP_instance)
 
-    def _abspath(self, relpath):
-        assert isinstance(relpath, basestring)
-        relpath = urlutils.unescape(relpath)
-        if relpath.startswith('/'):
-            basepath = []
-        else:
-            basepath = self._path.split('/')
-        if len(basepath) > 0 and basepath[-1] == '':
-            basepath = basepath[:-1]
-        for p in relpath.split('/'):
-            if p == '..':
-                if len(basepath) == 0:
-                    # In most filesystems, a request for the parent
-                    # of root, just returns root.
-                    continue
-                basepath.pop()
-            elif p == '.' or p == '':
-                continue # No-op
-            else:
-                basepath.append(p)
-        # Possibly, we could use urlparse.urljoin() here, but
-        # I'm concerned about when it chooses to strip the last
-        # portion of the path, and when it doesn't.
-
+    def _remote_path(self, relpath):
         # XXX: It seems that ftplib does not handle Unicode paths
-        # at the same time, medusa won't handle utf8 paths
-        # So if we .encode(utf8) here, then we get a Server failure.
-        # while if we use str(), we get a UnicodeError, and the test suite
-        # just skips testing UnicodePaths.
-        return str('/'.join(basepath) or '/')
-    
-    def abspath(self, relpath):
-        """Return the full url to the given relative path.
-        This can be supplied with a string or a list
-        """
-        path = self._abspath(relpath)
-        return self._unparse_url(path)
+        # at the same time, medusa won't handle utf8 paths So if
+        # we .encode(utf8) here (see ConnectedTransport
+        # implementation), then we get a Server failure.  while
+        # if we use str(), we get a UnicodeError, and the test
+        # suite just skips testing UnicodePaths.
+        relative = str(urlutils.unescape(relpath))
+        remote_path = self._combine_paths(self._path, relative)
+        return remote_path
 
     def has(self, relpath):
         """Does the target location exist?"""
@@ -232,7 +180,7 @@
         # XXX: I assume we're never asked has(dirname) and thus I use
         # the FTP size command and assume that if it doesn't raise,
         # all is good.
-        abspath = self._abspath(relpath)
+        abspath = self._remote_path(relpath)
         try:
             f = self._get_FTP()
             mutter('FTP has check: %s => %s', relpath, abspath)
@@ -258,10 +206,10 @@
         """
         # TODO: decode should be deprecated
         try:
-            mutter("FTP get: %s", self._abspath(relpath))
+            mutter("FTP get: %s", self._remote_path(relpath))
             f = self._get_FTP()
             ret = StringIO()
-            f.retrbinary('RETR '+self._abspath(relpath), ret.write, 8192)
+            f.retrbinary('RETR '+self._remote_path(relpath), ret.write, 8192)
             ret.seek(0)
             return ret
         except ftplib.error_perm, e:
@@ -297,7 +245,7 @@
         TODO: jam 20051215 ftp as a protocol seems to support chmod, but
         ftplib does not
         """
-        abspath = self._abspath(relpath)
+        abspath = self._remote_path(relpath)
         tmp_abspath = '%s.tmp.%.9f.%d.%d' % (abspath, time.time(),
                         os.getpid(), random.randint(0,0x7FFFFFFF))
         if getattr(fp, 'read', None) is None:
@@ -339,7 +287,7 @@
 
     def mkdir(self, relpath, mode=None):
         """Create a directory at the given path."""
-        abspath = self._abspath(relpath)
+        abspath = self._remote_path(relpath)
         try:
             mutter("FTP mkd: %s", abspath)
             f = self._get_FTP()
@@ -350,7 +298,7 @@
 
     def rmdir(self, rel_path):
         """Delete the directory at rel_path"""
-        abspath = self._abspath(rel_path)
+        abspath = self._remote_path(rel_path)
         try:
             mutter("FTP rmd: %s", abspath)
             f = self._get_FTP()
@@ -362,7 +310,7 @@
         """Append the text in the file-like object into the final
         location.
         """
-        abspath = self._abspath(relpath)
+        abspath = self._remote_path(relpath)
         if self.has(relpath):
             ftp = self._get_FTP()
             result = ftp.size(abspath)
@@ -381,7 +329,7 @@
         number of retries is exceeded.
         """
         try:
-            abspath = self._abspath(relpath)
+            abspath = self._remote_path(relpath)
             mutter("FTP appe (try %d) to %s", retries, abspath)
             ftp = self._get_FTP()
             ftp.voidcmd("TYPE I")
@@ -412,14 +360,14 @@
         """
         try:
             mutter("FTP site chmod: setting permissions to %s on %s",
-                str(mode), self._abspath(relpath))
+                str(mode), self._remote_path(relpath))
             ftp = self._get_FTP()
-            cmd = "SITE CHMOD %s %s" % (self._abspath(relpath), str(mode))
+            cmd = "SITE CHMOD %s %s" % (self._remote_path(relpath), str(mode))
             ftp.sendcmd(cmd)
         except ftplib.error_perm, e:
             # Command probably not available on this server
             warning("FTP Could not set permissions to %s on %s. %s",
-                    str(mode), self._abspath(relpath), str(e))
+                    str(mode), self._remote_path(relpath), str(e))
 
     # TODO: jam 20060516 I believe ftp allows you to tell an ftp server
     #       to copy something to another machine. And you may be able
@@ -427,8 +375,8 @@
     #       So implement a fancier 'copy()'
 
     def rename(self, rel_from, rel_to):
-        abs_from = self._abspath(rel_from)
-        abs_to = self._abspath(rel_to)
+        abs_from = self._remote_path(rel_from)
+        abs_to = self._remote_path(rel_to)
         mutter("FTP rename: %s => %s", abs_from, abs_to)
         f = self._get_FTP()
         return self._rename(abs_from, abs_to, f)
@@ -442,8 +390,8 @@
 
     def move(self, rel_from, rel_to):
         """Move the item at rel_from to the location at rel_to"""
-        abs_from = self._abspath(rel_from)
-        abs_to = self._abspath(rel_to)
+        abs_from = self._remote_path(rel_from)
+        abs_to = self._remote_path(rel_to)
         try:
             mutter("FTP mv: %s => %s", abs_from, abs_to)
             f = self._get_FTP()
@@ -464,7 +412,7 @@
 
     def delete(self, relpath):
         """Delete the item at relpath"""
-        abspath = self._abspath(relpath)
+        abspath = self._remote_path(relpath)
         f = self._get_FTP()
         self._delete(abspath, f)
 
@@ -482,7 +430,7 @@
 
     def list_dir(self, relpath):
         """See Transport.list_dir."""
-        basepath = self._abspath(relpath)
+        basepath = self._remote_path(relpath)
         mutter("FTP nlst: %s", basepath)
         f = self._get_FTP()
         try:
@@ -515,7 +463,7 @@
 
     def stat(self, relpath):
         """Return the stat information for a file."""
-        abspath = self._abspath(relpath)
+        abspath = self._remote_path(relpath)
         try:
             mutter("FTP stat: %s", abspath)
             f = self._get_FTP()



More information about the bazaar-commits mailing list