localpath = os.path.join(localdir, remotename)
print('downloading', remotename, 'to', localpath, end=' ')
print('as', maintype, encoding or '')
if maintype == 'text' and encoding == None:
use ascii mode xfer and text file
use encoding compatible wth ftplib's
localfile = open(localpath, 'w', encoding=connection.encoding)
callback = lambda line: localfile.write(line + '\n')
connection.retrlines('RETR ' + remotename, callback)
else:
use binary mode xfer and bytes file
localfile = open(localpath, 'wb')
connection.retrbinary('RETR ' + remotename, localfile.write)
localfile.close()
count += 1
connection.quit()
print('Done:', count, 'files downloaded.')
There’s not much that is new to speak of in this script, compared to other FTP examples
we’ve seen thus far. We open a connection with the remote FTP server, log in with a
username and password for the desired account (this script never uses anonymous
FTP), and go to the desired remote directory. New here, though, are loops to iterate
over all the files in local and remote directories, text-based retrievals, and file deletions:
Deleting all local files
This script has a cleanall option, enabled by an interactive prompt. If selected,
the script first deletes all the files in the local directory before downloading, to make
sure there are no extra files that aren’t also on the server (there may be junk here
from a prior download). To delete local files, the script calls os.listdir to get a list
of filenames in the directory, and os.remove to delete each; see Chapter 4 (or the
Python library manual) for more details if you’ve forgotten what these calls do.
Notice the use of os.path.join to concatenate a directory path and filename ac-
cording to the host platform’s conventions; os.listdir returns filenames without
their directory paths, and this script is not necessarily run in the local directory
where downloads will be placed. The local directory defaults to the current direc-
tory (“.”), but can be set differently with a command-line argument to the script.
Fetching all remote files
To grab all the files in a remote directory, we first need a list of their names. The
FTP object’s nlst method is the remote equivalent of os.listdir: nlst returns a
list of the string names of all files in the current remote directory. Once we have
this list, we simply step through it in a loop, running FTP retrieval commands for
each filename in turn (more on this in a minute).
The nlst method is, more or less, like requesting a directory listing with an ls
command in typical interactive FTP programs, but Python automatically splits up
876 | Chapter 13: Client-Side Scripting