title: twisted.protocols.ftp.FTPClient and Deferreds
body: <p>Like most it's taking me a while to get used to using Deferreds but I'm slowly getting there. However, it's not clear to me how I can process a response and then call another FTP command <em>using the processed response</em> when using Twisted's FTP module. I'm using the the <a href="http://twistedmatrix.com/documents/current/core/examples/ftpclient.py" rel="nofollow noreferrer">example FTP code</a> as my jumping off point.</p>
  
  <p>I want to connect to a FTP server, get all the top level directories, then enter each one and download all the files.</p>
  
  <p>First I connect:</p>
  
  <pre><code>creator = ClientCreator(reactor, FTPClient, config.opts['username'], config.opts['password'], passive=config.opts['passive'])
  creator.connectTCP(config.opts['host'], config.opts['port']).addCallback(connectionMade).addErrback(connectionFailed)
  reactor.run()
  </code></pre>
  
  <p>It connects successfully, so my <code>connectionMade</code> function gets called:</p>
  
  <pre><code>def connectionMade(ftpClient):
      # Get a detailed listing of the current directory
      fileList = FTPFileListProtocol()
      d = ftpClient.list('.', fileList)
      d.addCallbacks(getSortedDirectories, fail, callbackArgs=(fileList,))
      d.addCallback(enterDirs)
  </code></pre>
  
  <p>As you see, I queue up <code>getSortedDirectories</code> and then <code>enterDirs</code>.</p>
  
  <pre><code>def getSortedDirectories(result, fileListProtocol):
      # Go through all directories from greatest to least
      dirs = [directory for directory in sorted(fileListProtocol.files, reverse=True) if directory['filetype'] == 'd']
      return dirs
  </code></pre>
  
  <p>My question is, how do I go through the directories in <code>enterDirs</code>?</p>
  
  <pre><code>def enterDirs(dirs):
      for directory in dirs:
          print "We'd be entering '%s' now." % directory
  </code></pre>
  
  <p>Should I be passing <code>ftpClient</code> to <code>enterDirs</code> like <code>fileList</code> is passed to <code>getSortedDirectories</code> and then make my download requests?</p>
  
  <pre><code>d.addCallback(enterDirs, callbackArgs=(ftpClient,))
  
  def enterDirs(dirs, ftpClient):
      for directory in dirs:
          fileList = FTPFileListProtocol()
          d = ftpClient.list(directory, fileList)
          d.addCallbacks(downloadFiles, fail, callbackArgs=(directory, fileList, ftpClient))
  
  def downloadFiles(result, directory, fileListProtocol, ftpClient):
      for f in fileListProtocol.files if f.filetype == '-':
          fileConsumer = FileConsumer()
          ftpClient.retrieveFile(os.path.join(directory['filename'], file['filename']), fileConsumer)
  </code></pre>
  
  <p>Is this the best approach?</p>