thanks for your reply, i will check the codes.. 2009/2/11 Jean-Paul Calderone <[email protected]>
> On Wed, 11 Feb 2009 11:43:07 +0800, 柳锴 <[email protected]> wrote: > >> hello, everyone: >> >> I'm new to twisted and ftp protocol. for some purpose, i need a python >> ftp client to do list, get, put, remove operations upon a FTP server which >> is implemented with twisted. >> here is my codes, testing for 'get' passed, but 'put' failed. i checked >> the api of storeFile, abd got these: >> >> [snip] >> >> but i don't know how to handle it, :) >> sorry for the rubbish codes, but i really need help from you guys, it's >> hard to find some useful info from twisted official doc, >> Any suggestion on how to write a nice ftp client with twisted is welcome. >> Thanks in advance. >> > > The most obvious problem with the code is that it uses reactor.run and > reactor.stop too much. You can start and stop the reactor exactly once. > > IOSCAS >> >> >> ______________________________________________________________________________ >> >> from twisted.protocols.ftp import FTPClient, FTPFileListProtocol >> from twisted.internet.protocol import Protocol, ClientCreator >> from twisted.python import usage >> from twisted.internet import reactor, defer >> >> class SaveFile(Protocol): >> ''' >> save the ftp file to local filesystem >> ''' >> def __init__(self, output): >> self.fout = open(output, 'w') >> >> def dataReceived(self, data): >> self.fout.write(data) >> self.fout.close() >> > > This is also probably wrong. dataReceived may be called multiple times. > You can't close the output file until you've received all the data. I'm > not sure, but connectionLost is probably called when all data has been > received (or if there is an error receiving the data). > > class FTP: >> ''' >> a simple ftp client >> ''' >> def __init__(self, host, port): >> ''' >> init >> ''' >> self.__host = host >> self.__port = port >> self.__username = 'aaa' >> self.__passwd = 'bbb' >> self.__passive = 1 >> >> def __get(self, ftp_client, src, des): >> ''' >> ''' >> save_file = SaveFile(des) >> d = ftp_client.retrieveFile(src, save_file) >> d = ftp_client.quit() >> d.addCallback(lambda result: reactor.stop()) >> return d >> > > Don't stop the reactor here. Stopping the reactor means your program is > basically done and you don't want to do anything else with Twisted. > > def get(self, src, des): >> ''' >> get src file from ftp server, store it in des >> ''' >> creator = ClientCreator(reactor, FTPClient, self.__username, >> self.__passwd, self.__passive) >> defer = creator.connectTCP(self.__host, >> self.__port).addCallback(self.__get, src, des) >> reactor.run() >> return defer.result >> > > Don't start the reactor here. Start the reactor in the "main" part of your > program. Also, don't access "defer.result". Instead, just return "defer". > > >> def __put(self, ftp_client, src, des): >> ''' >> ''' >> source_file = os.path.basename(src) >> target_dir = os.path.dirname(des) >> ftp_client.changeDirectory(target_dir) >> d = ftp_client.storeFile(src) >> d = ftp_client.quit() >> d.addCallback(lambda result: reactor.stop()) >> return d >> > > Again, don't use stop here. > > def put(self, src, des): >> ''' >> put src file to ftp server, store it in des >> ''' >> creator = ClientCreator(reactor, FTPClient, self.__username, >> self.__passwd, self.__passive) >> defer = creator.connectTCP(self.__host, >> self.__port).addCallback(self.__put, src, des) >> reactor.run() >> return defer.result >> >> > And don't use run or .result here. > > Jean-Paul > > > _______________________________________________ > Twisted-Python mailing list > [email protected] > http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python >
_______________________________________________ Twisted-Python mailing list [email protected] http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
