python ftp工具类 上传、下载文件夹 封装类

-------------------------常用工具------------------------------------------------------------

!/bin/env python

import os, sys, ftplib
from getpass import getpass
from mimetypes import guess_type, add_type

dfltSite = 'home.rmi.net'
dfltRdir = '.'
dfltUser = 'lutz'

class FtpTools:

def getlocaldir(self):
    return (len(sys.argv) > 1 and sys.argv[1]) or '.'

def getcleanall(self):
    return input('Clean target dir first?')[:1] in ['y','Y']

def getpassword(self):
    return getpass(
           'Password for %s on %s:' % (self.remoteuser, self.remotesite))

def configTransfer(self, site=dfltSite, rdir=dfltRdir, user=dfltUser):
    self.nonpassive = False             # passive FTP on by default in 2.1+
    self.remotesite = site              # transfer to/from this site
    self.remotedir  = rdir              # and this dir ('.' means acct root)
    self.remoteuser = user
    self.localdir   = self.getlocaldir()
    self.cleanall   = self.getcleanall()
    self.remotepass = self.getpassword()

def isTextKind(self, 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 1st part
    if trace: print(maintype, encoding or '')
    return maintype == 'text' and encoding == None           # not compressed

def connectFtp(self):
    print('connecting...')
    connection = ftplib.FTP(self.remotesite)           # connect to FTP site
    connection.login(self.remoteuser, self.remotepass) # log in as user/pswd
    connection.cwd(self.remotedir)                     # cd to dir to xfer
    if self.nonpassive:                                # force active mode
        connection.set_pasv(False)                     # most do passive
    self.connection = connection

def cleanLocals(self):
    if self.cleanall:
        for localname in os.listdir(self.localdir):    # local dirlisting
            try:                                       # local file delete
                print('deleting local', localname)
                os.remove(os.path.join(self.localdir, localname))
            except:
                print('cannot delete local', localname)

def cleanRemotes(self):
    if self.cleanall:
        for remotename in self.connection.nlst():       # remote dir listing
            try:                                        # remote file delete
                print('deleting remote', remotename)
                self.connection.delete(remotename)
            except:
                print('cannot delete remote', remotename)

def downloadOne(self, remotename, localpath):
    if self.isTextKind(remotename):
        localfile = open(localpath, 'w', encoding=self.connection.encoding)
        def callback(line): localfile.write(line + '\n')
        self.connection.retrlines('RETR ' + remotename, callback)
    else:
        localfile = open(localpath, 'wb')
        self.connection.retrbinary('RETR ' + remotename, localfile.write)
    localfile.close()

def uploadOne(self, localname, localpath, remotename):
    if self.isTextKind(localname):
        localfile = open(localpath, 'rb')
        self.connection.storlines('STOR ' + remotename, localfile)
    else:
        localfile = open(localpath, 'rb')
        self.connection.storbinary('STOR ' + remotename, localfile)
    localfile.close()

def downloadDir(self):
    remotefiles = self.connection.nlst()         # nlst is remote listing
    for remotename in remotefiles:
        if remotename in ('.', '..'): continue
        localpath = os.path.join(self.localdir, remotename)
        print('downloading', remotename, 'to', localpath, 'as', end=' ')
        self.downloadOne(remotename, localpath)
    print('Done:', len(remotefiles), 'files downloaded.')

def uploadDir(self):
    localfiles = os.listdir(self.localdir)       # listdir is local listing
    for localname in localfiles:
        localpath = os.path.join(self.localdir, localname)
        print('uploading', localpath, 'to', localname, 'as', end=' ')
        self.uploadOne(localname, localpath, localname)
    print('Done:', len(localfiles), 'files uploaded.')

def run(self, cleanTarget=lambda:None, transferAct=lambda:None):
    self.connectFtp()
    cleanTarget()
    transferAct()
    self.connection.quit()

if name == 'main':
ftp = FtpTools()
xfermode = 'download'
if len(sys.argv) > 1:
xfermode = sys.argv.pop(1) # get+del 2nd arg
if xfermode == 'download':
ftp.configTransfer()
ftp.run(cleanTarget=ftp.cleanLocals, transferAct=ftp.downloadDir)
elif xfermode == 'upload':
ftp.configTransfer(site='learning-python.com', rdir='books', user='lutz')
ftp.run(cleanTarget=ftp.cleanRemotes, transferAct=ftp.uploadDir)
else:
print('Usage: ftptools.py ["download" | "upload"] [localdir]')

------------------------------------------------------------------#上传目录树

!/bin/env python

import os, ftptools

class UploadAll(ftptools.FtpTools):
def init(self):
self.fcount = self.dcount = 0

def getcleanall(self):
    return False  # don't even ask

def uploadDir(self, localdir):
    localfiles = os.listdir(localdir)
    for localname in localfiles:
        localpath = os.path.join(localdir, localname)
        print('uploading', localpath, 'to', localname, end=' ')
        if not os.path.isdir(localpath):
            self.uploadOne(localname, localpath, localname)
            self.fcount += 1
        else:
            try:
                self.connection.mkd(localname)
                print('directory created')
            except:
                print('directory not created')
            self.connection.cwd(localname)             # change remote dir
            self.uploadDir(localpath)                  # upload local subdir
            self.connection.cwd('..')                  # change back up
            self.dcount += 1
            print('directory exited')

if name == 'main':
ftp = UploadAll()
ftp.configTransfer(site='learning-python.com', rdir='training', user='lutz')
ftp.run(transferAct = lambda: ftp.uploadDir(ftp.localdir))
print('Done:', ftp.fcount, 'files and', ftp.dcount, 'directories uploaded.')

----------------------------------------------删除远程目录树

!/bin/env python

from ftptools import FtpTools

class CleanAll(FtpTools):
"""
delete an entire remote tree of subdirectories
"""
def init(self):
self.fcount = self.dcount = 0

def getlocaldir(self):
    return None  # irrelevent here

def getcleanall(self):
    return True  # implied here

def cleanDir(self):
    lines = []                                   # each level has own lines
    self.connection.dir(lines.append)            # list current remote dir
    for line in lines:
        parsed  = line.split()                   # split on whitespace
        permiss = parsed[0]                      # assume 'drw... ... filename'
        fname   = parsed[-1]
        if fname in ('.', '..'):                 # some include cwd and parent
            continue
        elif permiss[0] != 'd':                  # simple file: delete
            print('file', fname)
            self.connection.delete(fname)
            self.fcount += 1
        else:                                    # directory: recur, del
            print('directory', fname)
            self.connection.cwd(fname)           # chdir into remote dir
            self.cleanDir()                      # clean subdirectory
            self.connection.cwd('..')            # chdir remote back up
            self.connection.rmd(fname)           # delete empty remote dir
            self.dcount += 1
            print('directory exited')

if name == 'main':
ftp = CleanAll()
ftp.configTransfer(site='learning-python.com', rdir='training', user='lutz')
ftp.run(cleanTarget=ftp.cleanDir)
print('Done:', ftp.fcount, 'files and', ftp.dcount, 'directories cleaned.')


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容