!/bin/env python
import os, sys, ftplib from getpass import getpass from mimetypes import guess_type, add_type
defaultSite = 'home.rmi.net' defaultRdir = '.' defaultUser = 'lutz'
def configTransfer(site=defaultSite, rdir=defaultRdir, user=defaultUser): class cf: pass cf.nonpassive = False # passive FTP on by default in 2.1 cf.remotesite = site # transfer to/from this site cf.remotedir = rdir # and this dir ('.' means acct root) cf.remoteuser = user cf.localdir = (len(sys.argv) > 1 and sys.argv[1]) or '.' cf.cleanall = input('Clean target directory first? ')[:1] in ['y','Y'] cf.remotepass = getpass( 'Password for %s on %s:' % (cf.remoteuser, cf.remotesite)) return cf
def isTextKind(remotename, trace=True): add_type('text/x-python-win', '.pyw') # not in tables mimetype, encoding = guess_type(remotename, strict=False) # allow extras mimetype = mimetype or '?/?' # type unknown? maintype = mimetype.split('/')[0] # get first part if trace: print(maintype, encoding or '') return maintype == 'text' and encoding == None # not compressed
def connectFtp(cf): print('connecting...') connection = ftplib.FTP(cf.remotesite) # connect to FTP site connection.login(cf.remoteuser, cf.remotepass) # log in as user/password connection.cwd(cf.remotedir) # cd to directory to xfer if cf.nonpassive: # force active mode FTP connection.set_pasv(False) # most servers do passive return connection
def cleanLocals(cf): if cf.cleanall: for localname in os.listdir(cf.localdir): # local dirlisting try: # local file delete print('deleting local', localname) os.remove(os.path.join(cf.localdir, localname)) except: print('cannot delete local', localname)
def downloadAll(cf, connection): remotefiles = connection.nlst() # nlst is remote listing for remotename in remotefiles: if remotename in ('.', '..'): continue localpath = os.path.join(cf.localdir, remotename) print('downloading', remotename, 'to', localpath, 'as', end=' ') if isTextKind(remotename): # use text mode xfer localfile = open(localpath, 'w', encoding=connection.encoding) def callback(line): localfile.write(line 'n') connection.retrlines('RETR ' remotename, callback) else: # use binary mode xfer localfile = open(localpath, 'wb') connection.retrbinary('RETR ' remotename, localfile.write) localfile.close() connection.quit() print('Done:', len(remotefiles), 'files downloaded.')
if name == 'main': cf = configTransfer() conn = connectFtp(cf) cleanLocals(cf) # don't delete if can't connect downloadAll(cf, conn)
----------------------------------------------------上传所有文件到FTP服务器 封装类
!/bin/env python
import os from downloadflat_modular import configTransfer, connectFtp, isTextKind
def cleanRemotes(cf, connection): 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): 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') conn = connectFtp(cf) cleanRemotes(cf, conn) uploadAll(cf, conn)