[Twisted-Python] Ftp client

Andrew Bennetts andrew-twisted at puzzling.org
Wed Aug 3 14:42:58 EDT 2005

On Wed, Aug 03, 2005 at 07:23:56PM +0200, Michele Petrazzo wrote:
> Andrew Bennetts wrote:
> >>One problem is that if the user has no password, I receive an error [1] 
> >>(if I try to connect with a simple ftp client, when I connect to the 
> >>server, if it see that I have no password, it connect me without 
> >>password request), however if the user _has_ password, the client 
> >>connect correctly.
> >
> >
> >Before connecting, can you add:
> >
> >    FTPClient.debug = True
> >
> >Then we can see a full transcript of what's going on.
> >
> I add that line, but I can't see any new line except that I already seen

Odd.  It should log everything.

> >>Second:
> >>if the user _has_ password, so I can connect, I want to send "LIST 
> >>status" command, if I use:
> >>
> >>ftpClient.queueStringCommand("LIST").addCallbacks(success, fail)
> >>
> >>I receive [2], and if I use:
> >
> >
> >Right.  LIST requires a data connection to be established, and directly
> >issuing a LIST without arranging for a PASV or PORT command and associated
> >connection will fail.
> >
> Ok, but what I do with to make it work?

Use FTPClient.list ;)

Seriously, look at the implementation of FTPClient.list, it's very simple:

    def list(self, path, protocol):
        # ...docstring elided...
        if path is None:
            path = ''
        return self.receiveFromConnection(['LIST ' + self.escapePath(path)], protocol)

FTPClient.receiveFromConnection is a helper function that Does The Right
Thing depending on if self.passive is set or not.

> >
> >I don't understand why you're passing ' status ' instead of just 'status',
> >though.
> But, I don't know :)
> With this change " status " -> "status" now I don't receive any error!

Ok, I suspect what was happening was that the server was returning an error
like "' status ' does not exist".  The error reporting from FTPClient is
pretty messy, unfortunately.

> But what I receive is an empty file list [2] (on all status and recvq 
> sub-directory), both case if I change directory with the cwd command and 
> call ftpClient.list(".") or, call it with "status/"-"recvq/".
> But I know that into that sub-directory there are a lot of files...

Perhaps FTPFileListProtocol can't parse your file listing -- it tries to
parse stuff more-or-less like:

        -rw-r--r--   1 root     other        531 Jan 29 03:26 README

If you have another format, you'll need to write your own.  As a starting
point, you could try:

class LineRecorder(basic.LineReceiver):
    def connectionMade(self):
        self.lines = []
    def lineReceived(self,line):

Alternatively, subclass FTPFileListProtocol and override the unknownLine

> [1]
> The return are (on both OS):
> [Failure instance: Traceback (failure with no frames): 
> twisted.internet.defer.FirstError: 
> FirstError(<twisted.python.failure.Failure 
> twisted.internet.defer.FirstError>, 0)
> ]

Sorry, I was too hasty here -- you also need to change your errback to print
failure.subFailure or perhaps failure.subFailure.subFailure rather than just
failure.  There are several layers of failure here (because of several
layers of DeferredLists), which makes it ugly.  FTPClient shouldn't be
exposing the implementation detail of DeferredLists like this, but at the
moment it does.


More information about the Twisted-Python mailing list