#!/usr/bin/env python
#coding=gbk
#--------------------------------------------------------------
# History
#
import os
import socket
import ftplib
import time
import re
from EasyLogUtil import logMsg
import EasyRegex
# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
CRLF = '\r\n'
class EasyFtp(ftplib.FTP):
def __init__(self, host='', user='', passwd='', acct='', timeout=10, mode="a"):
''' mode: 'a' - ascii; 'b' - binary '''
if host:
self.timeout = timeout #增加超时机制,超时会抛出异常到外部
self.mode = mode #增加文件传输模式
self.connect(host)
if user: self.login(user, passwd, acct, timeout)
def __del__(self):
self.close()
def connect(self, host = '', port = 0, timeout=10):
'''Connect to host. Arguments are:
- host: hostname to connect to (string, default previous host)
- port: port to connect to (integer, default previous port)'''
if host: self.host = host
if port: self.port = port
msg = "getaddrinfo returns an empty list"
for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
self.sock.settimeout(self.timeout) #增加超时机制
self.sock.connect(sa)
except socket.error, msg:
if self.sock:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
raise socket.error, msg
self.af = af
self.file = self.sock.makefile('rb')
self.welcome = self.getresp()
return self.welcome
def setMode(self, mode):
if(mode == "a"):
self.mode = "a"
else:
self.mode = "b"
def get(self, remoteFilePath, localFilePath=None):
#判断远程文件是否存在
try:
self.size(remoteFilePath)
except Exception,e:
logMsg("EasyFtp: warn, get, file may not exist, Exception: %s"%(e))
return
writeMode = "w"
getFileFunc = self.getTextFile
if(self.mode == "b"):
writeMode = "wb"
getFileFunc = self.getBinaryFile
remoteFileName = os.path.split(remoteFilePath)[1]
#todo: 如果目录不存在可以生成目录, 注意:实际Ftp工具也并不提供这样的功能
#mkdir也并未提供多级目录创建功能,比如创建 r"g:/tst/tst/tst/tst"
if(None == localFilePath):
localFilePath = os.getcwd() + remoteFileName
try:
localFp = open(localFilePath, writeMode)
getFileFunc(remoteFilePath, localFp) #注意:一旦类方法赋给函数指针,则其第一个参数不必填写self
localFp.close()
except Exception,e:
logMsg("EasyFtp: error, get %s to %s, Exception: %s"%(remoteFilePath, localFilePath,e))
def getBinaryFile(self, remoteFilePath, localFp):
blocksize = 8192
self.voidcmd('TYPE I')
conn = self.transfercmd("RETR "+remoteFilePath, rest=None)
while 1:
data = conn.recv(blocksize)
if not data:
break
localFp.write(data)
conn.close()
return self.voidresp()
def getTextFile(self, remoteFilePath, localFp):
resp = self.sendcmd('TYPE A')
conn = self.transfercmd("RETR "+remoteFilePath, rest=None)
fp = conn.makefile('rb')
while 1:
line = fp.readline()
if self.debugging > 2: print '*retr*', repr(line)
if not line:
break
localFp.write(line)
fp.close()
conn.close()
return self.voidresp()
def put(self, localFilePath, remoteFilePath):
readMode = "r"
putFileFunc = self.putTextFile
if(self.mode == "b"):
readMode = "rb"
putFileFunc = self.putBinaryFile
try:
localFp = open(localFilePath, readMode)
putFileFunc(remoteFilePath, localFp)
localFp.close()
except Exception,e:
logMsg("EasyFtp: error, put %s to %s, Exception: %s"%(remoteFilePath, localFilePath,e))
def putBinaryFile(self, remoteFilePath, localFp):
blocksize=8192
self.voidcmd('TYPE I')
conn = self.transfercmd("STOR "+remoteFilePath)
while 1:
buf = localFp.read(blocksize)
if not buf:
break
conn.sendall(buf)
conn.close()
return self.voidresp()
def putTextFile(self, remoteFilePath, localFp):
self.voidcmd('TYPE A')
conn = self.transfercmd("STOR "+remoteFilePath)
while 1:
buf = localFp.readline()
if not buf: break
if buf[-2:] != CRLF:
if buf[-1] in CRLF: buf = buf[:-1]
buf = buf + CRLF
conn.sendall(buf)
conn.close()
return self.voidresp()
def try_cwd(self, dir):
try:
self.size(dir)
except Exception,e :
logMsg("EasyFtp: warn, cwd, may not exist, Exception: %s"%(e))
return False
self.cwd(dir)
#ftplib.FTP.cwd(dir)
#super(EasyFtp, self).cwd(dir)
return True
def getDirInfo(self, args):
cmd = 'NLST'
s = ''
for arg in args:
#判断远程目录是否存在
try:
self.size(arg)
s += (' ' + arg)
except Exception,e:
logMsg("EasyFtp: warn, dir, may not exist, Exception: %s"%(e))
files = []
cmd += s
self.retrlines(cmd, files.append)
return files
def dir(self, *args): #同 nlst 的实现
return self.getDirInfo(args)
#
#返回所有文件名字的小写形式,包括.和..
def files(self, *args):
fileNames =[]
files = self.getDirInfo(args)
if None == files:
return None
for item in files:
fileName = EasyRegex.regex_GetFileNameInDirLine(item)
if None != fileName:
fileNames.append(fileName.lower())
#print fileNames
return fileNames
class TelFtp():
def __init__(self, tel = None, ftpPrompt = "ftp->"):
self.tel = tel
self.promptFlag = ftpPrompt
def connect(self, ip ="", user="", pwd= ""):
loginSuccStr = "User <%s>:"%ip
ret = self.tel.execCmd('ftp "'+ ip + '"', loginSuccStr)
#print ret
if(-1 == ret.find(loginSuccStr)):
logMsg("TelFtp: error, ftp fail:%s"%ip)
return False
self.tel.execCmd("", self.promptFlag) #user
self.tel.execCmd("", self.promptFlag) #passwd
return True
def setMode(self, mode):
if(mode == "a"):
self.tel.execCmd("ascii", self.promptFlag)
else:
self.tel.execCmd("bin", self.promptFlag)
def cwd(self, dir):
return self.tel.execCmd('cd '+ dir, self.promptFlag)
def get(self, remoteFilePath, localFilePath=None, cmdTime = 5):
return self.tel.execCmd('get '+ remoteFilePath +' '+localFilePath, self.promptFlag, timeout=cmdTime)
def put(self, localFilePath, remoteFilePath, cmdTime = 5):
return self.tel.execCmd('put '+ localFilePath +' '+remoteFilePath, self.promptFlag, timeout=cmdTime)
def dir(self, cmdTime = 5):
return self.tel.execCmd('dir', self.promptFlag, timeout=cmdTime)
def files(self, cmdTime = 5):
#print self.dir()
fileInfoLines = self.dir().splitlines
- 1
- 2
前往页