Python FTP 文件上傳 例程

將服務器上的文件 及 數據庫備份文件,複製一份到 FTP 服務器的程序

上傳文件時,從數據庫取得文件名及ID號,每上傳一個文件,記錄當前 ID號,下次運行,從下一個ID號開始上傳。

文件保存目錄以月份爲單位,上層目錄是年份,下層是1-12月份。

import os
import sys
import time
import shutil
import datetime
import ftplib
import socket
import win32api
import win32com.client

g_blockSize = 2048
g_currentBlock = 0
g_totalBlock = 0
g_percent = 0

def getFtp(host, user, password, remoteDir):
    
    # connect to ftp server
    try:
        f = ftplib.FTP(host)
    except(socket.error, socket.gaierror), e:
        print 'Error: connect to server failure'
        print e
        return 1

    # login to ftp server
    try:
        f.login(user = user, passwd = password)
    except ftplib.error_perm, e:
        print 'Error: login to server failure.'
        print e
        f.quit()
        return 2

    # Change remote cd folder
    try:
        f.cwd(remoteDir)
    except ftplib.error_perm, e:
        print 'Error: can not CD to %s' % remoteDir
        print e
        f.quit()
        return 3

    return f

def isHostDirExist(f, dir):
    fileList = []
    f.retrlines('LIST', fileList.append)
    for item in fileList:
        if item.split()[-1] == dir and item.upper().startswith('D'):
            return True
    return False

def createHostDir(f, dir):
    if dir == None:
        return False
    
    if not isHostDirExist(f, dir):
        f.mkd(dir)
    f.cwd(dir)
    
    return True

def callback(message):
    global g_currentBlock, g_totalBlock, g_percent
    g_currentBlock += 1
    percent = g_currentBlock * 100 / g_totalBlock
    if not percent == g_percent:
        g_percent = percent
        sys.stdout.write('=')
        sys.stdout.flush()

def uploadFile(f, localFile):

    # check file does exists
    if not os.path.exists(localFile):
        print 'Error: local file[' + localFile + '] not found.'
        return 1

    global g_blockSize, g_totalBlock, g_currentBlock, g_percent
    g_totalBlock = int(os.path.getsize(localFile) / g_blockSize) + 1
    g_currentBlock = 0
    g_percent = 0

    # Upload file
    putfile = open(localFile, 'rb')
    try:
        print 'File uploading: %s' % localFile
        f.storbinary(cmd = 'STOR %s' % os.path.basename(localFile), \
                     fp = putfile, blocksize = g_blockSize, \
                     callback = callback)
        sys.stdout.write('\r\n')
    except ftplib.error_perm, e:
        print 'Error: upload failure.'
        print e
        return 2
    finally:
        putfile.close()

    return 0

def uploadFileFromDb(host, user, password, localDir, remoteDir, markFile):
    conn = win32com.client.Dispatch('adodb.connection')
    connServer = "."
    connUser = "sa"
    connPass = "disoekw##2048"
    connDbName = "CM_V3_MD"
    connString = "driver={SQL Server};Server=%s;User ID=%s;Password=%s;Database=%s;" % (connServer, connUser, connPass, connDbName)
    #print connString
    conn.ConnectionString = connString
    conn.Open()

    # read last file id from markfile
    try:
        markstring = markFile.read(100)
        #print 'read from mark file: [%s]' % markstring 
        lastId = int(markstring)
        print 'read from mark file: %d' % lastId
    except:
        lastId = 0
        
    query = "SELECT * FROM uploadfiles WHERE id > %d ORDER BY id ASC" % lastId
    rs = conn.execute(query)
    prevYear = 0
    prevMonth = 0
    
    f = getFtp(host, user, password, remoteDir)
    if type(f) == int:
        return False

    retValue = True
    while not rs.Eof:
        fileDate = rs("uploadDate").value
        fileName = "%s\\%s\\%s\\%s"%(localDir, fileDate.year, fileDate.month, rs("filename"))
        #print fileName
        if prevYear <> fileDate.year or prevMonth <> fileDate.month:
            f.cwd(remoteDir)
            createHostDir(f, str(fileDate.year))
            createHostDir(f, str(fileDate.month))
            prevYear = fileDate.year
            prevMonth = fileDate.month
        
        sys.stdout.write('[ID:%d]' % rs("id").value)
        sys.stdout.flush()
        if uploadFile(f, fileName) == 2:
            retValue = False
            break
        else:
            # update last id to markfile
            markFile.seek(0, 0)
            markFile.write("%d" % rs("id").value)
            markFile.flush()
            #time.sleep(0.1)
            
        rs.moveNext

    rs.close
    conn.Close()
    f.quit()

    return retValue

g_srv = 'ftserver'
g_usr = 'uploader'
g_pwd = '3nb2Cc0BB'

# upload invoice files from web uploadfiles folder to ftp server
def main_proc_webfile(localDir, remoteDir):

    if os.path.exists("%s\\uploadID.txt" % localDir):
        markFile = open("%s\\uploadID.txt" % localDir, 'r+')
    else:
        markFile = open("%s\\uploadID.txt" % localDir, 'w+')
        
    try:
        return uploadFileFromDb(g_srv, g_usr, g_pwd, localDir, remoteDir, markFile)
    except:
        return False
    finally:
        markFile.close

# upload DB backup files
def main_proc_dbfile(localDir, remoteDir):
    apps = ['PK', 'PX', 'PC', 'SP']
    tmpdir7z = '%s\\tmp' % localDir
    exe7z = "C:\\Program Files\\7-Zip\\7z.exe"
    timestamp = datetime.date.today().strftime("%Y%m%d0100")
    f = getFtp(g_srv, g_usr, g_pwd, remoteDir)
    for appname in apps:
        filebck = '%s\\CM_V3_%s_db_%s.BAK' % (localDir, appname, timestamp)
        file7z = '%s\\CM_V3_%s_db_%s.BAK.7z' % (tmpdir7z, appname, timestamp)
        #print filebck
        if os.path.exists(filebck):
            # compress file with 7-zip
            command = "\" \"%s\" a \"%s\" \"%s\" \"" % (exe7z, file7z, filebck)
            cmdRetCode = os.system(command)
            if cmdRetCode == 0:
                print command
                uploadFile(f, file7z)
            else:
                print 'Compress file failure.'
                print 'Command: %s' % command
                print 'Return code: %d' % cmdRetCode
                print '\r\nError Code:'
                print '    1:   Warning (Non fatal error(s)). For example, one or more files were locked by some other application, so they were not compressed. '
                print '    2:   Fatal error '
                print '    7:   Command line error '
                print '    8:   Not enough memory for operation '
                print '    255: User stopped the process '
        else:
            print 'File %s not found' % filebck

    # delete temp compress file
    shutil.rmtree(tmpdir7z, ignore_errors=True)

#try 10 times
for i in range(1, 10):
    if main_proc_webfile("C:\\CM.Root\\Application\\UploadFiles", "/home/Backup/UploadFiles.Backup/"):
        break

main_proc_dbfile("C:\\CM.Root\\DataBase\\Backup", "/home/Backup/DB.Backup/")

print 'end'


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章