Similar to the mirror download script, this program illustrates a handful of new FTP
interfaces and a set of FTP scripting techniques:
Deleting all remote files
Just like the mirror script, the upload begins by asking whether we want to delete
all the files in the remote target directory before copying any files there. This
cleanall option is useful if we’ve deleted files in the local copy of the directory in
the client—the deleted files would remain on the server-side copy unless we delete
all files there first.
To implement the remote cleanup, this script simply gets a listing of all the files in
the remote directory with the FTP nlst method, and deletes each in turn with
the FTP delete method. Assuming we have delete permission, the directory will
be emptied (file permissions depend on the account we logged into when con-
necting to the server). We’ve already moved to the target remote directory when
deletions occur, so no directory paths need to be prepended to filenames here. Note
that nlst may raise an exception for some servers if the remote directory is empty;
we don’t catch the exception here, but you can simply not select a cleaning if one
fails for you. We do catch deletion exceptions, because directory names like “.”
and “..” may be returned in the listing by some servers.
Storing all local files
To apply the upload operation to each file in the local directory, we get a list of
local filenames with the standard os.listdir call, and take care to prepend the
local source directory path to each filename with the os.path.join call. Recall that
os.listdir returns filenames without directory paths, and the source directory may
not be the same as the script’s execution directory if passed on the command line.
Uploading: Text versus binary
This script may also be run on both Windows and Unix-like clients, so we need to
handle text files specially. Like the mirror download, this script picks text or binary
transfer modes by using Python’s mimetypes module to guess a file’s type from its
filename extension; HTML and text files are moved in FTP text mode, for instance.
We already met the storbinary FTP object method used to upload files in binary
mode—an exact, byte-for-byte copy appears at the remote site.
Text-mode transfers work almost identically: the storlines method accepts an FTP
command string and a local file (or file-like) object, and simply copies each line
read from the local file to a same-named file on the remote machine.
Notice, though, that the local text input file must be opened in rb binary mode in
Python3.X. Text input files are normally opened in r text mode to perform Unicode
decoding and to convert any \r\n end-of-line sequences on Windows to the \n
platform-neutral character as lines are read. However, ftplib in Python 3.1 requires
that the text file be opened in rb binary mode, because it converts all end-lines to
the \r\n sequence for transmission; to do so, it must read lines as raw bytes with
readlines and perform bytes string processing, which implies binary mode files.
882 | Chapter 13: Client-Side Scripting