------------------------------------------getfile.py
!/usr/local/bin/python
from ftplib import FTP # socket-based FTP tools
from os.path import exists # file existence test
def getfile(file, site, dir, user=(), , verbose=True, refetch=False):
"""
fetch a file by ftp from a site/directory
anonymous or real login, binary transfer
"""
if exists(file) and not refetch:
if verbose: print(file, 'already fetched')
else:
if verbose: print('Downloading', file)
local = open(file, 'wb') # local file of same name
try:
remote = FTP(site) # connect to FTP site
remote.login(user) # anonymous=() or (name, pswd)
remote.cwd(dir)
remote.retrbinary('RETR ' + file, local.write, 1024)
remote.quit()
finally:
local.close() # close file no matter what
if verbose: print('Download done.') # caller handles exceptions
if name == 'main':
from getpass import getpass
file = 'monkeys.jpg'
dir = '.'
site = 'ftp.rmi.net'
user = ('lutz', getpass('Pswd?'))
getfile(file, site, dir, user)
---------------------------------getfilegui.py
from tkinter import Tk, mainloop
from tkinter.messagebox import showinfo
import getfile, os, sys, _thread # FTP getfile here, not socket
from PP4E.Internet.Sockets.form import Form # reuse form tool in socket dir
class FtpForm(Form):
def init(self):
root = Tk()
root.title(self.title)
labels = ['Server Name', 'Remote Dir', 'File Name',
'Local Dir', 'User Name?', 'Password?']
Form.init(self, labels, root)
self.mutex = _thread.allocate_lock()
self.threads = 0
def transfer(self, filename, servername, remotedir, userinfo):
try:
self.do_transfer(filename, servername, remotedir, userinfo)
print('%s of "%s" successful' % (self.mode, filename))
except:
print('%s of "%s" has failed:' % (self.mode, filename), end=' ')
print(sys.exc_info()[0], sys.exc_info()[1])
self.mutex.acquire()
self.threads -= 1
self.mutex.release()
def onSubmit(self):
Form.onSubmit(self)
localdir = 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 password:
userinfo = (username, password)
if localdir:
os.chdir(localdir)
self.mutex.acquire()
self.threads += 1
self.mutex.release()
ftpargs = (filename, servername, remotedir, userinfo)
_thread.start_new_thread(self.transfer, ftpargs)
showinfo(self.title, '%s of "%s" started' % (self.mode, filename))
def onCancel(self):
if self.threads == 0:
Tk().quit()
else:
showinfo(self.title,
'Cannot exit: %d threads running' % self.threads)
class FtpGetfileForm(FtpForm):
title = 'FtpGetfileGui'
mode = 'Download'
def do_transfer(self, filename, servername, remotedir, userinfo):
getfile.getfile(
filename, servername, remotedir, userinfo, verbose=False, refetch=True)
if name == 'main':
FtpGetfileForm()
mainloop()
-----------------------------------------------------Form.py
from tkinter import *
entrysize = 40
class Form: # add non-modal form box
def init(self, labels, parent=None): # pass field labels list
labelsize = max(len(x) for x in labels) + 2
box = Frame(parent) # box has rows, buttons
box.pack(expand=YES, fill=X) # rows has row frames
rows = Frame(box, bd=2, relief=GROOVE) # go=button or return key
rows.pack(side=TOP, expand=YES, fill=X) # runs onSubmit method
self.content = {}
for label in labels:
row = Frame(rows)
row.pack(fill=X)
Label(row, text=label, width=labelsize).pack(side=LEFT)
entry = Entry(row, width=entrysize)
entry.pack(side=RIGHT, expand=YES, fill=X)
self.content[label] = entry
Button(box, text='Cancel', command=self.onCancel).pack(side=RIGHT)
Button(box, text='Submit', command=self.onSubmit).pack(side=RIGHT)
box.master.bind('<Return>', (lambda event: self.onSubmit()))
def onSubmit(self): # override this
for key in self.content: # user inputs in
print(key, '\t=>\t', self.content[key].get()) # self.content[k]
def onCancel(self): # override if need
Tk().quit() # default is exit
class DynamicForm(Form):
def init(self, labels=None):
labels = input('Enter field names: ').split()
Form.init(self, labels)
def onSubmit(self):
print('Field values...')
Form.onSubmit(self)
self.onCancel()