dir ='.',
user=('lutz', getpass('Pswd?')),
refetch=True)
rest is the same
if input('Open file?') in ['Y', 'y']:
from PP4E.System.Media.playfile import playfile
playfile(filename)
Besides having a much smaller line count, the meat of this script has been split off into
a file for reuse elsewhere. If you ever need to download a file again, simply import an
existing function instead of copying code with cut-and-paste editing. Changes in down-
load operations would need to be made in only one file, not everywhere we’ve copied
boilerplate code; getfile.getfile could even be changed to use urllib rather than
ftplib without affecting any of its clients. It’s good engineering.
Download utility
So just how would we go about writing such an FTP interface wrapper (he asks, rhet-
orically)? Given the ftplib library module, wrapping downloads of a particular file in
a particular directory is straightforward. Connected FTP objects support two download
methods:
retrbinary
This method downloads the requested file in binary mode, sending its bytes in
chunks to a supplied function, without line-feed mapping. Typically, the supplied
function is a write method of an open local file object, such that the bytes are placed
in the local file on the client.
retrlines
This method downloads the requested file in ASCII text mode, sending each line
of text to a supplied function with all end-of-line characters stripped. Typically,
the supplied function adds a \n newline (mapped appropriately for the client ma-
chine), and writes the line to a local file.
We will meet the retrlines method in a later example; the getfile utility module in
Example 13-4 always transfers in binary mode with retrbinary. That is, files are down-
loaded exactly as they were on the server, byte for byte, with the server’s line-feed
conventions in text files (you may need to convert line feeds after downloads if they
look odd in your text editor—see your editor or system shell commands for pointers,
or write a Python script that opens and writes the text as needed).
Example 13-4. PP4E\Internet\Ftp\getfile.py
#!/usr/local/bin/python
"""
Fetch an arbitrary file by FTP. Anonymous FTP unless you pass a
user=(name, pswd) tuple. Self-test FTPs a test file and site.
"""
Transferring Files with ftplib | 861