[Tutor] Threaded FTP class
Bill Burns
billburns at pennswoods.net
Tue Oct 10 01:32:11 CEST 2006
Hi all,
I'm trying to make a small, threaded FTP app and I'm running into
a problem.
My program has a GUI (I use PythonCard) and I want the GUI to be
responsive while network operations are going on.
I assumed that if I made a class (shown below) which was sub-classed
from threading.Thread - I wouldn't have any problems.
My GUI class (not shown) has a 'connect' button with a method that
looks like this:
def on_connect_command(self, event):
"""Connect to the remote server."""
# getConnectData() -> returns a tuple with
# all of the data we need to connect.
server, username, password = self.getConnectData()
# Instantiate my threaded FTP class.
self.host = FTP(server, username, password)
self.host.setDaemon(True)
self.host.start()
time.sleep(1)
When I hit this button, the GUI is completely responsive while trying to
connect to the remote server. I have no problems and everything works as
expected.
Here's where I get the problem... The GUI class has another method which
looks like this:
def on_getData_command(self, event):
# getDirectoryData(...) is a method in the
# FTP() class. It walks a remote directory.
self.host.getDirectoryData(someDirectory)
When I fire this method - it blocks until getDirectoryData() returns,
which makes the GUI non-responsive. It's *not* hanging due to a network
problem (it will only fire if you're connected to the remote server.)
Why does this one method block? I assumed it would run in the FTP class
thread and I'd have no problems!? What should I do different?
Thanks,
Bill
A simplified version of my FTP class:
<code>
class FTP(threading.Thread):
"""This class requires ftputil which you can download
from here -> http://ftputil.sschwarzer.net/download
"""
def __init__(self, server, username, password):
threading.Thread.__init__(self)
self.server = server
self.username = username
self.password = password
self.host = None
self.connected = False
def run(self):
"""Connects to the remote server and prints a list
containing files and directories from the current
directory.
This does not block the GUI!
"""
try:
self.host = ftputil.FTPHost(
self.server,
self.username,
self.password)
data = self.getDirData()
self.connected = True
print data
except ftputil.ftp_error.FTPOSError:
self.connected = False
print 'Could not connect to remote server!'
def getDirData(self):
"""Returns a list containing remote 'listdir' output."""
return [d for d in self.host.listdir(self.host.curdir)]
def getDirectoryData(self, directory):
"""Walks the remote directory and then prints a list containing
the files which were found.
This blocks the GUI!
"""
if self.connected:
fileList = []
self.host.chdir(directory)
for root, dirs, files in self.host.walk(self.host.curdir):
for f in files:
fileList.append(self.host.path.abspath(
self.host.path.join(root, f)))
self.host.chdir('..')
print fileList
def disconnect(self):
"""Disconnect from the remote server."""
self.host.close()
self.connected = False
</code>
More information about the Tutor
mailing list