changed its behavior, though, we’ve modified the script’s software structure radically—
its code is now a set of tools that can be imported and reused in other programs.
The refactored upload program in Example 13-13, for instance, is now noticeably sim-
pler, and the code it shares with the download script only needs to be changed in one
place if it ever requires improvement.
Example 13-13. PP4E\Internet\Ftp\Mirror\uploadflat_modular.py
#!/bin/env python
"""
##############################################################################
use FTP to upload all files from a local dir to a remote site/directory;
this version reuses downloader's functions, to avoid code redundancy;
##############################################################################
"""
import os
from downloadflat_modular import configTransfer, connectFtp, isTextKind
def cleanRemotes(cf, connection):
"""
try to delete all remote files first to remove garbage
"""
if cf.cleanall:
for remotename in connection.nlst(): # remote dir listing
try: # remote file delete
print('deleting remote', remotename) # skips. and .. exc
connection.delete(remotename)
except:
print('cannot delete remote', remotename)
def uploadAll(cf, connection):
"""
upload all files to remote site/dir per cf config
listdir() strips dir path, any failure ends script
"""
localfiles = os.listdir(cf.localdir) # listdir is local listing
for localname in localfiles:
localpath = os.path.join(cf.localdir, localname)
print('uploading', localpath, 'to', localname, 'as', end=' ')
if isTextKind(localname):
use text mode xfer
localfile = open(localpath, 'rb')
connection.storlines('STOR ' + localname, localfile)
else:
use binary mode xfer
localfile = open(localpath, 'rb')
connection.storbinary('STOR ' + localname, localfile)
localfile.close()
connection.quit()
print('Done:', len(localfiles), 'files uploaded.')
if name == 'main':
cf = configTransfer(site='learning-python.com', rdir='books', user='lutz')
Transferring Directories with ftplib | 887