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