labels ['server name''remote dir''file name''local dir''user name?''password?'form __init__(selflabelsrootself mutex _thread allocate_lock(self threads def transfer(selffilenameservernameremotediruserinfo)tryself do_transfer(filenameservernameremotediruserinfoprint('% of "%ssuccessful(self modefilename)exceptprint('% of "%shas failed:(self modefilename)end='print(sys exc_info()[ ]sys exc_info()[ ]self mutex acquire(self threads - self mutex release(def onsubmit(self)form onsubmit(selflocaldir self content['local dir'get(remotedir self content['remote dir'get(servername self content['server name'get(filename self content['file name'get(username self content['user name?'get(password self content['password?'get(userinfo (if username and passworduserinfo (usernamepasswordif localdiros chdir(localdirself mutex acquire(self threads + self mutex release(ftpargs (filenameservernameremotediruserinfo_thread start_new_thread(self transferftpargsshowinfo(self title'% of "%sstarted(self modefilename)def oncancel(self)if self threads = tk(quit(elseshowinfo(self title'cannot exit% threads runningself threadsclass ftpgetfileform(ftpform)title 'ftpgetfileguimode 'downloaddef do_transfer(selffilenameservernameremotediruserinfo)getfile getfilefilenameservernameremotediruserinfoverbose=falserefetch=trueif __name__ ='__main__'ftpgetfileform(mainloop( client-side scripting