[PATCH] FTP transport append()

Alexandre Saint stalst at gmail.com
Sun Apr 16 12:25:11 BST 2006


Oh, sorry. I forgot one more commit. Here's the right patch.

On Sun, Apr 16, 2006 at 01:15:12PM +0200, Alexandre Saint wrote:
> Hi,
> 
> Here's another patch for the FTP transport:
> 
> - Implemented a append() method. So pushing with knit format is working now.
> - Fixed _abspath() to return the given path when it is given a absolute path.
- Simplified listdir().

In fact, the NLST command of the FTP protocol will only return *named* files,
so no "." or "..". Moreover, the files are returned relative.

> 
> Cheers,
> Alex.
> -- 
> alex



-- 
alex
-------------- next part --------------
=== modified file 'a/bzrlib/transport/ftp.py'
--- a/bzrlib/transport/ftp.py	
+++ b/bzrlib/transport/ftp.py	
@@ -134,8 +134,8 @@
             relpath_parts = relpath[:]
         if len(relpath_parts) > 1:
             if relpath_parts[0] == '':
-                raise ValueError("path %r within branch %r seems to be absolute"
-                                 % (relpath, self._path))
+                # the path seems to be absolute
+                return relpath
         basepath = self._path.split('/')
         if len(basepath) > 0 and basepath[-1] == '':
             basepath = basepath[:-1]
@@ -303,11 +303,39 @@
                 raise TransportError(msg="Cannot remove directory at %s" % \
                         self._abspath(rel_path), extra=str(e))
 
-    def append(self, relpath, f):
+    def append(self, relpath, fp, retries=0):
         """Append the text in the file-like object into the final
         location.
         """
-        raise TransportNotPossible('ftp does not support append()')
+        if isinstance(fp, basestring):
+            fp = StringIO(fp)
+        fp.seek(0)
+        try:
+            abspath = self._abspath(relpath)
+            mutter("FTP appe to %s" % abspath)
+            ftp = self._get_FTP()
+            if self.has(abspath):
+                length = ftp.size(abspath)
+            else:
+                length = 0
+            ftp.voidcmd("TYPE I")
+            cmd = "APPE %s" % abspath
+            conn = ftp.transfercmd(cmd)
+            conn.sendall(fp.read())
+            conn.close()
+            ftp.getresp()
+            return length
+        except ftplib.error_perm, e:
+            FtpTransportError("Error appending data to %s" % abspath,
+                    orig_error=e)
+        except ftplib.error_temp, e:
+            if retries > _number_of_retries:
+                raise TransportError("FTP temporary error during APPEND %s." \
+                        "Aborting." % self.abspath(relpath), orig_error=e)
+            else:
+                warning("FTP temporary error: %s. Retrying." % str(e))
+                self._FTP_instance = None
+                self.append(relpath, fp, retries+1)
 
     def copy(self, rel_from, rel_to):
         """Copy the item at rel_from to the location at rel_to"""
@@ -347,11 +375,7 @@
             mutter("FTP nlst: %s" % self._abspath(relpath))
             f = self._get_FTP()
             basepath = self._abspath(relpath)
-            # FTP.nlst returns paths prefixed by relpath, strip 'em
-            the_list = f.nlst(basepath)
-            stripped = [path[len(basepath)+1:] for path in the_list]
-            # Remove . and .. if present, and return
-            return [path for path in stripped if path not in (".", "..")]
+            return f.nlst(basepath)
         except ftplib.error_perm, e:
             raise TransportError(orig_error=e)
 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 191 bytes
Desc: not available
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20060416/18dc906d/attachment.pgp 


More information about the bazaar mailing list